FAZA 17: 2.5D Minecraft-Style Terrain + Y-Layer Stacking + Custom Sprites

COMPLETED FEATURES:

 Custom Sprite Integration:
- Player, Zombie, Merchant sprites (0.2 scale)
- 11 custom sprites + 5 asset packs loaded
- Auto-transparency processing (white/brown removal)
- Gravestone system with atlas extraction

 2.5D Minecraft-Style Terrain:
- Volumetric blocks with 25px thickness
- Strong left/right side shading (30%/50% darker)
- Minecraft-style texture patterns (grass, dirt, stone)
- Crisp black outlines for definition

 Y-Layer Stacking System:
- GRASS_FULL: All green (elevation > 0.7)
- GRASS_TOP: Green top + brown sides (elevation 0.4-0.7)
- DIRT: All brown (elevation < 0.4)
- Dynamic terrain depth based on height

 Floating Island World Edge:
- Stone cliff walls at map borders
- 2-tile transition zone
- Elevation flattening for cliff drop-off effect
- 100x100 world with defined boundaries

 Performance & Polish:
- Canvas renderer for pixel-perfect sharpness
- CSS image-rendering: crisp-edges
- willReadFrequently optimization
- No Canvas2D warnings

 Technical:
- 3D volumetric trees and rocks
- Hybrid rendering (2.5D terrain + 2D characters)
- Procedural texture generation
- Y-layer aware terrain type selection
This commit is contained in:
2025-12-07 01:44:16 +01:00
parent 34a2d07538
commit 9eb57ed117
60 changed files with 5082 additions and 195 deletions

View File

@@ -0,0 +1,198 @@
class ParallaxSystem {
constructor(scene) {
this.scene = scene;
this.layers = [];
// Layer depths (Phaser depth sorting)
this.DEPTH = {
SKY: -1000,
DISTANT_HILLS: -500,
FAR_TREES: -100,
TERRAIN: 0,
GAME_OBJECTS: 1000,
FOREGROUND_GRASS: 5000,
FOREGROUND_LEAVES: 5500
};
this.init();
}
init() {
console.log('🌄 ParallaxSystem: Initialized');
// Layer 1: Sky/Hills (Distant background)
this.createSkyLayer();
this.createDistantHills();
// Layer 4: Foreground overlay (High grass patches)
this.createForegroundGrass();
}
createSkyLayer() {
// Gradient sky rectangle
const width = 3000;
const height = 2000;
const skyBg = this.scene.add.rectangle(0, 0, width, height, 0x87CEEB); // Sky blue
skyBg.setOrigin(0, 0);
skyBg.setScrollFactor(0); // Fixed (no parallax)
skyBg.setDepth(this.DEPTH.SKY);
this.layers.push({
name: 'sky',
objects: [skyBg],
scrollFactor: 0
});
}
createDistantHills() {
// Create simple hill silhouettes in background
const hillCount = 5;
const hills = [];
for (let i = 0; i < hillCount; i++) {
const x = i * 800 - 1000;
const y = 600;
const width = Phaser.Math.Between(400, 800);
const height = Phaser.Math.Between(150, 300);
// Create hill as ellipse
const hill = this.scene.add.ellipse(x, y, width, height, 0x4a5f3a); // Dark green
hill.setAlpha(0.4);
hill.setDepth(this.DEPTH.DISTANT_HILLS);
hill.setScrollFactor(0.2, 0.2); // Slow parallax
hills.push(hill);
}
this.layers.push({
name: 'distant_hills',
objects: hills,
scrollFactor: 0.2
});
}
createForegroundGrass() {
// Create tall grass patches that appear in front of player
const grassPatches = [];
const patchCount = 30;
for (let i = 0; i < patchCount; i++) {
const x = Phaser.Math.Between(-500, 2500);
const y = Phaser.Math.Between(-500, 2500);
const grass = this.createGrassPatch(x, y);
grass.setDepth(this.DEPTH.FOREGROUND_GRASS);
grass.setScrollFactor(1.05, 1.05); // Slight forward parallax
grass.setAlpha(0.6);
grassPatches.push(grass);
}
this.layers.push({
name: 'foreground_grass',
objects: grassPatches,
scrollFactor: 1.05
});
}
createGrassPatch(x, y) {
// Create procedural grass patch
const graphics = this.scene.add.graphics();
// Draw several grass blades
for (let i = 0; i < 6; i++) {
const offsetX = Phaser.Math.Between(-10, 10);
const offsetY = Phaser.Math.Between(-5, 5);
const height = Phaser.Math.Between(20, 40);
graphics.fillStyle(0x3a5f2a, 0.8); // Dark grass green
// Draw grass blade (thin triangle)
graphics.beginPath();
graphics.moveTo(x + offsetX, y + offsetY);
graphics.lineTo(x + offsetX - 2, y + offsetY + height);
graphics.lineTo(x + offsetX + 2, y + offsetY + height);
graphics.closePath();
graphics.fillPath();
}
return graphics;
}
update(playerX, playerY) {
// Update foreground grass visibility based on player position
// Hide/show grass patches that are too close to player for better gameplay
const foregroundLayer = this.layers.find(l => l.name === 'foreground_grass');
if (!foregroundLayer) return;
for (const grass of foregroundLayer.objects) {
const distance = Phaser.Math.Distance.Between(
grass.x, grass.y,
playerX, playerY
);
// Fade out grass when player is very close
if (distance < 50) {
grass.setAlpha(0.2);
} else if (distance < 100) {
grass.setAlpha(0.4);
} else {
grass.setAlpha(0.6);
}
}
}
addFarTree(x, y) {
// Add a background tree (Layer 2)
if (!this.scene.textures.exists('tree')) return;
const tree = this.scene.add.sprite(x, y, 'tree');
tree.setDepth(this.DEPTH.FAR_TREES);
tree.setScrollFactor(0.7, 0.7); // Medium parallax
tree.setAlpha(0.7);
tree.setScale(1.5);
return tree;
}
addForegroundLeaves(x, y) {
// Add falling leaves or branch overlay (Layer 4)
const graphics = this.scene.add.graphics();
// Draw some leaves
for (let i = 0; i < 3; i++) {
const leafX = x + Phaser.Math.Between(-20, 20);
const leafY = y + Phaser.Math.Between(-10, 10);
graphics.fillStyle(0x2d4a1f, 0.5); // Dark green leaf
graphics.fillEllipse(leafX, leafY, 8, 12);
}
graphics.setDepth(this.DEPTH.FOREGROUND_LEAVES);
graphics.setScrollFactor(1.1, 1.1); // Fastest parallax (closest)
return graphics;
}
clearLayer(layerName) {
const layer = this.layers.find(l => l.name === layerName);
if (!layer) return;
for (const obj of layer.objects) {
obj.destroy();
}
layer.objects = [];
}
destroy() {
for (const layer of this.layers) {
for (const obj of layer.objects) {
obj.destroy();
}
}
this.layers = [];
}
}