// NPC Entity // NPC z random walk AI in isometrično podporo class NPC { constructor(scene, gridX, gridY, offsetX = 0, offsetY = 0, type = 'zombie') { this.scene = scene; this.gridX = gridX; this.gridY = gridY; this.type = type; // Terrain offset this.offsetX = offsetX; this.offsetY = offsetY; this.iso = new IsometricUtils(48, 24); // Random walk paramters this.moveSpeed = 100; // px/s (počasnejše od igralca) this.gridMoveTime = 300; // ms za premik (počasneje) // Stanje this.isMoving = false; this.pauseTime = 0; this.maxPauseTime = 2000; // Pavza med premiki (2s) // Kreira sprite this.createSprite(); // Začetna pozicija this.updatePosition(); // Naključna začetna pavza this.pauseTime = Math.random() * this.maxPauseTime; } createSprite() { // Check for custom sprites first let texKey = `npc_${this.type}`; if (this.type === 'zombie' && this.scene.textures.exists('zombie_sprite')) { texKey = 'zombie_sprite'; } else if (this.type === 'merchant' && this.scene.textures.exists('merchant_sprite')) { texKey = 'merchant_sprite'; } else if (!this.scene.textures.exists(texKey)) { TextureGenerator.createNPCSprite(this.scene, texKey, this.type); } // Kreira sprite const screenPos = this.iso.toScreen(this.gridX, this.gridY); this.sprite = this.scene.add.sprite( screenPos.x + this.offsetX, screenPos.y + this.offsetY, texKey ); this.sprite.setOrigin(0.5, 1); this.sprite.setScale(0.3); // Optimized for visibility // Depth sorting this.updateDepth(); } update(delta) { if (this.isMoving) { return; // Že se premika } // Random walk - pavza med premiki this.pauseTime += delta; if (this.pauseTime >= this.maxPauseTime) { this.performRandomWalk(); this.pauseTime = 0; } } performRandomWalk() { // Naključna smer (NSEW + možnost obstati) const directions = [ { x: -1, y: 0 }, // North-West { x: 1, y: 0 }, // South-East { x: 0, y: -1 }, // South-West { x: 0, y: 1 }, // North-East { x: 0, y: 0 } // Stay (30% možnost) ]; const dir = Phaser.Math.RND.pick(directions); const targetX = this.gridX + dir.x; const targetY = this.gridY + dir.y; // Preveri kolizijo z robovi const terrainSystem = this.scene.terrainSystem; if (terrainSystem && this.iso.isInBounds(targetX, targetY, terrainSystem.width, terrainSystem.height)) { // Preveri da ni ista pozicija kot igralec if (this.scene.player) { const playerPos = this.scene.player.getPosition(); if (targetX === playerPos.x && targetY === playerPos.y) { return; // Ne premakni se na igralca } } if (dir.x !== 0 || dir.y !== 0) { this.moveToGrid(targetX, targetY); } } } moveToGrid(targetX, targetY) { this.isMoving = true; this.gridX = targetX; this.gridY = targetY; const targetScreen = this.iso.toScreen(targetX, targetY); // Tween za smooth gibanje this.scene.tweens.add({ targets: this.sprite, x: targetScreen.x + this.offsetX, y: targetScreen.y + this.offsetY, duration: this.gridMoveTime, ease: 'Linear', onComplete: () => { this.isMoving = false; } }); // Posodobi depth this.updateDepth(); } updatePosition() { const screenPos = this.iso.toScreen(this.gridX, this.gridY); this.sprite.setPosition( screenPos.x + this.offsetX, screenPos.y + this.offsetY ); this.updateDepth(); } updateDepth() { const depth = this.iso.getDepth(this.gridX, this.gridY); this.sprite.setDepth(depth + 1000); // +1000 da je nad terenom } getPosition() { return { x: this.gridX, y: this.gridY }; } destroy() { if (this.sprite) { this.sprite.destroy(); } } }