or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdanimation.mdaudio.mdcameras.mddata-management.mdevents.mdgame-objects.mdindex.mdinput.mdloading.mdmath-geometry.mdphysics.mdrendering.mdscenes.mdtweens.mdutilities.md

animation.mddocs/

0

# Animation Systems

1

2

Phaser provides two powerful animation systems: frame-based animations for sprite sequences and tween animations for smooth property interpolation. These systems work together to create rich, dynamic visual effects.

3

4

## Frame-Based Animations

5

6

### Animation Manager

7

The global animation manager handles all sprite animations:

8

9

```javascript { .api }

10

class AnimationScene extends Phaser.Scene {

11

preload() {

12

// Load spritesheet for animations

13

this.load.spritesheet('player', 'assets/player.png', {

14

frameWidth: 32,

15

frameHeight: 48

16

});

17

18

// Load texture atlas

19

this.load.atlas('characters', 'assets/characters.png', 'assets/characters.json');

20

}

21

22

create() {

23

// Create animations from spritesheet

24

this.anims.create({

25

key: 'player-walk',

26

frames: this.anims.generateFrameNumbers('player', { start: 0, end: 3 }),

27

frameRate: 10,

28

repeat: -1

29

});

30

31

this.anims.create({

32

key: 'player-idle',

33

frames: [{ key: 'player', frame: 4 }],

34

frameRate: 20

35

});

36

37

// Create animations from texture atlas

38

this.anims.create({

39

key: 'enemy-attack',

40

frames: this.anims.generateFrameNames('characters', {

41

prefix: 'enemy-attack-',

42

start: 1,

43

end: 6,

44

zeroPad: 3

45

}),

46

frameRate: 15,

47

repeat: 0

48

});

49

50

// Complex animation configuration

51

this.anims.create({

52

key: 'explosion',

53

frames: this.anims.generateFrameNumbers('explosion', { start: 0, end: 15 }),

54

frameRate: 20,

55

repeat: 0,

56

hideOnComplete: true,

57

yoyo: false,

58

delay: 0,

59

repeatDelay: 0,

60

showOnStart: true,

61

randomFrame: false,

62

duration: 800 // Override frameRate calculation

63

});

64

}

65

}

66

```

67

68

### Animation Configuration

69

Comprehensive animation options:

70

71

```javascript { .api }

72

// Animation creation with all options

73

scene.anims.create({

74

key: 'complex-animation',

75

frames: scene.anims.generateFrameNumbers('sprite', { start: 0, end: 7 }),

76

77

// Timing

78

frameRate: 12, // Frames per second

79

duration: 1000, // Total duration (overrides frameRate)

80

delay: 500, // Delay before starting

81

82

// Repetition

83

repeat: 3, // Number of repeats (-1 = infinite)

84

repeatDelay: 200, // Delay between repeats

85

yoyo: true, // Play forward then backward

86

87

// Visibility

88

showOnStart: true, // Show sprite when animation starts

89

hideOnComplete: false, // Hide sprite when animation completes

90

91

// Frame selection

92

randomFrame: false, // Start on random frame

93

skipMissedFrames: true, // Skip frames if running slow

94

95

// Events

96

onStart: (animation, frame, gameObject) => {

97

console.log('Animation started');

98

},

99

onRepeat: (animation, frame, gameObject) => {

100

console.log('Animation repeated');

101

},

102

onUpdate: (animation, frame, gameObject) => {

103

console.log('Frame updated to:', frame.index);

104

},

105

onComplete: (animation, frame, gameObject) => {

106

console.log('Animation completed');

107

}

108

});

109

```

110

111

### Frame Generation

112

Multiple ways to generate frame sequences:

113

114

```javascript { .api }

115

class FrameGenerationScene extends Phaser.Scene {

116

create() {

117

// Generate numbered frames

118

const walkFrames = this.anims.generateFrameNumbers('player', {

119

start: 0,

120

end: 7,

121

first: 1 // First frame to use (optional)

122

});

123

124

// Generate named frames (for texture atlas)

125

const runFrames = this.anims.generateFrameNames('atlas', {

126

prefix: 'run-',

127

suffix: '.png',

128

start: 1,

129

end: 8,

130

zeroPad: 3 // Pad numbers to 3 digits (001, 002, etc.)

131

});

132

133

// Custom frame array

134

const customFrames = [

135

{ key: 'atlas', frame: 'idle-1' },

136

{ key: 'atlas', frame: 'idle-2', duration: 100 }, // Custom frame duration

137

{ key: 'atlas', frame: 'idle-3' },

138

{ key: 'player', frame: 0 } // Mix different textures

139

];

140

141

// Create animations

142

this.anims.create({

143

key: 'walk',

144

frames: walkFrames,

145

frameRate: 10,

146

repeat: -1

147

});

148

149

this.anims.create({

150

key: 'run',

151

frames: runFrames,

152

frameRate: 15,

153

repeat: -1

154

});

155

156

this.anims.create({

157

key: 'custom',

158

frames: customFrames,

159

frameRate: 8,

160

repeat: -1

161

});

162

}

163

}

164

```

165

166

### Animation Control

167

Control animations on GameObjects:

168

169

```javascript { .api }

170

class AnimationControlScene extends Phaser.Scene {

171

create() {

172

this.player = this.add.sprite(400, 300, 'player');

173

174

// Play animation

175

this.player.play('walk');

176

177

// Play with options

178

this.player.play({

179

key: 'walk',

180

ignoreIfPlaying: false, // Restart even if already playing

181

startFrame: 2, // Start from specific frame

182

timeScale: 1.5 // Play 1.5x speed

183

});

184

185

// Animation state queries

186

console.log('Is playing:', this.player.anims.isPlaying);

187

console.log('Current animation:', this.player.anims.currentAnim);

188

console.log('Current frame:', this.player.anims.currentFrame);

189

console.log('Total frames:', this.player.anims.getTotalFrames());

190

console.log('Progress:', this.player.anims.getProgress());

191

192

// Animation control

193

this.player.anims.pause();

194

this.player.anims.resume();

195

this.player.anims.stop();

196

this.player.anims.restart();

197

198

// Play in reverse

199

this.player.playReverse('walk');

200

201

// Chain animations

202

this.player.chain(['walk', 'idle', 'jump']);

203

204

// Set time scale (speed multiplier)

205

this.player.anims.setTimeScale(2.0);

206

207

// Seek to specific progress

208

this.player.anims.setProgress(0.5); // 50% through animation

209

210

// Set repeat count

211

this.player.anims.setRepeat(5);

212

213

// Manual frame control

214

this.player.setFrame(3);

215

this.player.anims.nextFrame();

216

this.player.anims.previousFrame();

217

}

218

}

219

```

220

221

### Animation Events

222

Listen for animation events:

223

224

```javascript { .api }

225

class AnimationEventsScene extends Phaser.Scene {

226

create() {

227

this.player = this.add.sprite(400, 300, 'player');

228

229

// Global animation events (all sprites)

230

this.anims.on('animationstart', (anim, frame, gameObject) => {

231

console.log('Any animation started:', anim.key);

232

});

233

234

this.anims.on('animationcomplete', (anim, frame, gameObject) => {

235

console.log('Any animation completed:', anim.key);

236

});

237

238

// Specific animation events

239

this.anims.on('animationcomplete-walk', (anim, frame, gameObject) => {

240

console.log('Walk animation completed');

241

gameObject.play('idle');

242

});

243

244

// Sprite-specific events

245

this.player.on('animationstart', (anim, frame) => {

246

console.log('Player animation started:', anim.key);

247

});

248

249

this.player.on('animationupdate', (anim, frame) => {

250

console.log('Player frame:', frame.index);

251

252

// Trigger effects on specific frames

253

if (frame.index === 2) {

254

this.createFootstepEffect();

255

}

256

});

257

258

this.player.on('animationrepeat', (anim, frame) => {

259

console.log('Player animation repeated');

260

});

261

262

this.player.on('animationcomplete', (anim, frame) => {

263

console.log('Player animation completed');

264

265

// Handle animation completion

266

if (anim.key === 'attack') {

267

this.player.play('idle');

268

} else if (anim.key === 'death') {

269

this.gameOver();

270

}

271

});

272

}

273

}

274

```

275

276

## Tween Animations

277

278

### Basic Tweens

279

Smooth property interpolation:

280

281

```javascript { .api }

282

class TweenBasicsScene extends Phaser.Scene {

283

create() {

284

this.sprite = this.add.sprite(100, 300, 'player');

285

286

// Basic tween

287

this.tweens.add({

288

targets: this.sprite,

289

x: 700,

290

duration: 2000,

291

ease: 'Power2'

292

});

293

294

// Multiple properties

295

this.tweens.add({

296

targets: this.sprite,

297

x: 400,

298

y: 100,

299

scaleX: 2,

300

scaleY: 2,

301

rotation: Math.PI,

302

alpha: 0.5,

303

duration: 1500,

304

ease: 'Bounce.easeOut'

305

});

306

307

// Relative values

308

this.tweens.add({

309

targets: this.sprite,

310

x: '+=100', // Relative to current value

311

y: '-=50',

312

rotation: '+=0.5',

313

duration: 1000

314

});

315

316

// Array of values (tween through each)

317

this.tweens.add({

318

targets: this.sprite,

319

x: [100, 300, 500, 700],

320

y: [100, 200, 300, 100],

321

duration: 3000,

322

ease: 'Linear'

323

});

324

}

325

}

326

```

327

328

### Tween Configuration

329

Comprehensive tween options:

330

331

```javascript { .api }

332

class TweenConfigScene extends Phaser.Scene {

333

create() {

334

const sprite = this.add.sprite(400, 300, 'player');

335

336

// Full configuration

337

this.tweens.add({

338

targets: sprite,

339

340

// Properties to tween

341

x: 600,

342

y: 200,

343

scaleX: 1.5,

344

alpha: 0.8,

345

346

// Timing

347

duration: 2000,

348

delay: 500, // Delay before starting

349

350

// Repetition

351

repeat: 2, // Number of repeats (-1 = infinite)

352

repeatDelay: 300, // Delay between repeats

353

yoyo: true, // Return to start values

354

355

// Easing

356

ease: 'Power2.easeInOut',

357

358

// Hold

359

hold: 1000, // Hold at end values

360

361

// Callbacks

362

onStart: (tween, targets) => {

363

console.log('Tween started');

364

},

365

onUpdate: (tween, target) => {

366

console.log('Tween progress:', tween.progress);

367

},

368

onRepeat: (tween, target) => {

369

console.log('Tween repeated');

370

},

371

onComplete: (tween, targets) => {

372

console.log('Tween completed');

373

},

374

375

// Callback scope and parameters

376

callbackScope: this,

377

onCompleteParams: ['param1', 'param2']

378

});

379

}

380

}

381

```

382

383

### Easing Functions

384

Rich collection of easing functions:

385

386

```javascript { .api }

387

// Linear

388

'Linear'

389

390

// Quadratic

391

'Quad.easeIn'

392

'Quad.easeOut'

393

'Quad.easeInOut'

394

'Power1' // Same as Quad

395

396

// Cubic

397

'Cubic.easeIn'

398

'Cubic.easeOut'

399

'Cubic.easeInOut'

400

'Power2' // Same as Cubic

401

402

// Quartic

403

'Quart.easeIn'

404

'Quart.easeOut'

405

'Quart.easeInOut'

406

'Power3' // Same as Quart

407

408

// Quintic

409

'Quint.easeIn'

410

'Quint.easeOut'

411

'Quint.easeInOut'

412

'Power4' // Same as Quint

413

414

// Sine

415

'Sine.easeIn'

416

'Sine.easeOut'

417

'Sine.easeInOut'

418

419

// Exponential

420

'Expo.easeIn'

421

'Expo.easeOut'

422

'Expo.easeInOut'

423

424

// Circular

425

'Circ.easeIn'

426

'Circ.easeOut'

427

'Circ.easeInOut'

428

429

// Back

430

'Back.easeIn'

431

'Back.easeOut'

432

'Back.easeInOut'

433

434

// Elastic

435

'Elastic.easeIn'

436

'Elastic.easeOut'

437

'Elastic.easeInOut'

438

439

// Bounce

440

'Bounce.easeIn'

441

'Bounce.easeOut'

442

'Bounce.easeInOut'

443

444

// Stepped

445

'Stepped'

446

447

// Custom easing function

448

function customEase(t) {

449

return t * t * (3 - 2 * t); // Smoothstep

450

}

451

```

452

453

### Tween Control

454

Control tween playback:

455

456

```javascript { .api }

457

class TweenControlScene extends Phaser.Scene {

458

create() {

459

this.sprite = this.add.sprite(100, 300, 'player');

460

461

// Store tween reference

462

this.myTween = this.tweens.add({

463

targets: this.sprite,

464

x: 700,

465

duration: 3000,

466

paused: true // Start paused

467

});

468

469

// Tween control methods

470

this.myTween.play(); // Start/resume

471

this.myTween.pause(); // Pause

472

this.myTween.resume(); // Resume

473

this.myTween.stop(); // Stop

474

this.myTween.restart(); // Restart from beginning

475

476

// Seek to specific progress

477

this.myTween.seek(0.5); // Jump to 50% completion

478

479

// Update target values while running

480

this.myTween.updateTo('x', 500); // Change target to 500

481

this.myTween.updateTo('y', 200, true); // Change target, start from current

482

483

// Time scale (speed multiplier)

484

this.myTween.setTimeScale(2); // 2x speed

485

486

// Tween properties

487

console.log('Progress:', this.myTween.progress);

488

console.log('Duration:', this.myTween.duration);

489

console.log('Is playing:', this.myTween.isPlaying());

490

console.log('Is paused:', this.myTween.isPaused());

491

console.log('Has started:', this.myTween.hasStarted);

492

}

493

}

494

```

495

496

### Multiple Target Tweens

497

Tween multiple objects simultaneously:

498

499

```javascript { .api }

500

class MultiTargetScene extends Phaser.Scene {

501

create() {

502

// Create multiple sprites

503

const sprites = [];

504

for (let i = 0; i < 5; i++) {

505

sprites.push(this.add.sprite(100 + i * 100, 300, 'player'));

506

}

507

508

// Tween all sprites together

509

this.tweens.add({

510

targets: sprites,

511

y: 100,

512

duration: 1000,

513

ease: 'Bounce.easeOut'

514

});

515

516

// Staggered animation

517

this.tweens.add({

518

targets: sprites,

519

x: 600,

520

duration: 500,

521

delay: this.tweens.stagger(100) // 100ms delay between each

522

});

523

524

// Staggered with options

525

this.tweens.add({

526

targets: sprites,

527

scaleX: 2,

528

scaleY: 2,

529

duration: 800,

530

delay: this.tweens.stagger(150, { start: 500, from: 'center' })

531

});

532

}

533

}

534

```

535

536

### Tween Chains and Timelines

537

Sequence multiple animations:

538

539

```javascript { .api }

540

class TweenChainScene extends Phaser.Scene {

541

create() {

542

this.sprite = this.add.sprite(100, 300, 'player');

543

544

// Chain tweens together

545

const tween1 = this.tweens.add({

546

targets: this.sprite,

547

x: 400,

548

duration: 1000,

549

paused: true

550

});

551

552

const tween2 = this.tweens.add({

553

targets: this.sprite,

554

y: 100,

555

duration: 1000,

556

paused: true

557

});

558

559

const tween3 = this.tweens.add({

560

targets: this.sprite,

561

rotation: Math.PI * 2,

562

duration: 1000,

563

paused: true

564

});

565

566

// Create chain

567

this.tweens.chain({

568

tweens: [tween1, tween2, tween3]

569

}).play();

570

571

// Timeline for complex sequences

572

const timeline = this.tweens.timeline({

573

targets: this.sprite,

574

575

// Timeline tweens

576

tweens: [

577

{

578

x: 300,

579

duration: 1000

580

},

581

{

582

y: 200,

583

duration: 500,

584

offset: 800 // Start 800ms into timeline

585

},

586

{

587

rotation: Math.PI,

588

duration: 1000,

589

offset: '-=500' // Start 500ms before previous ends

590

}

591

],

592

593

// Timeline options

594

loop: 2,

595

loopDelay: 1000,

596

onComplete: () => {

597

console.log('Timeline complete');

598

}

599

});

600

}

601

}

602

```

603

604

### Counter Tweens

605

Animate numbers and custom values:

606

607

```javascript { .api }

608

class CounterTweenScene extends Phaser.Scene {

609

create() {

610

// Score counter

611

this.score = 0;

612

this.scoreText = this.add.text(400, 100, 'Score: 0', {

613

fontSize: '32px',

614

fill: '#ffffff'

615

});

616

617

// Tween the score value

618

this.tweens.addCounter({

619

from: 0,

620

to: 1000,

621

duration: 2000,

622

onUpdate: (tween) => {

623

this.score = Math.floor(tween.getValue());

624

this.scoreText.setText('Score: ' + this.score);

625

}

626

});

627

628

// Health bar animation

629

this.healthBarWidth = 200;

630

this.healthBar = this.add.rectangle(400, 200, this.healthBarWidth, 20, 0x00ff00);

631

632

this.tweens.addCounter({

633

from: 100,

634

to: 25,

635

duration: 3000,

636

ease: 'Power2.easeIn',

637

onUpdate: (tween) => {

638

const health = tween.getValue();

639

this.healthBar.width = (health / 100) * this.healthBarWidth;

640

641

// Change color based on health

642

if (health > 60) {

643

this.healthBar.fillColor = 0x00ff00; // Green

644

} else if (health > 30) {

645

this.healthBar.fillColor = 0xffff00; // Yellow

646

} else {

647

this.healthBar.fillColor = 0xff0000; // Red

648

}

649

}

650

});

651

}

652

}

653

```

654

655

### Tween Manager

656

Access and control all tweens:

657

658

```javascript { .api }

659

class TweenManagerScene extends Phaser.Scene {

660

create() {

661

// Create some tweens

662

const sprites = [

663

this.add.sprite(100, 100, 'player'),

664

this.add.sprite(200, 200, 'player'),

665

this.add.sprite(300, 300, 'player')

666

];

667

668

sprites.forEach(sprite => {

669

this.tweens.add({

670

targets: sprite,

671

x: 600,

672

duration: 2000,

673

repeat: -1,

674

yoyo: true

675

});

676

});

677

678

// Manager operations

679

const allTweens = this.tweens.getAllTweens();

680

console.log('Total tweens:', allTweens.length);

681

682

// Get tweens of specific object

683

const spriteTweens = this.tweens.getTweensOf(sprites[0]);

684

685

// Check if object is being tweened

686

const isTweening = this.tweens.isTweening(sprites[0]);

687

688

// Kill all tweens of object

689

this.tweens.killTweensOf(sprites[1]);

690

691

// Global tween control

692

this.tweens.pauseAll();

693

this.tweens.resumeAll();

694

this.tweens.killAll();

695

696

// Global time scale

697

this.tweens.setGlobalTimeScale(0.5); // Half speed

698

console.log('Global time scale:', this.tweens.getGlobalTimeScale());

699

}

700

}

701

```

702

703

## Advanced Animation Techniques

704

705

### Physics-Based Animations

706

Combine tweens with physics:

707

708

```javascript { .api }

709

class PhysicsAnimationScene extends Phaser.Scene {

710

create() {

711

// Enable physics

712

this.physics.world.gravity.y = 300;

713

714

this.ball = this.physics.add.sprite(100, 100, 'ball');

715

this.ball.setBounce(0.8);

716

this.ball.setCollideWorldBounds(true);

717

718

// Animate physics properties

719

this.tweens.add({

720

targets: this.ball.body.velocity,

721

x: 200,

722

y: -400,

723

duration: 500

724

});

725

726

// Animate gravity

727

this.tweens.add({

728

targets: this.physics.world.gravity,

729

y: 800,

730

duration: 3000,

731

yoyo: true,

732

repeat: -1

733

});

734

}

735

}

736

```

737

738

### Particle Animation

739

Animate particle system properties:

740

741

```javascript { .api }

742

class ParticleAnimationScene extends Phaser.Scene {

743

create() {

744

// Create particle emitter

745

this.particles = this.add.particles(400, 300, 'particle', {

746

speed: { min: 100, max: 200 },

747

lifespan: 1000,

748

quantity: 5

749

});

750

751

// Animate emitter properties

752

this.tweens.add({

753

targets: this.particles,

754

x: 600,

755

y: 200,

756

duration: 2000,

757

yoyo: true,

758

repeat: -1

759

});

760

761

// Animate emission rate

762

this.tweens.addCounter({

763

from: 5,

764

to: 50,

765

duration: 3000,

766

yoyo: true,

767

repeat: -1,

768

onUpdate: (tween) => {

769

this.particles.setQuantity(tween.getValue());

770

}

771

});

772

}

773

}

774

```

775

776

### Morphing Animations

777

Animate shape transformations:

778

779

```javascript { .api }

780

class MorphingScene extends Phaser.Scene {

781

create() {

782

this.graphics = this.add.graphics();

783

784

// Start shape

785

this.currentShape = {

786

x: 200,

787

y: 200,

788

radius: 50,

789

sides: 3

790

};

791

792

this.drawShape();

793

794

// Morph to different shape

795

this.tweens.add({

796

targets: this.currentShape,

797

radius: 100,

798

sides: 8,

799

duration: 2000,

800

ease: 'Power2.easeInOut',

801

onUpdate: () => {

802

this.drawShape();

803

}

804

});

805

}

806

807

drawShape() {

808

this.graphics.clear();

809

this.graphics.fillStyle(0x00ff00);

810

811

const sides = Math.round(this.currentShape.sides);

812

const angleStep = (Math.PI * 2) / sides;

813

814

this.graphics.beginPath();

815

for (let i = 0; i <= sides; i++) {

816

const angle = i * angleStep;

817

const x = this.currentShape.x + Math.cos(angle) * this.currentShape.radius;

818

const y = this.currentShape.y + Math.sin(angle) * this.currentShape.radius;

819

820

if (i === 0) {

821

this.graphics.moveTo(x, y);

822

} else {

823

this.graphics.lineTo(x, y);

824

}

825

}

826

this.graphics.fillPath();

827

}

828

}

829

```

830

831

This comprehensive animation system provides all the tools needed to create engaging, smooth animations that bring games to life with both sprite sequences and property tweening.