// Player Entity // Igralec z WASD kontrolami in isometrično podporo class Player { constructor(scene, gridX = 50, gridY = 50, offsetX = 0, offsetY = 0) { this.scene = scene; this.gridX = gridX; this.gridY = gridY; // Terrain offset (za sinhronizacijo s terrain containerjem) this.offsetX = offsetX; this.offsetY = offsetY; this.iso = new IsometricUtils(48, 24); // Hitrostgibanja this.moveSpeed = 150; // px/s this.gridMoveTime = 200; // ms za premik na eno kocko // Stanje this.isMoving = false; this.direction = 'down'; // Kreira sprite this.createSprite(); // Setup kontrole this.setupControls(); // Začetna pozicija this.updatePosition(); } createSprite() { // Prefer animated sprite if available let texKey = 'player_walk'; // Spritesheet let isAnimated = this.scene.textures.exists(texKey); if (!isAnimated) { texKey = this.scene.textures.exists('player_sprite') ? 'player_sprite' : 'player'; if (!this.scene.textures.exists(texKey)) { TextureGenerator.createPlayerSprite(this.scene, texKey); } } // 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); // Scale logic if (isAnimated) { this.sprite.setScale(1.5); // 64px frame -> looks good around 96px total height relative to 48px tile } else { this.sprite.setScale(0.3); } // --- HAND / HELD ITEM SPRITE --- this.handSprite = this.scene.add.sprite( screenPos.x + this.offsetX + 10, screenPos.y + this.offsetY - 25, // Adjusted for new height 'item_axe' ); this.handSprite.setOrigin(0.5, 0.5); this.handSprite.setScale(0.25); this.handSprite.setVisible(false); // Depth sorting this.updateDepth(); } // ... setupControls ... // ... update ... moveToGrid(targetX, targetY) { this.isMoving = true; this.gridX = targetX; this.gridY = targetY; const targetScreen = this.iso.toScreen(targetX, targetY); // Play Animation if (this.sprite.texture.key === 'player_walk') { this.sprite.play('player_walk_anim', true); } // Tween za smooth gibanje this.scene.tweens.add({ targets: [this.sprite, this.handSprite], // Move both x: '+=' + (targetScreen.x + this.offsetX - this.sprite.x), y: '+=' + (targetScreen.y + this.offsetY - this.sprite.y), duration: this.gridMoveTime, ease: 'Linear', onComplete: () => { this.isMoving = false; this.updatePosition(); // Stop Animation if (this.sprite.texture.key === 'player_walk') { this.sprite.stop(); this.sprite.setFrame(0); // Idle frame } } }); // Posodobi depth this.updateDepth(); } setupControls() { // WASD kontrole this.keys = this.scene.input.keyboard.addKeys({ up: Phaser.Input.Keyboard.KeyCodes.W, down: Phaser.Input.Keyboard.KeyCodes.S, left: Phaser.Input.Keyboard.KeyCodes.A, right: Phaser.Input.Keyboard.KeyCodes.D }); } update(delta) { this.updateDepth(); if (!this.isMoving) { this.handleInput(); } // Sync Held Item with Inventory this.updateHeldItem(); } updateHeldItem() { const uiScene = this.scene.scene.get('UIScene'); const invSys = this.scene.inventorySystem; if (uiScene && invSys) { const selectedIdx = uiScene.selectedSlot; const slot = invSys.slots[selectedIdx]; if (slot && (slot.type === 'axe' || slot.type === 'pickaxe' || slot.type === 'hoe' || slot.type === 'sword')) { const texKey = `item_${slot.type}`; if (this.scene.textures.exists(texKey)) { this.handSprite.setTexture(texKey); this.handSprite.setVisible(true); } else { this.handSprite.setVisible(false); } } else { this.handSprite.setVisible(false); } } } handleInput() { let targetX = this.gridX; let targetY = this.gridY; let moved = false; let facingRight = !this.sprite.flipX; // Keep current // WASD za isometric movement if (this.keys.up.isDown) { // North-West targetX--; moved = true; facingRight = false; // Left-ish } else if (this.keys.down.isDown) { // South-East targetX++; moved = true; facingRight = true; // Right-ish } if (this.keys.left.isDown) { // South-West targetY++; // SWAPPED: Was -- moved = true; facingRight = false; // Left-ish } else if (this.keys.right.isDown) { // North-East targetY--; // SWAPPED: Was ++ moved = true; facingRight = true; // Right-ish } // Apply Facing this.sprite.setFlipX(!facingRight); // Update Hand Position based on facing const handOffset = facingRight ? 10 : -10; this.handSprite.setX(this.sprite.x + handOffset); this.handSprite.setFlipX(!facingRight); // Preveri kolizijo z robovi mape const terrainSystem = this.scene.terrainSystem; if (moved && terrainSystem) { if (this.iso.isInBounds(targetX, targetY, terrainSystem.width, terrainSystem.height)) { this.moveToGrid(targetX, targetY); } } } updatePosition() { const screenPos = this.iso.toScreen(this.gridX, this.gridY); this.sprite.setPosition( screenPos.x + this.offsetX, screenPos.y + this.offsetY ); // Update hand const facingRight = !this.sprite.flipX; const handOffset = facingRight ? 10 : -10; this.handSprite.setPosition( screenPos.x + this.offsetX + handOffset, screenPos.y + this.offsetY - 15 ); this.updateDepth(); } updateDepth() { // Pixel-perfect depth sorting based on screen Y if (this.sprite) { this.sprite.setDepth(this.sprite.y); if (this.handSprite) this.handSprite.setDepth(this.sprite.y + 1); } } getPosition() { return { x: this.gridX, y: this.gridY }; } getScreenPosition() { return { x: this.sprite.x, y: this.sprite.y }; } destroy() { if (this.sprite) { this.sprite.destroy(); } } dieAnimation() { this.sprite.setTint(0xff0000); this.scene.tweens.add({ targets: this.sprite, angle: 90, duration: 500, ease: 'Bounce.easeOut' }); } respawn() { this.sprite.clearTint(); this.sprite.angle = 0; } }