Visuals:
- PCFSoftShadowMap (2048²), directional light follows player with a tight
shadow frustum (SHADOW_AREA) for high texel density; opak blocks cast+receive,
water receives.
- Baked vertex ambient occlusion ("smooth lighting"): per-vertex solid-neighbor
lookup (0fps algorithm) written into a color attribute, with flip-triangulation
to avoid brightness seams across quad diagonals.
- EffectComposer: RenderPass -> UnrealBloomPass (subtle) -> OutputPass with
ACES filmic tone-mapping + sRGB. HalfFloat render target (anti-banding) + MSAA.
Controls:
- Sprint moved from Ctrl to Shift (Ctrl is problematic in browsers). Shift in
fly mode still means "descend" (no conflict, sprint only applies when walking).
config.js:
- New central js/config.js for all tweakable values (world, performance,
renderer/tone-mapping, sky & fog, camera, lighting, shadows, bloom, AO,
player physics, mouse sensitivity, reach) with SHADOWS_ENABLED / BLOOM_ENABLED
feature toggles. Structural engine constants stay in constants.js.
- SEA_LEVEL / WORLD_SEED moved constants.js -> config.js (consumers rewired).
Co-Authored-By: Claude <noreply@anthropic.com>
95 lines
2.5 KiB
JavaScript
95 lines
2.5 KiB
JavaScript
// Globale Konstanten und Block-/Biome-Definitionen
|
|
|
|
// --- Welt-Dimensionen ---
|
|
// Hinweis: SEA_LEVEL und WORLD_SEED sind einstellbar und liegen in config.js.
|
|
// Chunk-Größen sind strukturell (Array-/Mesh-Größen) und sollten NICHT geändert
|
|
// werden.
|
|
export const CHUNK_SIZE = 16; // X und Z Ausdehnung eines Chunks
|
|
export const CHUNK_HEIGHT = 64; // Y Ausdehnung eines Chunks
|
|
|
|
// --- Block-Typen ---
|
|
export const BLOCK = {
|
|
AIR: 0,
|
|
GRASS: 1,
|
|
DIRT: 2,
|
|
STONE: 3,
|
|
SAND: 4,
|
|
WOOD: 5,
|
|
LEAVES: 6,
|
|
WATER: 7,
|
|
BEDROCK: 8,
|
|
};
|
|
|
|
// Welche Bloecke fuer den Spieler nicht solide sind (keine Kollision, durchschaubar)
|
|
export function isTransparent(id) {
|
|
return id === BLOCK.AIR || id === BLOCK.WATER;
|
|
}
|
|
export function isSolid(id) {
|
|
return id !== BLOCK.AIR && id !== BLOCK.WATER;
|
|
}
|
|
// Wasser als einziger (halb-)transparenter Renderblock
|
|
export function isRenderTransparent(id) {
|
|
return id === BLOCK.WATER;
|
|
}
|
|
|
|
// --- Biome ---
|
|
export const BIOME = { PLAINS: 0, FOREST: 1, DESERT: 2 };
|
|
|
|
// --- Texturatlas ---
|
|
export const ATLAS_COLS = 16; // Tiles pro Reihe
|
|
export const TILE_PX = 16; // Pixel pro Tile
|
|
export const ATLAS_PX = ATLAS_COLS * TILE_PX; // 256
|
|
|
|
// Tile-Indizes im Atlas (Reihe 0)
|
|
export const TILE = {
|
|
GRASS_TOP: 0,
|
|
GRASS_SIDE: 1,
|
|
DIRT: 2,
|
|
STONE: 3,
|
|
SAND: 4,
|
|
WOOD_TOP: 5,
|
|
WOOD_SIDE: 6,
|
|
LEAVES: 7,
|
|
WATER: 8,
|
|
};
|
|
|
|
// Liefert (col,row) im Atlas fuer einen Block + Seite ('top'|'bottom'|'side')
|
|
export function tileFor(block, side) {
|
|
let idx;
|
|
switch (block) {
|
|
case BLOCK.GRASS:
|
|
idx = side === 'top' ? TILE.GRASS_TOP : side === 'bottom' ? TILE.DIRT : TILE.GRASS_SIDE;
|
|
break;
|
|
case BLOCK.DIRT: idx = TILE.DIRT; break;
|
|
case BLOCK.STONE: idx = TILE.STONE; break;
|
|
case BLOCK.SAND: idx = TILE.SAND; break;
|
|
case BLOCK.WOOD:
|
|
idx = (side === 'top' || side === 'bottom') ? TILE.WOOD_TOP : TILE.WOOD_SIDE;
|
|
break;
|
|
case BLOCK.LEAVES: idx = TILE.LEAVES; break;
|
|
case BLOCK.WATER: idx = TILE.WATER; break;
|
|
default: idx = TILE.STONE;
|
|
}
|
|
return { col: idx % ATLAS_COLS, row: Math.floor(idx / ATLAS_COLS) };
|
|
}
|
|
|
|
// Bloecke, die per Hotbar gesetzt werden koennen
|
|
export const HOTBAR = [
|
|
BLOCK.GRASS,
|
|
BLOCK.DIRT,
|
|
BLOCK.STONE,
|
|
BLOCK.SAND,
|
|
BLOCK.WOOD,
|
|
BLOCK.LEAVES,
|
|
];
|
|
|
|
// Anzeige-Farben pro Block fuer die Hotbar-Symbole
|
|
export const BLOCK_COLOR = {
|
|
[BLOCK.GRASS]: '#6ab04c',
|
|
[BLOCK.DIRT]: '#8b5a2b',
|
|
[BLOCK.STONE]: '#8a8a8a',
|
|
[BLOCK.SAND]: '#e6d8a8',
|
|
[BLOCK.WOOD]: '#6e4f2a',
|
|
[BLOCK.LEAVES]:'#3f8a2f',
|
|
};
|