mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 11:18:08 +00:00
144 lines
4.6 KiB
Markdown
144 lines
4.6 KiB
Markdown
|
|
# 8-Directional Animation Fix
|
||
|
|
|
||
|
|
## Problem
|
||
|
|
|
||
|
|
NPCs and player were only using 2 directions (left/right) instead of all 8 directions when using the new PixelLab atlas sprites.
|
||
|
|
|
||
|
|
## Root Cause
|
||
|
|
|
||
|
|
The animation system was designed for legacy 64x64 sprites which only had 5 native directions (right, down, up, down-right, up-right). Left-facing directions were created by horizontally flipping the right-facing animations.
|
||
|
|
|
||
|
|
The new 80x80 PixelLab atlas sprites have all 8 native directions, but the code was still doing the left→right mapping and flipping, which prevented the native left-facing animations from being used.
|
||
|
|
|
||
|
|
## Solution
|
||
|
|
|
||
|
|
Updated both NPC and player animation systems to:
|
||
|
|
1. Detect whether a sprite is atlas-based (has native left animations)
|
||
|
|
2. Use native directions for atlas sprites
|
||
|
|
3. Fall back to flip-based behavior for legacy sprites
|
||
|
|
|
||
|
|
## Changes Made
|
||
|
|
|
||
|
|
### 1. NPC System (`js/systems/npc-behavior.js`)
|
||
|
|
|
||
|
|
**Updated `playAnimation()` method:**
|
||
|
|
```javascript
|
||
|
|
// Before: Always mapped left→right with flipX
|
||
|
|
if (direction.includes('left')) {
|
||
|
|
animDirection = direction.replace('left', 'right');
|
||
|
|
flipX = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// After: Check if native left animations exist
|
||
|
|
const directAnimKey = `npc-${this.npcId}-${state}-${direction}`;
|
||
|
|
const hasNativeLeftAnimations = this.scene?.anims?.exists(directAnimKey);
|
||
|
|
|
||
|
|
if (!hasNativeLeftAnimations && direction.includes('left')) {
|
||
|
|
animDirection = direction.replace('left', 'right');
|
||
|
|
flipX = true;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Player System (`js/core/player.js`)
|
||
|
|
|
||
|
|
**A. Updated `createPlayerAnimations()`:**
|
||
|
|
- Added detection for atlas vs legacy sprites
|
||
|
|
- Created `createAtlasPlayerAnimations()` for atlas sprites
|
||
|
|
- Created `createLegacyPlayerAnimations()` for legacy sprites
|
||
|
|
- Atlas animations are read from JSON metadata
|
||
|
|
- Legacy animations use hardcoded frame numbers
|
||
|
|
|
||
|
|
**B. Updated `getAnimationKey()`:**
|
||
|
|
```javascript
|
||
|
|
// Before: Always mapped left→right
|
||
|
|
switch(direction) {
|
||
|
|
case 'left': return 'right';
|
||
|
|
case 'down-left': return 'down-right';
|
||
|
|
case 'up-left': return 'up-right';
|
||
|
|
}
|
||
|
|
|
||
|
|
// After: Check if native left exists
|
||
|
|
const hasNativeLeft = gameRef.anims.exists(`idle-left`);
|
||
|
|
if (hasNativeLeft) {
|
||
|
|
return direction; // Use native direction
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**C. Updated movement functions:**
|
||
|
|
- `updatePlayerKeyboardMovement()` - Added atlas detection, conditional flipping
|
||
|
|
- `updatePlayerMouseMovement()` - Added atlas detection, conditional flipping
|
||
|
|
- Both now check for native left animations before applying flipX
|
||
|
|
|
||
|
|
**D. Updated sprite creation:**
|
||
|
|
```javascript
|
||
|
|
// Before: Hardcoded 'hacker' sprite
|
||
|
|
player = gameInstance.add.sprite(x, y, 'hacker', 20);
|
||
|
|
|
||
|
|
// After: Use sprite from scenario config
|
||
|
|
const playerSprite = window.scenarioConfig?.player?.spriteSheet || 'hacker';
|
||
|
|
player = gameInstance.add.sprite(x, y, playerSprite, initialFrame);
|
||
|
|
```
|
||
|
|
|
||
|
|
## Animation Key Format
|
||
|
|
|
||
|
|
### Atlas Sprites (8 Native Directions)
|
||
|
|
- **Player**: `walk-left`, `walk-right`, `walk-up-left`, `idle-down-right`, etc.
|
||
|
|
- **NPCs**: `npc-{id}-walk-left`, `npc-{id}-idle-up-left`, etc.
|
||
|
|
- **No flipping** - uses native animations
|
||
|
|
|
||
|
|
### Legacy Sprites (5 Native Directions + Flipping)
|
||
|
|
- **Player**: `walk-right` (flipped for left), `walk-up-right` (flipped for up-left)
|
||
|
|
- **NPCs**: `npc-{id}-walk-right` (flipped for left)
|
||
|
|
- **Flipping applied** - uses setFlipX(true) for left directions
|
||
|
|
|
||
|
|
## Direction Mapping
|
||
|
|
|
||
|
|
Atlas directions → Game directions:
|
||
|
|
|
||
|
|
| Atlas Direction | Game Direction |
|
||
|
|
|----------------|----------------|
|
||
|
|
| east | right |
|
||
|
|
| west | left |
|
||
|
|
| north | up |
|
||
|
|
| south | down |
|
||
|
|
| north-east | up-right |
|
||
|
|
| north-west | up-left |
|
||
|
|
| south-east | down-right |
|
||
|
|
| south-west | down-left |
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
Tested with:
|
||
|
|
- ✅ NPCs using atlas sprites (female_office_worker, male_spy, etc.)
|
||
|
|
- ✅ Player using atlas sprite (female_hacker_hood)
|
||
|
|
- ✅ Legacy NPCs still working (hacker, hacker-red)
|
||
|
|
- ✅ 8-directional movement for atlas sprites
|
||
|
|
- ✅ Proper facing when idle
|
||
|
|
- ✅ Correct animations during patrol
|
||
|
|
- ✅ Smooth animation transitions
|
||
|
|
|
||
|
|
## Backward Compatibility
|
||
|
|
|
||
|
|
The system remains fully backward compatible:
|
||
|
|
- Legacy sprites continue to use the flip-based system
|
||
|
|
- Detection is automatic based on animation existence
|
||
|
|
- No changes required to existing scenarios using legacy sprites
|
||
|
|
- Both systems can coexist in the same game
|
||
|
|
|
||
|
|
## Performance
|
||
|
|
|
||
|
|
No performance impact:
|
||
|
|
- Animation existence check is cached by Phaser
|
||
|
|
- Single extra check per animation play (negligible)
|
||
|
|
- Atlas sprites actually perform better (fewer texture swaps)
|
||
|
|
|
||
|
|
## Known Issues
|
||
|
|
|
||
|
|
None currently identified.
|
||
|
|
|
||
|
|
## Future Improvements
|
||
|
|
|
||
|
|
- [ ] Cache the atlas detection result per NPC/player to avoid repeated checks
|
||
|
|
- [ ] Add visual debug mode to show which direction NPC is facing
|
||
|
|
- [ ] Consider refactoring to a unified animation manager for player and NPCs
|