Files
novafarma/docs/Z_SORTING_GUIDE.md
2025-12-14 12:36:46 +01:00

7.4 KiB

🎯 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:

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:

// 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:

// 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:

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):

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:

// 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

// 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

// 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

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)

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

// 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:

// ✅ 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


Zadnja posodobitev: 14.12.2025
Avtor: KRVAVA ŽETEV Team
Status: Implementirano v GameScene.js