- Updated the game to support new character sprite atlases for both male and female characters, allowing for a wider variety of NPC designs. - Improved player sprite initialization to dynamically select between atlas-based and legacy sprites, enhancing flexibility in character representation. - Refined collision box settings based on sprite type, ensuring accurate physics interactions for both atlas (80x80) and legacy (64x64) sprites. - Enhanced NPC behavior to utilize atlas animations, allowing for more fluid and diverse animations based on available frames. Files modified: - game.js: Added new character atlases and updated sprite loading logic. - player.js: Improved player sprite handling and collision box adjustments. - npc-behavior.js: Updated animation handling for NPCs to support atlas-based animations. - npc-sprites.js: Enhanced NPC sprite creation to accommodate atlas detection and initial frame selection. - scenario.json.erb: Updated player and NPC configurations to utilize new sprite sheets and animation settings. - m01_npc_sarah.ink: Revised dialogue options to include new interactions related to NPCs.
5.9 KiB
PixelLab to Phaser.js Sprite Sheet Converter
This script converts PixelLab character animation directories into optimized sprite sheets with Phaser.js-compatible JSON atlases.
Why Sprite Sheets?
For Phaser.js games, sprite sheets are essential for:
- Performance: Single HTTP request instead of dozens/hundreds
- Memory: More efficient GPU texture management
- Rendering: Faster frame switching during animations
- Loading: Quicker initial load times
Installation
The script requires Python 3.6+ and Pillow (PIL):
pip install Pillow
Or if you have a requirements.txt:
pip install -r requirements.txt
Usage
Basic Usage
python tools/convert_pixellab_to_spritesheet.py ~/Downloads/characters ./assets/sprites
Arguments
input_dir: Directory containing PixelLab character foldersoutput_dir: Where to save the generated sprite sheets and atlases--padding: (Optional) Padding between frames in pixels (default: 2)
Example
# Convert all characters from Downloads to game assets
python tools/convert_pixellab_to_spritesheet.py \
~/Downloads/characters \
./public/break_escape/assets/characters
Input Directory Structure
The script expects this structure (as exported from PixelLab):
characters/
├── Female_woman._Hacker_in_a_hoodie._Hood_up_black_ob/
│ └── animations/
│ ├── breathing-idle/
│ │ ├── east/
│ │ │ ├── frame_000.png
│ │ │ ├── frame_001.png
│ │ │ └── ...
│ │ ├── north/
│ │ ├── north-east/
│ │ └── ...
│ ├── walk/
│ │ ├── east/
│ │ └── ...
│ └── ...
└── Other_Character/
└── animations/
└── ...
Output Files
For each character, the script generates two files:
1. Sprite Sheet PNG (character_name.png)
- Single PNG combining all animation frames
- Optimized layout for efficient GPU usage
- Transparent background (RGBA)
2. Atlas JSON (character_name.json)
- Phaser.js-compatible JSON Hash format
- Contains frame positions and dimensions
- Includes animation metadata organized by type and direction
- Custom
animationsfield for easy animation creation
Using in Phaser.js
1. Loading the Sprite Sheet
function preload() {
this.load.atlas(
'female_hacker',
'break_escape/assets/characters/female_hacker.png',
'break_escape/assets/characters/female_hacker.json'
);
}
2. Creating Animations
Manual Method:
function create() {
this.anims.create({
key: 'breathing-idle-east',
frames: this.anims.generateFrameNames('female_hacker', {
prefix: 'breathing-idle_east_frame_',
start: 0,
end: 3,
zeroPad: 3
}),
frameRate: 8,
repeat: -1
});
}
Dynamic Method (Recommended):
function create() {
// Load the atlas data
const atlasTexture = this.textures.get('female_hacker');
const atlasData = this.cache.json.get('female_hacker');
// Create all animations from metadata
if (atlasData.animations) {
for (const [animKey, frames] of Object.entries(atlasData.animations)) {
this.anims.create({
key: animKey,
frames: frames.map(frameName => ({
key: 'female_hacker',
frame: frameName
})),
frameRate: 8,
repeat: -1
});
}
}
// Use the animation
const sprite = this.add.sprite(400, 300, 'female_hacker');
sprite.play('breathing-idle_east');
}
3. Switching Animations
// Change direction based on player input
if (cursors.right.isDown) {
sprite.play('walk_east', true);
} else if (cursors.up.isDown) {
sprite.play('walk_north', true);
} else {
sprite.play('breathing-idle_east', true);
}
Atlas JSON Structure
The generated JSON includes:
{
"frames": {
"breathing-idle_east_frame_000": {
"frame": {"x": 0, "y": 0, "w": 80, "h": 80},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x": 0, "y": 0, "w": 80, "h": 80},
"sourceSize": {"w": 80, "h": 80}
},
...
},
"meta": {
"app": "PixelLab to Phaser Converter",
"image": "female_hacker.png",
"format": "RGBA8888",
"size": {"w": 1280, "h": 960},
"scale": "1"
},
"animations": {
"breathing-idle_east": ["breathing-idle_east_frame_000", "breathing-idle_east_frame_001", ...],
"breathing-idle_north": [...],
"walk_east": [...],
...
}
}
Tips
-
Frame Rate: Adjust
frameRatein your animations based on the visual speed you want (typically 8-12 for character animations) -
Preloading: Load all sprite sheets in the preload phase to avoid lag during gameplay
-
Multiple Characters: Process all characters at once - the script handles multiple character directories automatically
-
Direction Names: The script preserves PixelLab's direction names (east, north, north-east, etc.)
-
Animation Keys: Animation keys are formatted as
{animation-type}_{direction}(e.g.,walk_east,breathing-idle_north)
Troubleshooting
No animations found: Ensure your character directory has an animations subdirectory
Frame size mismatch: All frames should be the same dimensions (e.g., 80x80 pixels)
Large sprite sheets: If your sprite sheet is too large, consider splitting characters into separate sheets or reducing frame counts
Performance Notes
- Each sprite sheet is kept as a single texture for optimal GPU performance
- The JSON atlas allows Phaser to quickly locate frames without additional parsing
- The
animationsmetadata enables dynamic animation creation without hardcoding frame names