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

313 lines
7.4 KiB
Markdown

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