changed visual movement speed to be slower and made diagonal movement with arrow keys work
This commit is contained in:
@@ -15,7 +15,7 @@ export class DungeonRenderer {
|
||||
private scene: Phaser.Scene;
|
||||
private map?: Phaser.Tilemaps.Tilemap;
|
||||
private layer?: Phaser.Tilemaps.TilemapLayer;
|
||||
|
||||
|
||||
private playerSprite?: Phaser.GameObjects.Sprite;
|
||||
private enemySprites: Map<EntityId, Phaser.GameObjects.Sprite> = new Map();
|
||||
private orbSprites: Map<EntityId, Phaser.GameObjects.Arc> = new Map();
|
||||
@@ -24,7 +24,7 @@ export class DungeonRenderer {
|
||||
private fovManager: FovManager;
|
||||
private minimapRenderer: MinimapRenderer;
|
||||
private fxRenderer: FxRenderer;
|
||||
|
||||
|
||||
private world!: World;
|
||||
private entityAccessor!: EntityAccessor;
|
||||
private ecsWorld!: ECSWorld;
|
||||
@@ -67,7 +67,7 @@ export class DungeonRenderer {
|
||||
// Setup Tilemap
|
||||
if (this.map) this.map.destroy();
|
||||
this.map = this.scene.make.tilemap({
|
||||
data: Array.from({ length: world.height }, (_, y) =>
|
||||
data: Array.from({ length: world.height }, (_, y) =>
|
||||
Array.from({ length: world.width }, (_, x) => this.world.tiles[idx(this.world, x, y)])
|
||||
),
|
||||
tileWidth: 16,
|
||||
@@ -84,7 +84,7 @@ export class DungeonRenderer {
|
||||
});
|
||||
|
||||
this.fxRenderer.clearCorpses();
|
||||
|
||||
|
||||
// Ensure player sprite exists
|
||||
if (!this.playerSprite) {
|
||||
this.playerSprite = this.scene.add.sprite(0, 0, "warrior", 0);
|
||||
@@ -93,13 +93,13 @@ export class DungeonRenderer {
|
||||
}
|
||||
|
||||
this.minimapRenderer.positionMinimap();
|
||||
|
||||
|
||||
// Reset player sprite position to prevent tween animation from old floor
|
||||
if (this.playerSprite) {
|
||||
// Kill any active tweens on the player sprite
|
||||
this.scene.tweens.killTweensOf(this.playerSprite);
|
||||
|
||||
|
||||
|
||||
|
||||
const player = this.entityAccessor.getPlayer();
|
||||
if (player && player.category === "combatant") {
|
||||
this.playerSprite.setPosition(
|
||||
@@ -143,7 +143,7 @@ export class DungeonRenderer {
|
||||
computeFov() {
|
||||
const player = this.entityAccessor.getPlayer();
|
||||
if (player && player.category === "combatant") {
|
||||
this.fovManager.compute(this.world, player.pos);
|
||||
this.fovManager.compute(this.world, player.pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,9 +152,9 @@ export class DungeonRenderer {
|
||||
}
|
||||
|
||||
updateTile(x: number, y: number) {
|
||||
if (!this.map || !this.world) return;
|
||||
const t = this.world.tiles[idx(this.world, x, y)];
|
||||
this.map.putTileAt(t, x, y);
|
||||
if (!this.map || !this.world) return;
|
||||
const t = this.world.tiles[idx(this.world, x, y)];
|
||||
this.map.putTileAt(t, x, y);
|
||||
}
|
||||
|
||||
get seenArray() {
|
||||
@@ -171,7 +171,7 @@ export class DungeonRenderer {
|
||||
this.layer.forEachTile(tile => {
|
||||
const i = idx(this.world, tile.x, tile.y);
|
||||
const worldTile = this.world.tiles[i];
|
||||
|
||||
|
||||
// Sync visual tile with logical tile (e.g. if grass was destroyed)
|
||||
if (tile.index !== worldTile) {
|
||||
// We can safely update the index property for basic tile switching
|
||||
@@ -201,19 +201,19 @@ export class DungeonRenderer {
|
||||
for (const [trapId, sprite] of this.trapSprites) {
|
||||
const pos = this.ecsWorld.getComponent(trapId, "position");
|
||||
const spriteData = this.ecsWorld.getComponent(trapId, "sprite");
|
||||
|
||||
|
||||
if (pos && spriteData) {
|
||||
const i = idx(this.world, pos.x, pos.y);
|
||||
const isSeen = seen[i] === 1;
|
||||
const isVis = visible[i] === 1;
|
||||
|
||||
|
||||
sprite.setVisible(isSeen);
|
||||
|
||||
|
||||
// Update sprite frame in case trap was triggered
|
||||
if (sprite.frame.name !== String(spriteData.index)) {
|
||||
sprite.setFrame(spriteData.index);
|
||||
}
|
||||
|
||||
|
||||
// Dim if not currently visible
|
||||
if (isSeen && !isVis) {
|
||||
sprite.setAlpha(0.4);
|
||||
@@ -241,16 +241,16 @@ export class DungeonRenderer {
|
||||
if (this.playerSprite) {
|
||||
const tx = a.pos.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const ty = a.pos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
|
||||
|
||||
if (this.playerSprite.x !== tx || this.playerSprite.y !== ty) {
|
||||
this.scene.tweens.add({
|
||||
targets: this.playerSprite,
|
||||
x: tx,
|
||||
y: ty,
|
||||
duration: 120,
|
||||
ease: 'Quad.easeOut',
|
||||
overwrite: true
|
||||
});
|
||||
this.scene.tweens.add({
|
||||
targets: this.playerSprite,
|
||||
x: tx,
|
||||
y: ty,
|
||||
duration: GAME_CONFIG.rendering.moveDuration,
|
||||
ease: 'Quad.easeOut',
|
||||
overwrite: true
|
||||
});
|
||||
}
|
||||
this.playerSprite.setVisible(true);
|
||||
}
|
||||
@@ -263,10 +263,10 @@ export class DungeonRenderer {
|
||||
activeEnemyIds.add(a.id);
|
||||
let sprite = this.enemySprites.get(a.id);
|
||||
const textureKey = a.type;
|
||||
|
||||
|
||||
const tx = a.pos.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const ty = a.pos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
|
||||
|
||||
if (!sprite) {
|
||||
sprite = this.scene.add.sprite(tx, ty, textureKey, 0);
|
||||
sprite.setDepth(99);
|
||||
@@ -274,22 +274,22 @@ export class DungeonRenderer {
|
||||
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
|
||||
});
|
||||
}
|
||||
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: GAME_CONFIG.rendering.moveDuration,
|
||||
ease: 'Quad.easeOut',
|
||||
overwrite: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
} else if (a.category === "collectible") {
|
||||
@@ -308,23 +308,23 @@ export class DungeonRenderer {
|
||||
orb.setVisible(true);
|
||||
}
|
||||
} else if (a.category === "item_drop") {
|
||||
if (!isVis) continue;
|
||||
|
||||
activeItemIds.add(a.id);
|
||||
let itemContainer = this.itemSprites.get(a.id);
|
||||
if (!itemContainer) {
|
||||
// Use ItemSpriteFactory to create sprite with optional glow
|
||||
itemContainer = ItemSpriteFactory.createItemSprite(this.scene, a.item, 0, 0, 1);
|
||||
itemContainer.setDepth(40);
|
||||
this.itemSprites.set(a.id, itemContainer);
|
||||
}
|
||||
const tx = a.pos.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const ty = a.pos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
itemContainer.setPosition(tx, ty);
|
||||
itemContainer.setVisible(true);
|
||||
|
||||
// bobbing effect on the container
|
||||
itemContainer.y += Math.sin(this.scene.time.now / 300) * 2;
|
||||
if (!isVis) continue;
|
||||
|
||||
activeItemIds.add(a.id);
|
||||
let itemContainer = this.itemSprites.get(a.id);
|
||||
if (!itemContainer) {
|
||||
// Use ItemSpriteFactory to create sprite with optional glow
|
||||
itemContainer = ItemSpriteFactory.createItemSprite(this.scene, a.item, 0, 0, 1);
|
||||
itemContainer.setDepth(40);
|
||||
this.itemSprites.set(a.id, itemContainer);
|
||||
}
|
||||
const tx = a.pos.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const ty = a.pos.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
itemContainer.setPosition(tx, ty);
|
||||
itemContainer.setVisible(true);
|
||||
|
||||
// bobbing effect on the container
|
||||
itemContainer.y += Math.sin(this.scene.time.now / 300) * 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,13 +350,13 @@ export class DungeonRenderer {
|
||||
}
|
||||
|
||||
for (const [id, item] of this.itemSprites.entries()) {
|
||||
if (!activeItemIds.has(id)) {
|
||||
item.setVisible(false);
|
||||
if (!this.entityAccessor.hasActor(id)) {
|
||||
item.destroy();
|
||||
this.itemSprites.delete(id);
|
||||
}
|
||||
if (!activeItemIds.has(id)) {
|
||||
item.setVisible(false);
|
||||
if (!this.entityAccessor.hasActor(id)) {
|
||||
item.destroy();
|
||||
this.itemSprites.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.minimapRenderer.render(this.world, seen, visible, this.entityAccessor);
|
||||
@@ -405,44 +405,44 @@ export class DungeonRenderer {
|
||||
}
|
||||
|
||||
showProjectile(from: Vec2, to: Vec2, itemId: string, onComplete: () => void) {
|
||||
// World coords
|
||||
const startX = from.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const startY = from.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
const endX = to.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const endY = to.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
// World coords
|
||||
const startX = from.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const startY = from.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
const endX = to.x * TILE_SIZE + TILE_SIZE / 2;
|
||||
const endY = to.y * TILE_SIZE + TILE_SIZE / 2;
|
||||
|
||||
// Create sprite
|
||||
// Look up sprite index from config
|
||||
const itemConfig = ALL_TEMPLATES[itemId as keyof typeof ALL_TEMPLATES];
|
||||
const texture = itemConfig?.textureKey ?? "items";
|
||||
const frame = itemConfig?.spriteIndex ?? 0;
|
||||
// Create sprite
|
||||
// Look up sprite index from config
|
||||
const itemConfig = ALL_TEMPLATES[itemId as keyof typeof ALL_TEMPLATES];
|
||||
const texture = itemConfig?.textureKey ?? "items";
|
||||
const frame = itemConfig?.spriteIndex ?? 0;
|
||||
|
||||
// Use 'items' spritesheet
|
||||
const sprite = this.scene.add.sprite(startX, startY, texture, frame);
|
||||
sprite.setDepth(2000);
|
||||
|
||||
// Rotate?
|
||||
const angle = Phaser.Math.Angle.Between(startX, startY, endX, endY);
|
||||
sprite.setRotation(angle + Math.PI / 4); // Adjust for sprite orientation (diagonal usually)
|
||||
// Use 'items' spritesheet
|
||||
const sprite = this.scene.add.sprite(startX, startY, texture, frame);
|
||||
sprite.setDepth(2000);
|
||||
|
||||
const dist = Phaser.Math.Distance.Between(startX, startY, endX, endY);
|
||||
const duration = dist * 2; // speed
|
||||
// Rotate?
|
||||
const angle = Phaser.Math.Angle.Between(startX, startY, endX, endY);
|
||||
sprite.setRotation(angle + Math.PI / 4); // Adjust for sprite orientation (diagonal usually)
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: sprite,
|
||||
x: endX,
|
||||
y: endY,
|
||||
rotation: sprite.rotation + 4 * Math.PI, // Spin effect
|
||||
duration: duration,
|
||||
ease: 'Linear',
|
||||
onComplete: () => {
|
||||
sprite.destroy();
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
const dist = Phaser.Math.Distance.Between(startX, startY, endX, endY);
|
||||
const duration = dist * 2; // speed
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: sprite,
|
||||
x: endX,
|
||||
y: endY,
|
||||
rotation: sprite.rotation + 4 * Math.PI, // Spin effect
|
||||
duration: duration,
|
||||
ease: 'Linear',
|
||||
onComplete: () => {
|
||||
sprite.destroy();
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shakeCamera() {
|
||||
this.scene.cameras.main.shake(100, 0.01);
|
||||
this.scene.cameras.main.shake(100, 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user