diff --git a/nova farma TRAE/src/scenes/GrassScene_Clean.js b/nova farma TRAE/src/scenes/GrassScene_Clean.js index 7eea70541..6d1778696 100644 --- a/nova farma TRAE/src/scenes/GrassScene_Clean.js +++ b/nova farma TRAE/src/scenes/GrassScene_Clean.js @@ -124,33 +124,83 @@ export default class GrassSceneClean extends Phaser.Scene { // Note: We need to update tilePosition in update() loop to match camera scroll! // --- 2. RIVER SYSTEM (Infinite Scrolling) --- - // Ustvarimo neskončno reko čez celo mapo (navpično) - // Predvidevamo, da je river_tile_seamless.png širine 128px (ali več) in se ponavlja navpično + // Ustvarimo neskončno reko čez celo mapo (HORIZONTALNO) - const riverX = WORLD_W / 2 + 300; // Desno od centra - // Uporabimo tileSprite, ki sega od vrha do dna sveta - // Višina = WORLD_H (32000px), Širina = originalna širina slike (npr. 256px) + const riverY = WORLD_H / 2 + 300; // Spodaj od centra (ali kjerkoli želiš) // Najprej dobimo teksturo, da preverimo dimenzije const riverTex = this.textures.get('river_tile_seamless').getSourceImage(); - const riverW = riverTex.width; + const riverHeight = riverTex.height; // Višina originalne slike - this.river = this.add.tileSprite(riverX, WORLD_H / 2, riverW, WORLD_H, 'river_tile_seamless'); + // Uporabimo tileSprite, ki sega od leve do desne strani sveta + // Širina = WORLD_W (32000px), Višina = originalna višina slike + this.river = this.add.tileSprite(WORLD_W / 2, riverY, WORLD_W, riverHeight, 'river_tile_seamless'); this.river.setDepth(-50); // Nad zemljo (-100), pod igralcem (Y) + // ROTACIJA TEKSTURE: Ker je originalna slika verjetno navpična (tok dol), jo moramo ali rotirati + // ali pa predpostaviti, da je že vodoravna. + // Če je slika "tok navzdol", in jo raztegnemo vodoravno, bo izgledalo čudno. + // Ampak tileSprite ne podpira rotacije teksture znotraj (samo cel objekt). + // Zato bomo zarotirali cel tileSprite za 90 stopinj! + this.river.setAngle(90); + // Ko zarotiramo za 90, se Width in Height zamenjata v vizualnem smislu. + // Zato moramo nastaviti dimenzije obratno: + // Width (ki postane višina) = WORLD_W + // Height (ki postane širina) = riverHeight + // Vendar tileSprite logika deluje na lokalnih oseh. + + // POPRAVEK: Namesto rotacije (ki zaplete tilePosition), raje nastavimo: + // Width = riverHeight (ožja stranica) + // Height = WORLD_W (dolga stranica) + // In nato zarotiramo za -90 stopinj, da leži vodoravno. + this.river.setSize(riverHeight, WORLD_W); + this.river.setAngle(-90); + // FIZIKA: Reka je ovira (ne moreš čeznjo) this.physics.add.existing(this.river, true); // Static body - // Nastavimo collider malo ožji od slike, da lahko stopiš na breg - this.river.body.setSize(riverW * 0.6, WORLD_H); - this.river.body.setOffset(riverW * 0.2, 0); - // Dodamo kolizijo z igralcem (ko bo ustvarjen) - // To naredimo kasneje v create() ali pa shranimo referenco za update + // Zaradi rotacije moramo ročno nastaviti physics body (ker body se ne rotira avtomatsko z objektom na isti način) + // Body je AABB (Axis Aligned Bounding Box). + // Želimo vodoraven body: Širina = WORLD_W, Višina = riverHeight * 0.6 (ožja struga) + this.river.body.setSize(WORLD_W, riverHeight * 0.6); + // Center body-a se mora ujemati s centrom reke + // Offset je relativen na top-left texture (ki je zarotirana). To je zapleteno. + // Najlažje: Body nastavimo na novo, neodvisno od sprite-a. - // "ZAKOPANA V ZEMLJO" - Vizualni trik - // Ker je slika že narisana z bregovi, samo dodamo malo sence, če je treba - // Ali pa rahlo temnejši tint, da izgleda globlje - this.river.setTint(0xdddddd); // Rahlo zatemnimo za globino + // Rešitev za fiziko: Ustvarimo nevidno cono za kolizijo, ker rotiran tileSprite dela težave z body-em + this.riverCollider = this.add.rectangle(WORLD_W / 2, riverY, WORLD_W, riverHeight * 0.6, 0x0000ff, 0); + this.physics.add.existing(this.riverCollider, true); + + // Vizualni trik + this.river.setTint(0xdddddd); + + // --- 2.1 BREG REKE (River Banks - Dirt) --- + // Dodamo zemljo ob robove reke + const bankThickness = 64; // Debelina brega + const steps = Math.ceil(WORLD_W / 128); // Koliko kosov zemlje rabimo + + // Zgornji in spodnji breg (glede na reko, ki je sedaj vodoravna) + // Ker je reka na riverY, sta bregova na riverY +/- (riverHeight/2 + offset) + const bankTopY = riverY - (riverHeight / 2) - 20; + const bankBottomY = riverY + (riverHeight / 2) + 20; + + for (let i = 0; i < steps; i++) { + let bx = (i * 128); // Začnemo od 0 do WORLD_W + + // Zgornji breg + let d1 = this.add.image(bx, bankTopY, 'ground_base'); + d1.setDepth(-49); // Tik nad reko, pod igralcem + d1.setAngle(Math.random() * 360); + d1.setScale(0.8 + Math.random() * 0.4); + d1.setTint(0xcccccc); // Malo temnejša zemlja + + // Spodnji breg + let d2 = this.add.image(bx, bankBottomY, 'ground_base'); + d2.setDepth(-49); + d2.setAngle(Math.random() * 360); + d2.setScale(0.8 + Math.random() * 0.4); + d2.setTint(0xcccccc); + } // --- 2.1 Prejšnji Stream System (Removed) --- /* @@ -210,10 +260,20 @@ export default class GrassSceneClean extends Phaser.Scene { const GRASS_COUNT = 3000; const SPREAD = 4000; // 4000px radius okoli centra + // Parametri reke za preverjanje (da ne sadimo trave v vodo) + // Reka je na riverY, visoka je riverHeight + // riverY je sredina reke + const riverSafeZone = riverHeight / 2 + 50; // Polovica višine + malo rezerve + for (let i = 0; i < GRASS_COUNT; i++) { let x = (WORLD_W / 2) + (Math.random() * SPREAD * 2 - SPREAD); let y = (WORLD_H / 2) + (Math.random() * SPREAD * 2 - SPREAD); + // PREVERJANJE: Če je trava v reki, preskoči + if (Math.abs(y - riverY) < riverSafeZone) { + continue; + } + // Randomizacija - samo divja trava let key = Math.random() > 0.5 ? 'grass_wild' : 'grass_wild_v2'; @@ -639,7 +699,7 @@ export default class GrassSceneClean extends Phaser.Scene { // 3. COLLIDERS if (this.stream) this.physics.add.collider(this.kai, this.stream); - this.physics.add.collider(this.kai, this.river); // Nova reka + this.physics.add.collider(this.kai, this.riverCollider); // Nova reka (nevidna kolizija) // this.physics.add.collider(this.kai, this.obstaclesGroup); // --- ANIMATIONS --- @@ -799,7 +859,8 @@ export default class GrassSceneClean extends Phaser.Scene { // 2. River Flow Animation // Premikamo tilePositionY, da voda "teče" navzdol - // Hitrost: 0.5px na frame (prilagodi po želji) + // Ker smo zarotirali tileSprite za -90 stopinj, "navzdol" po lokalni osi Y pomeni "levo" v globalnem prostoru. + // Če želimo tok levo-desno, moramo premikati Y os teksture (ki je sedaj vodoravna). if (this.river) { this.river.tilePositionY -= 2.0; }