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,85 @@
class InventorySystem {
constructor(scene) {
this.scene = scene;
// Data structure: Array of slots
// Each slot: { type: 'wood', count: 5 } or null
this.slots = new Array(9).fill(null);
this.maxStack = 99;
// Initial test items
this.addItem('hoe', 1);
this.addItem('seeds', 10);
this.addItem('wood', 100); // For restoration
this.addItem('stone', 100); // For restoration
this.gold = 0;
}
addItem(type, count) {
// 1. Try to stack
for (let i = 0; i < this.slots.length; i++) {
if (this.slots[i] && this.slots[i].type === type) {
const space = this.maxStack - this.slots[i].count;
if (space > 0) {
const toAdd = Math.min(space, count);
this.slots[i].count += toAdd;
count -= toAdd;
if (count === 0) break;
}
}
}
// 2. Empty slots
if (count > 0) {
for (let i = 0; i < this.slots.length; i++) {
if (!this.slots[i]) {
const toAdd = Math.min(this.maxStack, count);
this.slots[i] = { type: type, count: toAdd };
count -= toAdd;
if (count === 0) break;
}
}
}
this.updateUI();
return count === 0; // True if everything added
}
removeItem(type, count) {
for (let i = 0; i < this.slots.length; i++) {
if (this.slots[i] && this.slots[i].type === type) {
if (this.slots[i].count >= count) {
this.slots[i].count -= count;
if (this.slots[i].count === 0) this.slots[i] = null;
this.updateUI();
return true;
} else {
count -= this.slots[i].count;
this.slots[i] = null;
}
}
}
this.updateUI();
return false; // Not enough items
}
updateUI() {
const uiScene = this.scene.scene.get('UIScene');
if (uiScene) {
uiScene.updateInventory(this.slots);
if (uiScene.updateGold) uiScene.updateGold(this.gold);
}
}
hasItem(type, count) {
let total = 0;
for (const slot of this.slots) {
if (slot && slot.type === type) {
total += slot.count;
}
}
return total >= count;
}
}