Skip to main content

animations

Use this skill when creating or controlling sprite animations in Phaser 4. Covers spritesheets, atlases, AnimationManager, AnimationState, play/stop/chain, frame callbacks, and animation events. Triggers on: sprite animation, spritesheet, play animation, animation frames.

설치로 이동

소스 정보

저장소
phaserjs/phaser
최근 소스 활동
2026년 4월 10일 12:38
감지된 SKILL.md 언어
영어
스타
40,324
포크
7,160

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
animations
description
Use this skill when creating or controlling sprite animations in Phaser 4. Covers spritesheets, atlases, AnimationManager, AnimationState, play/stop/chain, frame callbacks, and animation events. Triggers on: sprite animation, spritesheet, play animation, animation frames.
# Phaser 4 -- Sprite Animations > AnimationManager (global), AnimationState (per-sprite), creating animations from spritesheets and atlases, playing/pausing/chaining, animation events, frame callbacks. **Related skills:** ../sprites-and-images/SKILL.md, ../loading-assets/SKILL.md --- ## Quick Start ```js // In preload -- load a spritesheet this.load.spritesheet('explosion', 'explosion.png', { frameWidth: 64, frameHeight: 64 }); // In create -- define a global animation this.anims.create({ key: 'explode', frames: this.anims.generateFrameNumbers('explosion', { start: 0, end: 11 }), frameRate: 24, repeat: 0 }); // Play it on a sprite const sprite = this.add.sprite(400, 300, 'explosion'); sprite.play('explode'); ``` --- ## Core Concepts ### AnimationManager vs AnimationState Phaser has two distinct animation objects: | Aspect | AnimationManager | AnimationState | |---|---|---| | Access | `this.anims` (in a Scene) or `this.game.anims` | `sprite.anims` | | Scope | Global -- shared across all scenes | Per-sprite instance | | Purpose | Create/store animation definitions | Control playback on one Game Object | | Class | `Phaser.Animations.AnimationManager` | `Phaser.Animations.AnimationState` | The AnimationManager is a singleton owned by the Game. Animations registered there are available in every Scene. The AnimationState lives on each Sprite and handles playback for that specific object. An `Animation` is a sequence of `AnimationFrame` objects plus timing data. Created via `this.anims.create(config)` (global) or `sprite.anims.create(config)` (local to one sprite). ### Local vs Global Animations When `sprite.anims.play(key)` is called, it first checks for a local animation with that key, then falls back to the global AnimationManager. Use local for sprite-specific animations; use global when shared across sprites. ```js // Global animation -- available to all sprites this.anims.create({ key: 'walk', frames: 'player_walk', frameRate: 12, repeat: -1 }); // Local animation -- only on this sprite sprite.anims.create({ key: 'walk', frames: 'npc_walk', frameRate: 10, repeat: -1 }); // This plays the LOCAL version because local takes priority sprite.play('walk'); ``` --- ## Common Patterns ### Spritesheet Animation Use `generateFrameNumbers` for spritesheets (numeric frame indices). ```js this.load.spritesheet('dude', 'dude.png', { frameWidth: 32, frameHeight: 48 }); // All frames this.anims.create({ key: 'run', frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 7 }), frameRate: 10, repeat: -1 }); // Custom frame sequence this.anims.create({ key: 'idle', frames: this.anims.generateFrameNumbers('dude', { frames: [0, 1, 2, 1] }), frameRate: 6, repeat: -1 }); ``` `generateFrameNumbers` config: - `start` (default `0`) -- first frame index - `end` (default `-1`, meaning last frame) -- final frame index - `first` -- a single frame to prepend before the range - `frames` -- explicit array of frame indices (overrides start/end) ### Atlas Animation Use `generateFrameNames` for texture atlases (string-based frame names). ```js this.load.atlas('gems', 'gems.png', 'gems.json'); this.anims.create({ key: 'ruby_sparkle', frames: this.anims.generateFrameNames('gems', { prefix: 'ruby_', start: 1, end: 6, zeroPad: 4 // produces ruby_0001 through ruby_0006 }), frameRate: 12, repeat: -1 }); ``` `generateFrameNames` config: - `prefix` -- prepended to each frame number - `suffix` -- appended after each frame number - `start`, `end` -- numeric range - `zeroPad` -- left-pad numbers to this length with zeros - `frames` -- explicit array of frame numbers (overrides start/end) If you call `generateFrameNames(key)` with no config, it returns all frames from the atlas. ### String as Frames Pass a texture key string as `frames` to use all frames from that texture, sorted numerically by default. Set `sortFrames: false` to disable sorting. ```js this.anims.create({ key: 'walk', frames: 'player_walk', frameRate: 12, repeat: -1 }); ``` ### Yoyo and Repeat ```js this.anims.create({ key: 'pulse', frames: this.anims.generateFrameNumbers('orb', { start: 0, end: 5 }), frameRate: 10, yoyo: true, // plays forward then backward repeat: -1, // -1 = forever repeatDelay: 500 // ms pause between each repeat cycle }); ``` When `yoyo` is true, the animation plays forward then reverses. The full cycle counts as one play. ### Chaining Animations ```js sprite.play('attack'); sprite.chain('idle'); // play idle after attack completes sprite.chain(['fall', 'land', 'idle']); // chain multiple sprite.anims.chain(); // clear the chain queue ``` Chaining is per-sprite. Chained animations start after `animationcomplete` or `animationstop`. An animation with `repeat: -1` never completes -- call `stop()` to trigger the chain. ### Playing in Reverse ```js // Play an animation from last frame to first sprite.playReverse('walk'); // Reverse direction mid-playback sprite.anims.reverse(); ``` `playReverse` sets `forward = false` and `inReverse = true`. The `reverse()` method toggles direction mid-playback. ### Play Variants ```js sprite.play('walk', true); // ignoreIfPlaying = true sprite.anims.playAfterDelay('walk', 1000); // play after 1s delay sprite.anims.playAfterRepeat('walk', 2); // play after current anim repeats 2x ``` ### Animation Mixing Adds a transition delay between two specific animations, set globally on the AnimationManager. ```js this.anims.addMix('idle', 'walk', 200); this.anims.addMix('walk', 'idle', 300); sprite.play('idle'); sprite.play('walk'); // 200ms mix delay applied automatically this.anims.removeMix('idle', 'walk'); // remove specific pair this.anims.removeMix('idle'); // remove all mixes for 'idle' ``` Mix delays only apply with `sprite.play()`, not `playAfterDelay` or `playAfterRepeat`. ### Pause, Resume, and Stop ```js sprite.anims.pause(); // pause per-sprite sprite.anims.resume(); // resume per-sprite this.anims.pauseAll(); // global pause this.anims.resumeAll(); // global resume sprite.anims.stop(); // stop immediately sprite.anims.stopAfterDelay(2000); // stop after 2 seconds sprite.anims.stopAfterRepeat(1); // stop after 1 more repeat sprite.anims.stopOnFrame(frame); // stop when a specific frame is reached ``` All stop methods fire `animationstop` (not `animationcomplete`). Chained animations trigger after stop. ### Animation Events ```js sprite.on('animationcomplete', (anim, frame, gameObject, frameKey) => { console.log('completed:', anim.key); }); // Key-specific complete -- only fires for the named animation sprite.on('animationcomplete-explode', (anim, frame, gameObject, frameKey) => { gameObject.destroy(); }); ``` Available events: `animationstart`, `animationcomplete`, `animationcomplete-{key}`, `animationupdate`, `animationstop`, `animationrepeat`, `animationrestart`. All share the same callback signature: `(animation, frame, gameObject, frameKey)`. ### Frame-Level Callbacks via animationupdate ```js sprite.on('animationupdate', (anim, frame, gameObject, frameKey) => { if (anim.key === 'attack' && frame.index === 4) { this.checkHit(gameObject); } }); ``` ### Per-Frame Duration Individual frames can have a `duration` (ms) that is added to the base msPerFrame. ```js this.anims.create({ key: 'combo', frames: [ { key: 'fighter', frame: 'punch1', duration: 50 }, { key: 'fighter', frame: 'kick', duration: 200 }, // hold longer { key: 'fighter', frame: 'recover', duration: 100 } ], frameRate: 24 }); ``` ### Visibility, Random Start, and TimeScale ```js // Visibility control this.anims.create({ key: 'appear', frames: 'sparkle', frameRate: 12, showOnStart: true, // sprite.visible = true when anim starts (after delay) hideOnComplete: true, // sprite.visible = false when anim completes showBeforeDelay: true // show first frame immediately even during delay }); // Random start frame -- each sprite begins on a different frame this.anims.create({ key: 'ambient', frames: 'fire', frameRate: 10, repeat: -1, randomFrame: true }); // TimeScale -- per-sprite or global speed control sprite.anims.timeScale = 2; // 2x speed sprite.play({ key: 'walk', timeScale: 0.5 }); // half speed via config this.anims.globalTimeScale = 0.5; // affects ALL animations ``` ### Staggered Playback ```js const enemies = this.add.group({ key: 'enemy', repeat: 9 }); this.anims.staggerPlay('walk', enemies.getChildren(), 100); // Each sprite starts 100ms after the previous. Pass staggerFirst: false to skip delay on first. ``` ### JSON Export and Import ```js // Export all global animations to JSON const data = this.anims.toJSON(); // Import animations from JSON (pass true to clear existing animations first) this.anims.fromJSON(data); this.anims.fromJSON(data, true); // Check before creating to avoid duplicate warning if (!this.anims.exists('walk')) { this.anims.create({ key: 'walk', frames: 'player_walk', frameRate: 12, repeat: -1 }); } ``` ### Modifying Animation Frames at Runtime ```js const anim = this.anims.get('walk'); // Add frames to the end anim.addFrame(this.anims.generateFrameNumbers('player', { start: 8, end: 10 })); // Insert frames at a specific index anim.addFrameAt(this.anims.generateFrameNumbers('player', { frames: [5] }), 2); // Remove a specific frame object const frame = anim.frames[3]; anim.removeFrame(frame); // Remove frame at index anim.removeFrameAt(0); ``` ### Aseprite Support ```js this.load.aseprite('paladin', 'paladin.png', 'paladin.json'); // In create: this.anims.createFromAseprite('paladin'); // all tags this.anims.createFromAseprite('paladin', ['walk']); // specific tags only sprite.play('walk'); // play by tag name ``` --- ## Configuration Reference ### AnimationConfig (used with `this.anims.create()`) | Property | Type | Default | Description | |---|---|---|---| | `key` | string | -- | Unique identifier for the animation | | `frames` | string or AnimationFrame[] | `[]` | Texture key string (uses all frames) or array of frame config objects | | `sortFrames` | boolean | `true` | Numerically sort frames when using a string key | | `defaultTextureKey` | string | `null` | Fallback texture key if not set per-frame | | `frameRate` | number | `24` | Playback rate in frames per second (used if `duration` is null) | | `duration` | number | `null` | Total animation length in ms (derives frameRate if set) | | `skipMissedFrames` | boolean | `true` | Skip frames when lagging behind | | `delay` | number | `0` | Delay before playback starts (ms) | | `repeat` | number | `0` | Times to repeat after first play (-1 = infinite) | | `repeatDelay` | number | `0` | Delay before each repeat (ms) | | `yoyo` | boolean | `false` | Reverse back to start before repeating | | `showBeforeDelay` | boolean | `false` | Show first frame immediately during delay period |
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기