mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 19:28:03 +00:00
feat(npc): Complete Phase -1 prerequisites for NPC behavior system
✅ Phase -1: Critical Prerequisites COMPLETE Changes: 1. **Added walk animations** to npc-sprites.js (8 directions) - Walk animations: right, down, up, up-right, down-right - Idle animations: right, down, up, up-right, down-right - Left directions use right animations with flipX - Frame references from hacker sprite sheet 2. **Verified existing features**: - ✅ setupNPCEnvironmentCollisions exists (line 381) - ✅ Phone NPC filtering exists (rooms.js line 1899) - ✅ roomId added to NPCs (npc-lazy-loader.js line 39) - ✅ Player position access safe (game.js line 715) Animation Details: - Idle: 5 base directions + 3 mirrored = 8 total - Walk: 5 base directions + 3 mirrored = 8 total - Legacy idle animation preserved for backward compatibility - Frame rate: 8 fps for walk, 4 fps for idle Ready for Phase 0: Foundation Setup
This commit is contained in:
@@ -119,10 +119,10 @@ export function calculateNPCWorldPosition(npc, roomData) {
|
||||
|
||||
/**
|
||||
* Set up animations for an NPC sprite
|
||||
*
|
||||
*
|
||||
* Creates animation sequences based on sprite configuration.
|
||||
* Supports: idle, greeting, and talking animations.
|
||||
*
|
||||
* Supports: idle (8 directions), walk (8 directions), greeting, and talking animations.
|
||||
*
|
||||
* @param {Phaser.Scene} scene - Phaser scene instance
|
||||
* @param {Phaser.Sprite} sprite - NPC sprite
|
||||
* @param {string} spriteSheet - Texture key
|
||||
@@ -131,12 +131,56 @@ export function calculateNPCWorldPosition(npc, roomData) {
|
||||
*/
|
||||
export function setupNPCAnimations(scene, sprite, spriteSheet, config, npcId) {
|
||||
const animPrefix = config.animPrefix || 'idle';
|
||||
|
||||
// Idle animation (facing down by default)
|
||||
// For hacker sprite: frames 20-23 = idle-down
|
||||
|
||||
// ===== IDLE ANIMATIONS (8 directions) =====
|
||||
// Idle animations for 5 base directions (left uses right with flipX)
|
||||
const idleAnimations = [
|
||||
{ dir: 'right', frame: 0 },
|
||||
{ dir: 'down', frame: 5 },
|
||||
{ dir: 'up', frame: 10 },
|
||||
{ dir: 'up-right', frame: 15 },
|
||||
{ dir: 'down-right', frame: 20 }
|
||||
];
|
||||
|
||||
idleAnimations.forEach(anim => {
|
||||
const animKey = `npc-${npcId}-idle-${anim.dir}`;
|
||||
if (!scene.anims.exists(animKey)) {
|
||||
scene.anims.create({
|
||||
key: animKey,
|
||||
frames: [{ key: spriteSheet, frame: anim.frame }],
|
||||
frameRate: config.idleFrameRate || 4,
|
||||
repeat: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Create mirrored idle animations for left directions
|
||||
// These use the same animation keys but will be flipped with sprite.setFlipX(true)
|
||||
const leftIdleAnimations = [
|
||||
{ dir: 'left', mirrorDir: 'right' },
|
||||
{ dir: 'up-left', mirrorDir: 'up-right' },
|
||||
{ dir: 'down-left', mirrorDir: 'down-right' }
|
||||
];
|
||||
|
||||
leftIdleAnimations.forEach(anim => {
|
||||
const animKey = `npc-${npcId}-idle-${anim.dir}`;
|
||||
const mirrorKey = `npc-${npcId}-idle-${anim.mirrorDir}`;
|
||||
if (!scene.anims.exists(animKey) && scene.anims.exists(mirrorKey)) {
|
||||
// Create alias - left directions will use right animations with flipX
|
||||
const mirrorAnim = scene.anims.get(mirrorKey);
|
||||
scene.anims.create({
|
||||
key: animKey,
|
||||
frames: mirrorAnim.frames,
|
||||
frameRate: mirrorAnim.frameRate,
|
||||
repeat: mirrorAnim.repeat
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Legacy idle animation (default facing down) for backward compatibility
|
||||
const idleStart = config.idleFrameStart || 20;
|
||||
const idleEnd = config.idleFrameEnd || 23;
|
||||
|
||||
|
||||
if (!scene.anims.exists(`npc-${npcId}-idle`)) {
|
||||
scene.anims.create({
|
||||
key: `npc-${npcId}-idle`,
|
||||
@@ -148,7 +192,54 @@ export function setupNPCAnimations(scene, sprite, spriteSheet, config, npcId) {
|
||||
repeat: -1
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ===== WALK ANIMATIONS (8 directions) =====
|
||||
// Walk animations for 5 base directions (left uses right with flipX)
|
||||
const walkAnimations = [
|
||||
{ dir: 'right', frames: [1, 2, 3, 4] },
|
||||
{ dir: 'down', frames: [6, 7, 8, 9] },
|
||||
{ dir: 'up', frames: [11, 12, 13, 14] },
|
||||
{ dir: 'up-right', frames: [16, 17, 18, 19] },
|
||||
{ dir: 'down-right', frames: [21, 22, 23, 24] }
|
||||
];
|
||||
|
||||
walkAnimations.forEach(anim => {
|
||||
const animKey = `npc-${npcId}-walk-${anim.dir}`;
|
||||
if (!scene.anims.exists(animKey)) {
|
||||
scene.anims.create({
|
||||
key: animKey,
|
||||
frames: scene.anims.generateFrameNumbers(spriteSheet, {
|
||||
frames: anim.frames
|
||||
}),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Create mirrored walk animations for left directions
|
||||
const leftWalkAnimations = [
|
||||
{ dir: 'left', mirrorDir: 'right' },
|
||||
{ dir: 'up-left', mirrorDir: 'up-right' },
|
||||
{ dir: 'down-left', mirrorDir: 'down-right' }
|
||||
];
|
||||
|
||||
leftWalkAnimations.forEach(anim => {
|
||||
const animKey = `npc-${npcId}-walk-${anim.dir}`;
|
||||
const mirrorKey = `npc-${npcId}-walk-${anim.mirrorDir}`;
|
||||
if (!scene.anims.exists(animKey) && scene.anims.exists(mirrorKey)) {
|
||||
// Create alias - left directions will use right animations with flipX
|
||||
const mirrorAnim = scene.anims.get(mirrorKey);
|
||||
scene.anims.create({
|
||||
key: animKey,
|
||||
frames: mirrorAnim.frames,
|
||||
frameRate: mirrorAnim.frameRate,
|
||||
repeat: mirrorAnim.repeat
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ===== OPTIONAL ANIMATIONS =====
|
||||
// Optional: Greeting animation (wave or nod)
|
||||
if (config.greetFrameStart !== undefined && config.greetFrameEnd !== undefined) {
|
||||
if (!scene.anims.exists(`npc-${npcId}-greet`)) {
|
||||
@@ -163,7 +254,7 @@ export function setupNPCAnimations(scene, sprite, spriteSheet, config, npcId) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Optional: Talking animation (subtle movement)
|
||||
if (config.talkFrameStart !== undefined && config.talkFrameEnd !== undefined) {
|
||||
if (!scene.anims.exists(`npc-${npcId}-talk`)) {
|
||||
|
||||
Reference in New Issue
Block a user