Files
BreakEscape/tools/README_SPRITE_CONVERTER.md
Z. Cliffe Schreuders fb6e9b603c Enhance character sprite loading and animation handling
- 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.
2026-02-11 00:18:21 +00:00

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 folders
  • output_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 animations field 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
    });
}
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

  1. Frame Rate: Adjust frameRate in your animations based on the visual speed you want (typically 8-12 for character animations)

  2. Preloading: Load all sprite sheets in the preload phase to avoid lag during gameplay

  3. Multiple Characters: Process all characters at once - the script handles multiple character directories automatically

  4. Direction Names: The script preserves PixelLab's direction names (east, north, north-east, etc.)

  5. 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 animations metadata enables dynamic animation creation without hardcoding frame names