From 57fb85f62ebb1e36372bc0edda62a51830dde6a1 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Tue, 6 Jan 2026 17:59:56 +1100 Subject: [PATCH] When enemy is comes into site dont tween sprite from (0,0) to correct location, instead just create at correct location --- src/rendering/DungeonRenderer.ts | 40 +++++++++++-------- .../__tests__/DungeonRenderer.test.ts | 30 ++++++++++++++ 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/rendering/DungeonRenderer.ts b/src/rendering/DungeonRenderer.ts index 999331e..257caee 100644 --- a/src/rendering/DungeonRenderer.ts +++ b/src/rendering/DungeonRenderer.ts @@ -172,27 +172,33 @@ export class DungeonRenderer { let sprite = this.enemySprites.get(a.id); const textureKey = a.type; - if (!sprite) { - sprite = this.scene.add.sprite(0, 0, textureKey, 0); - sprite.setDepth(99); - sprite.play(`${textureKey}-idle`); - this.enemySprites.set(a.id, sprite); - } - const tx = a.pos.x * TILE_SIZE + TILE_SIZE / 2; const ty = a.pos.y * TILE_SIZE + TILE_SIZE / 2; - if (sprite.x !== tx || sprite.y !== ty) { - this.scene.tweens.add({ - targets: sprite, - x: tx, - y: ty, - duration: 120, - ease: 'Quad.easeOut', - overwrite: true - }); + if (!sprite) { + sprite = this.scene.add.sprite(tx, ty, textureKey, 0); + sprite.setDepth(99); + sprite.play(`${textureKey}-idle`); + this.enemySprites.set(a.id, sprite); + sprite.setVisible(true); + } else { + if (!sprite.visible) { + // If it was hidden, snap to new position immediately + this.scene.tweens.killTweensOf(sprite); + sprite.setPosition(tx, ty); + sprite.setVisible(true); + } else if (sprite.x !== tx || sprite.y !== ty) { + // Only tween if it was already visible and moved + this.scene.tweens.add({ + targets: sprite, + x: tx, + y: ty, + duration: 120, + ease: 'Quad.easeOut', + overwrite: true + }); + } } - sprite.setVisible(true); } else if (a.category === "collectible") { if (a.type === "exp_orb") { diff --git a/src/rendering/__tests__/DungeonRenderer.test.ts b/src/rendering/__tests__/DungeonRenderer.test.ts index 7b40a1e..87f3774 100644 --- a/src/rendering/__tests__/DungeonRenderer.test.ts +++ b/src/rendering/__tests__/DungeonRenderer.test.ts @@ -209,4 +209,34 @@ describe('DungeonRenderer', () => { const ratSpriteCall = mockScene.add.sprite.mock.calls.find((call: any) => call[2] === 'rat'); expect(ratSpriteCall).toBeDefined(); }); + + it('should initialize new enemy sprites at target position and not tween them', () => { + renderer.initializeFloor(mockWorld, 1); + + // Position 5,5 -> 5*16 + 8 = 88 + const TILE_SIZE = 16; + const targetX = 5 * TILE_SIZE + TILE_SIZE / 2; + const targetY = 5 * TILE_SIZE + TILE_SIZE / 2; + + mockWorld.actors.set(999, { + id: 999, + category: "combatant", + isPlayer: false, + type: "rat", + pos: { x: 5, y: 5 }, + stats: { hp: 10, maxHp: 10 } as any, + } as any); + + (renderer as any).fovManager.visibleArray[5 * mockWorld.width + 5] = 1; + mockScene.add.sprite.mockClear(); + mockScene.tweens.add.mockClear(); + + renderer.render([]); + + // Check spawn position + expect(mockScene.add.sprite).toHaveBeenCalledWith(targetX, targetY, 'rat', 0); + + // Should NOT tween because it's the first spawn + expect(mockScene.tweens.add).not.toHaveBeenCalled(); + }); });