# 🎯 Z-Sorting System Guide (2.5D Depth) Vodič za obvladovanje globine objektov v 2.5D isometric igrah. --- ## 📖 Kaj je Z-Sorting? V 2.5D isometric igrah moramo objekte **pravilno prekrivati** glede na njihovo pozicijo: - Objekti **spredaj** (višji Y) morajo biti **nad** objekti zadaj (nižji Y) - To se doseže z nastavitvijo **depth** vrednosti **Primer:** ``` Drevo na Y=100 mora biti NAD karakterjem na Y=50 Karakter na Y=100 mora biti NAD drevesom na Y=50 ``` --- ## 🔄 DVA PRISTOPA ### **Pristop 1: Manual updateDepth()** ❌ STAR SISTEM **Kako deluje:** ```javascript updateDepth() { const layerBase = 200000; // LAYER_OBJECTS const depth = layerBase + this.sprite.y; this.sprite.setDepth(depth); } ``` **Klici:** - V `update()` funkciji vsake Entity - Ko se objekt premakne **Prednosti:** - ✅ Zelo natančno (vsak piksel šteje) - ✅ Deluje z layerji (LAYER_TERRAIN, LAYER_OBJECTS, LAYER_UI) **Slabosti:** - ❌ Vsak objekt potrebuje svojo `updateDepth()` funkcijo - ❌ Več kode za vzdrževanje - ❌ Moral klicat ročno --- ### **Pristop 2: sortableObjects Group** ✅ NOV SISTEM **Kako deluje:** ```javascript // V create() - GameScene.js this.sortableObjects = this.add.group(); this.sortableObjects.add(this.player.sprite); // V update() - GameScene.js const children = this.sortableObjects.getChildren(); children.sort((a, b) => a.y - b.y); // Sortiranje po Y children.forEach((obj, index) => { obj.setDepth(200000 + index); }); ``` **Prednosti:** - ✅ **Enostavno** - samo dodaš sprite v group - ✅ **Centralizirano** - vse na enem mestu - ✅ **Avtomatsko** - sortira se vsak frame **Slabosti:** - ⚠️ Sortira VSE objekte vsak frame (lahko počasno pri 100+ objektih) - ⚠️ Depth je samo index (0, 1, 2, 3...) ne natančen Y --- ## 🛠️ Implementacija (Korak-po-Korak) ### **Korak 1: Ustvari sortableObjects Group** V `GameScene.js` - `create()` funkciji: ```javascript // Po ustvarjanju playerja this.player = new Player(this, 50, 50, offsetX, offsetY); // 🎯 SORTABLE OBJECTS GROUP console.log('🎯 Creating sortableObjects group...'); this.sortableObjects = this.add.group(); // Dodaj player sprite if (this.player && this.player.sprite) { this.sortableObjects.add(this.player.sprite); } ``` ### **Korak 2: Dodaj Z-Sorting v Update** V `GameScene.js` - `update()` funkciji: ```javascript update(time, delta) { if (this.player) this.player.update(delta); // 🎯 Z-SORTING if (this.sortableObjects) { const children = this.sortableObjects.getChildren(); // Sortiranje po Y koordinati children.sort((a, b) => a.y - b.y); // Nastavi depth glede na vrstni red children.forEach((obj, index) => { obj.setDepth(200000 + index); // LAYER_OBJECTS base }); } // ... ostali sistemi } ``` ### **Korak 3: Odstrani Manual updateDepth()** V `Player.js` (ali drugih Entity classes): ```javascript update(delta) { // ❌ ODSTRANI TO: // if (this.isMoving) { // this.updateDepth(); // } // ✅ Ne rabiš več - sortableObjects to naredi avtomatsko! if (!this.isMoving) { this.handleInput(); } } ``` ### **Korak 4: Dodaj Nove Objekte (Drevesa, NPCji, itd.)** Ko ustvarjaš nov objekt: ```javascript // PRIMER: Dodaj drevo const tree = this.add.sprite(x, y, 'tree_sprite'); tree.setOrigin(0.5, 1.0); // ✨ DODAJ V SORTABLE OBJECTS this.sortableObjects.add(tree); // PRIMER: Dodaj NPC const npc = new NPC(this, gridX, gridY); this.sortableObjects.add(npc.sprite); ``` --- ## 🎮 Praktični Primeri ### **Primer 1: Player + Drevesa** ```javascript // V create() this.player = new Player(this, 50, 50, offsetX, offsetY); this.sortableObjects = this.add.group(); this.sortableObjects.add(this.player.sprite); // Dodaj 5 dreves for (let i = 0; i < 5; i++) { const tree = this.add.sprite( Math.random() * 500, Math.random() * 500, 'tree_sprite' ); tree.setOrigin(0.5, 1.0); this.sortableObjects.add(tree); // ✨ Avtomatično sortiranje! } ``` ### **Primer 2: Player + NPCs + Drevesa** ```javascript // Player this.sortableObjects.add(this.player.sprite); // NPCs this.npcs = []; for (let i = 0; i < 10; i++) { const npc = new NPC(this, randX, randY); this.npcs.push(npc); this.sortableObjects.add(npc.sprite); // ✨ } // Drevesa this.trees.forEach(tree => { this.sortableObjects.add(tree.sprite); // ✨ }); ``` --- ## ⚡ Performance Tips ### **Problem: Počasno pri 100+ objektih** Če imaš **več kot 100 objektov**, sortiranje vsak frame (60x/sekundo) je lahko počasno. **Rešitev 1: Dirty Flag** ```javascript update(time, delta) { // Sortiranje samo ko potrebno, ne vsak frame if (this.needsSorting) { const children = this.sortableObjects.getChildren(); children.sort((a, b) => a.y - b.y); children.forEach((obj, index) => obj.setDepth(200000 + index)); this.needsSorting = false; } } // Nastavi v Player.moveToGrid() ali NPC movement moveToGrid(targetX, targetY) { // ... movement code this.scene.needsSorting = true; // ✅ Označi za sortiranje } ``` **Rešitev 2: Throttling (vsak N-ti frame)** ```javascript update(time, delta) { this.sortCounter = (this.sortCounter || 0) + 1; // Sortiranje samo vsak 3. frame (namesto vsakega) if (this.sortCounter % 3 === 0) { const children = this.sortableObjects.getChildren(); children.sort((a, b) => a.y - b.y); children.forEach((obj, index) => obj.setDepth(200000 + index)); } } ``` --- ## 🔍 Debugging ### **Problem: Objekti ne prekrivajo pravilno** ```javascript // V update(), dodaj console.log update(time, delta) { if (this.sortableObjects) { const children = this.sortableObjects.getChildren(); children.sort((a, b) => a.y - b.y); children.forEach((obj, index) => { obj.setDepth(200000 + index); // 🔍 DEBUG console.log(`${obj.texture.key}: Y=${obj.y}, Depth=${obj.depth}`); }); } } ``` ### **Problem: Objekti manjkajo** Preveri če si dodal sprite v group: ```javascript // ✅ PRAVILNO this.sortableObjects.add(this.player.sprite); // ❌ NAROBE this.sortableObjects.add(this.player); // Mora biti .sprite! ``` --- ## 📊 Primerjava: Manual vs. SortableObjects | Feature | Manual updateDepth() | sortableObjects | |---------|---------------------|-----------------| | **Enostavnost** | ⭐⭐ | ⭐⭐⭐⭐⭐ | | **Performance (< 50 obj)** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | | **Performance (> 100 obj)** | ⭐⭐⭐⭐ | ⭐⭐ | | **Natančnost** | ⭐⭐⭐⭐⭐ (pixel perfect) | ⭐⭐⭐ (index based) | | **Vzdrževanje** | ⭐⭐ (več kode) | ⭐⭐⭐⭐⭐ (ena funkcija) | | **Layer podpora** | ✅ Da | ⚠️ Samo eno layer | --- ## 🎯 PRIPOROČILO ### **Za KRVAVA ŽETEV:** ✅ **Uporabljaj sortableObjects** - enostavnejše in hitrejše za razvoj ### **Kdaj Manual:** - Zelo kompleksne igre (10+ layerjev) - Več kot 200+ objektov - Potrebuješ pixel-perfect depth --- ## 📚 Dodatno Branje - [Phaser Groups Documentation](https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.Group.html) - [Isometric Depth Sorting](https://www.youtube.com/watch?v=04oQ2jOUjkU) - [Advanced Z-Sorting Techniques](https://gamedev.stackexchange.com/questions/8/how-do-i-sort-isometric-sprites-into-the-correct-order) --- **Zadnja posodobitev:** 14.12.2025 **Avtor:** KRVAVA ŽETEV Team **Status:** ✅ Implementirano v GameScene.js