AutoSprite
Compatible with Phaser

Sprite Sheet Generator for Phaser

Generate animated 2D sprite sheets for Phaser. Export PNG sheets and JSON frame data, then load texture keys faster.

assets/player/run.png
Example AutoSprite character sprite sheet for Phaser import

Phaser loader

PNG grid to animation keys

load.spritesheet
generateFrameNumbers
Arcade Physics ready
Loaderthis.load.spritesheet
Frame configframeWidth + frameHeight
Runtimeanims.play + setVelocityX

Output fit

What AutoSprite exports for a Phaser project

Phaser can load character animation quickly when every sheet has predictable frame dimensions and a stable texture key.

Phaser needs

  • Exact frameWidth and frameHeight
  • Texture keys that stay unique
  • Zero-indexed frame ranges for animations

AutoSprite gives

  • PNG sheets you can preview first
  • JSON data for sizing and frame counts
  • Per-animation outputs for clear loader keys

Uniform PNG sheets

Export a spritesheet for each character move so Phaser can slice it with load.spritesheet and a frame config.

JSON frame reference

Use frameWidth, frameHeight, columns, and frame count from AutoSprite's JSON metadata instead of counting cells by eye.

One sheet per animation

Keep idle, run, jump, attack, hit, or custom actions as separate texture keys you can wire into Phaser animations.

Consistent characters

Start from a prompt or single character image and keep identity stable across the web-game states you plan to play.

Export files at a glance

PNG spritesheet

load.spritesheet

Best fit when every frame uses the same width and height in a uniform grid.

JSON frame data

Frame reference

Use it to confirm frameWidth, frameHeight, columns, and the number of frames.

Multiple sheets

Separate texture keys

Load idle, run, jump, and attack with separate keys for straightforward animation setup.

Packed atlas

load.atlas

Use after packing frames with a Phaser-compatible atlas tool, not for raw AutoSprite grid sheets.

Actual workflow

From AutoSprite to Phaser in four passes

AutoSprite supplies frame art while Phaser keeps ownership of the Scene lifecycle, loader, animations, and gameplay code.

Generate the artLoad texture keysPlay animations in code
01

Prompt or image

Start from a character brief or existing concept art.

02

PNG sheet

Download one uniform spritesheet per move from AutoSprite.

03

preload()

Register texture keys with load.spritesheet and frame dimensions.

04

create/update

Create animations, then play them from input or Arcade Physics state.

01

Start with the Phaser scene in mind

Plan the character as texture keys, animation keys, and state changes your Scene can own.

  • Upload a concept image or describe the player, enemy, NPC, pickup, or effect you need.
  • Name the camera angle, silhouette, art style, and target game feel before generating frames.
  • Think in Phaser keys such as player_idle, player_run, player-attack, and PlayerScene.
AutoSprite upload step for creating a Phaser sprite character
02

Choose animations for the Animation Manager

Pick moves that map cleanly to Phaser animation keys and Scene update logic.

  • Select idle, walk, run, jump, attack, hit, or a custom action.
  • Keep each move separate so each sheet can have its own loader key and frame range.
  • Use names that match the strings your code will pass to this.anims.create() and anims.play().
Animation selection screen for Phaser sprite sheet generation
03

Generate, preview, and check the loop

Preview the animation before the PNG lands in your public assets folder.

  • Check motion timing, readable silhouettes, foot sliding, clipped weapons, and frame-to-frame consistency.
  • Confirm the sheet is a uniform grid so Phaser can slice frames from the same width and height.
  • Regenerate or adjust prompts before you copy the PNG and JSON into your project.
AutoSprite preview screen showing generated Phaser animation frames
04

Load the sheets and create animations

Copy the PNGs into your assets path, load them in preload(), then create animation keys in create().

  • Use this.load.spritesheet(key, url, { frameWidth, frameHeight }) for uniform AutoSprite sheets.
  • Use this.anims.generateFrameNumbers() with zero-indexed start and inclusive end values.
  • Use Arcade Physics, input, and animation events to decide which animation plays at runtime.

Spritesheet loader path

Load each uniform PNG with a texture key and the frame size from AutoSprite JSON.

Phaser integration docs

Atlas alternative

Use load.atlas only after packing frames into Phaser-compatible named atlas data.

Atlas import notes
AutoSprite export screen for downloading Phaser sprite sheets and JSON

Phaser loading

Settings that keep texture keys predictable

A good Phaser import keeps file paths, texture keys, frame sizes, and animation keys easy to inspect.

Loader keysFrame configAnimation ranges

Phaser loader checklist

Asset path

public/assets or loader path

Place exported PNG and JSON files where your Phaser Loader can resolve them.

Loader call

this.load.spritesheet()

Use a texture key, image URL, and frameConfig object for uniform spritesheets.

Frame config

frameWidth + frameHeight

Read these values from AutoSprite's JSON metadata so slicing matches the exported cells.

Animation frames

generateFrameNumbers()

Use spritesheet-style numbered frame indexes, usually starting at 0 and ending at frames - 1.

Looping

repeat: -1 or repeat: 0

Loop idle and run animations, but keep attack and hit finite if completion events matter.

Pixel rendering

pixelArt: true

Use Phaser's game config when scaled pixel sprites should stay crisp in the browser.

Asset flow

Keep AutoSprite output mapped to Phaser systems

Phaser works best when files, texture keys, animation keys, and Sprite instances are separate enough to debug quickly.

  • Load player_idle, player_run, and player_attack as separate spritesheet textures.
  • Create animation keys like player-idle and player-run from those texture frames.
  • Let Scene code decide playback from input, velocity, collision state, or animation events.

Phaser Scene flow

PlayerScene

preload()

01

load.spritesheet('player_run', url, frameConfig)

create()

02

anims.create({ key: 'player-run', frames })

update()

03

player.anims.play('player-run', true)

Texture keys

player_idleplayer_runplayer_attack

Animation keys

player-idleplayer-runplayer-attack

AutoSprite supplies the sheets. Phaser owns loader keys, animation keys, and runtime playback.

Import guardrails

Common Phaser sprite-sheet mistakes to avoid

Most Phaser issues come from mismatched frame config, wrong animation ranges, or mixing spritesheet and atlas APIs.

Frame sizeAnimation keysFinite loops

Frame size guessed from the PNG

Use AutoSprite's JSON frameWidth and frameHeight. A wrong cell size makes Phaser slice every frame incorrectly.

Animation end is off by one

Phaser frame indexes start at 0, and generateFrameNumbers() uses an inclusive end value. For 12 frames, end is 11.

Animation plays before it exists

Call this.anims.create() in create() before player.anims.play(), and keep animation keys consistent.

Looping attack waits forever

An animation that repeats forever will not complete. Keep one-shot attacks finite if you need animationcomplete handling.

Atlas and spritesheet APIs mixed

Use generateFrameNumbers() for load.spritesheet textures. Use generateFrameNames() only after loading a named atlas.

Workflow decision

When this Phaser workflow is the right fit

Use AutoSprite for animation coverage, then let Phaser own loading, playback, input, physics, and browser deployment.

Use AutoSprite when

Your Phaser Scene needs motion fast

Use this workflow when input feel, enemy behavior, hit timing, or browser readability is blocked by missing character frames.

Use load.spritesheet when

Frames live in a uniform grid

This is the direct fit for AutoSprite PNG sheets because Phaser can slice cells by frameWidth and frameHeight.

Use load.atlas when

You have packed named frames

Switch to atlas loading after a packing step creates Phaser-compatible JSON with named frames.

Use Arcade Physics when

Velocity and collisions drive state

Let physics decide whether the Sprite is idle, running, jumping, landing, or blocked before choosing an animation.

Pipeline fit

Built around the way Phaser developers load assets into Scenes

  • AutoSprite sits before Phaser's Loader, Texture Manager, Animation Manager, Sprite Game Objects, Scene lifecycle, and optional Arcade Physics.
  • Use it when missing 2D character motion is slowing down a web-game prototype, jam build, playable ad, or browser-first production.
  • The fit question is concrete: generate the character, download sheets, load texture keys in preload(), create animations in create(), and play them in update().

Prototype before final animation polish

Use generated idle, run, jump, and attack sheets while you tune input, camera scale, physics body size, and browser performance.

Keep Phaser as the runtime source of truth

AutoSprite supplies frame art. Phaser still owns Scenes, Loader keys, Texture Manager entries, Animation Manager keys, input, physics, and rendering config.

Choose spritesheet or atlas deliberately

Use load.spritesheet for the normal uniform AutoSprite grid. Use load.atlas only after a packing step creates named frame data.

Treat completion events carefully

Looped animations never truly finish. Use finite repeat values for attack and hit if your code waits for animationcomplete.

JavaScript handoff

Load sheets and play animation keys

After exporting AutoSprite sheets, a Phaser Scene can load textures, create animation keys, and swap motion from input or physics state.

  • Load each AutoSprite PNG with this.load.spritesheet().
  • Create global animation keys with this.anims.create().
  • Use Arcade Physics velocity and input state to choose idle, run, jump, or attack.
  • Listen for animationcomplete on finite one-shot moves.
PlayerScene.js
// Requires Arcade Physics in your game config:
// physics: { default: 'arcade', arcade: { gravity: { y: 600 } } }
class PlayerScene extends Phaser.Scene {
    preload() {
        const frame = { frameWidth: 256, frameHeight: 256 };

        this.load.spritesheet('player_idle', 'assets/player/idle.png', frame);
        this.load.spritesheet('player_run', 'assets/player/run.png', frame);
        this.load.spritesheet('player_jump', 'assets/player/jump.png', frame);
        this.load.spritesheet('player_attack', 'assets/player/attack.png', frame);
    }

    create() {
        this.anims.create({
            key: 'player-idle',
            frames: this.anims.generateFrameNumbers('player_idle', { start: 0, end: 7 }),
            frameRate: 8,
            repeat: -1,
        });

        this.anims.create({
            key: 'player-run',
            frames: this.anims.generateFrameNumbers('player_run', { start: 0, end: 11 }),
            frameRate: 14,
            repeat: -1,
        });

        this.anims.create({
            key: 'player-jump',
            frames: this.anims.generateFrameNumbers('player_jump', { start: 0, end: 7 }),
            frameRate: 12,
            repeat: 0,
        });

        this.anims.create({
            key: 'player-attack',
            frames: this.anims.generateFrameNumbers('player_attack', { start: 0, end: 9 }),
            frameRate: 16,
            repeat: 0,
        });

        this.player = this.physics.add.sprite(120, 320, 'player_idle');
        this.player.setCollideWorldBounds(true);
        this.player.anims.play('player-idle');

        this.cursors = this.input.keyboard.createCursorKeys();

        this.player.on('animationcomplete-player-attack', () => {
            this.player.anims.play('player-idle', true);
        });
    }

    update() {
        const { left, right, up, space } = this.cursors;
        const onGround = this.player.body.blocked.down;

        if (space.isDown && this.player.anims.currentAnim?.key !== 'player-attack') {
            this.player.setVelocityX(0);
            this.player.anims.play('player-attack', true);
            return;
        }

        if (this.player.anims.currentAnim?.key === 'player-attack') {
            return;
        }

        if (left.isDown) {
            this.player.setVelocityX(-180);
            this.player.setFlipX(true);
            if (onGround) this.player.anims.play('player-run', true);
        } else if (right.isDown) {
            this.player.setVelocityX(180);
            this.player.setFlipX(false);
            if (onGround) this.player.anims.play('player-run', true);
        } else {
            this.player.setVelocityX(0);
            if (onGround) this.player.anims.play('player-idle', true);
        }

        if (up.isDown && onGround) {
            this.player.setVelocityY(-420);
            this.player.anims.play('player-jump', true);
        }
    }
}

Phaser use cases

Where a Phaser sprite sheet generator helps most

AutoSprite helps most when missing animation frames are blocking playable browser tests, Scene behavior, or motion timing.

Ship browser buildsTune Arcade PhysicsCover animation keys

Browser game prototypes

Create enough idle, run, jump, and attack motion to test controls, canvas scale, input feel, and browser performance quickly.

Arcade Physics characters

Generate player, enemy, NPC, and effect sheets that can be driven by velocity, collision checks, and Scene update logic.

Animation-key coverage

Export the exact moves your Phaser Scene expects so code can call real animation keys during playtesting.

FAQ

Phaser sprite sheet questions

These are the practical questions developers usually ask before they try the workflow in a real Phaser project.

Q

Does AutoSprite work with Phaser?

A

Yes. AutoSprite exports PNG spritesheets and JSON frame data that support a Phaser 3 load.spritesheet workflow. Use the JSON to set frameWidth, frameHeight, and the animation frame range.

Q

Should I use load.spritesheet or load.atlas?

A

Use load.spritesheet for the normal AutoSprite grid export. Use load.atlas only after you pack frames into a Phaser-compatible atlas with named frame data.

Q

What frame range should I pass to generateFrameNumbers?

A

Phaser frame indexes start at 0, and the end value is inclusive. If AutoSprite's JSON says the animation has 12 frames, use start: 0 and end: 11.

Q

Can I use one animation on several Phaser sprites?

A

Yes. Animations created through this.anims.create() are global Animation Manager entries, so multiple Sprite Game Objects can play the same animation key.

Q

How do I keep pixel art crisp in Phaser?

A

Set pixelArt: true in the Phaser game config for pixel-art games. Phaser also supports antialias settings, but pixelArt is the direct project-level option for crisp scaled sprites.

Q

How do I return an attack animation back to idle?

A

Make the attack animation finite with repeat: 0, then listen for the matching dynamic event, such as animationcomplete-player-attack, or the Phaser ANIMATION_COMPLETE event and play idle when it finishes.

Generate your first Phaser sprite sheet.

Start with a prompt or character image, choose the Phaser animation moves you need, and export PNG sheets when the motion is ready to test.

AutoSprite is independent and is not sponsored by or affiliated with Phaser, Phaser Studio, or Photon Storm.