UNPKG

@phaserjs/phaser

Version:
268 lines (267 loc) 7.26 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; import { CreateAnimData } from "../../animation/CreateAnimData"; import { Sprite } from "../sprite/Sprite"; export class AnimatedSprite extends Sprite { constructor(x, y, texture, frame) { super(x, y, texture, frame); __publicField(this, "currentAnimation"); __publicField(this, "currentFrame"); __publicField(this, "animData"); __publicField(this, "hasStarted", false); __publicField(this, "forward", true); __publicField(this, "inReverse", false); __publicField(this, "accumulator", 0); __publicField(this, "nextTick", 0); __publicField(this, "delayCounter", 0); __publicField(this, "repeatCounter", 0); __publicField(this, "pendingRepeat", false); __publicField(this, "paused", false); __publicField(this, "wasPlaying", false); __publicField(this, "pendingStop", 0); __publicField(this, "pendingStopValue", 0); this.animData = CreateAnimData(); } handleStart() { if (this.animData.showOnStart) { this.visible = true; } this.setCurrentFrame(this.currentFrame); this.hasStarted = true; } handleRepeat() { this.pendingRepeat = false; } handleStop() { this.pendingStop = 0; this.animData.isPlaying = false; } handleComplete() { this.pendingStop = 0; this.animData.isPlaying = false; if (this.animData.hideOnComplete) { this.visible = false; } } reverse() { if (this.isPlaying) { this.inReverse = !this.inReverse; this.forward = !this.forward; } return this; } getProgress() { const frame = this.currentFrame; if (!frame) { return 0; } let p = frame.progress; if (this.inReverse) { p *= -1; } return p; } stop() { this.pendingStop = 0; this.animData.isPlaying = false; if (this.currentAnimation) { this.handleStop(); } return this; } update(delta, now) { super.update(delta, now); const data = this.animData; const anim = this.currentAnimation; if (!anim || !data.isPlaying || anim.paused) { return; } this.accumulator += delta * data.timeScale; if (this.pendingStop === 1) { this.pendingStopValue -= delta; if (this.pendingStopValue <= 0) { this.stop(); return; } } if (!this.hasStarted) { if (this.accumulator >= this.delayCounter) { this.accumulator -= this.delayCounter; this.handleStart(); } } else if (this.accumulator >= this.nextTick) { if (this.forward) { this.nextFrame(); } else { this.prevFrame(); } if (data.isPlaying && this.pendingStop === 0 && anim.skipMissedFrames && this.accumulator > this.nextTick) { let safetyNet = 0; do { if (this.forward) { this.nextFrame(); } else { this.prevFrame(); } safetyNet++; } while (data.isPlaying && this.accumulator > this.nextTick && safetyNet < 60); } } } nextFrame() { const frame = this.currentFrame; const data = this.animData; if (frame.isLast) { if (data.yoyo) { this.handleYoyoFrame(false); } else if (this.repeatCounter > 0) { if (this.inReverse && this.forward) { this.forward = false; } else { this.repeatAnimation(); } } else { this.complete(); } } else { this.setCurrentFrame(this.currentFrame.nextFrame); this.getNextTick(); } return this; } repeatAnimation() { if (this.pendingStop === 2) { if (this.pendingStopValue === 0) { return this.stop(); } else { this.pendingStopValue--; } } const data = this.animData; if (data.repeatDelay > 0 && !this.pendingRepeat) { this.pendingRepeat = true; this.accumulator -= this.nextTick; this.nextTick += data.repeatDelay; } else { this.repeatCounter--; if (this.forward) { this.setCurrentFrame(this.currentFrame.nextFrame); } else { this.setCurrentFrame(this.currentFrame.prevFrame); } if (this.isPlaying) { this.getNextTick(); this.handleRepeat(); } } } setCurrentFrame(animFrame) { this.currentFrame = animFrame; this.setTexture(animFrame.texture, animFrame.frame); } getNextTick() { this.accumulator -= this.nextTick; this.nextTick = this.currentAnimation.msPerFrame + this.currentFrame.duration; } handleYoyoFrame(isReverse = false) { const animData = this.animData; if (this.inReverse === !isReverse && this.repeatCounter > 0) { if (animData.repeatDelay === 0 || this.pendingRepeat) { this.forward = isReverse; } this.repeatAnimation(); return; } if (this.inReverse !== isReverse && this.repeatCounter === 0) { this.complete(); return; } this.forward = isReverse; if (isReverse) { this.setCurrentFrame(this.currentFrame.nextFrame); } else { this.setCurrentFrame(this.currentFrame.prevFrame); } this.getNextTick(); } prevFrame() { const frame = this.currentFrame; const animData = this.animData; if (frame.isFirst) { if (animData.yoyo) { this.handleYoyoFrame(true); } else if (this.repeatCounter > 0) { if (this.inReverse && !this.forward) { this.repeatAnimation(); } else { this.forward = true; this.repeatAnimation(); } } else { this.complete(); } } else { this.setCurrentFrame(frame.prevFrame); this.getNextTick(); } return this; } complete() { this.pendingStop = 0; this.animData.isPlaying = false; if (this.currentAnimation) { this.handleComplete(); } } play() { const data = this.animData; if (data.repeat === -1) { this.repeatCounter = Number.MAX_VALUE; } data.isPlaying = true; if (data.delay === 0) { this.setTexture(this.currentFrame.texture, this.currentFrame.frame); if (data.onStart) { data.onStart(this, this.currentAnimation); } } else { data.pendingStart = true; } return this; } pause(atFrame) { if (!this.paused) { this.paused = true; this.wasPlaying = this.isPlaying; this.animData.isPlaying = false; } if (atFrame) { this.setCurrentFrame(atFrame); } return this; } resume(fromFrame) { if (this.paused) { this.paused = false; this.animData.isPlaying = this.wasPlaying; } if (fromFrame) { this.setCurrentFrame(fromFrame); } return this; } get isPlaying() { return this.animData.isPlaying; } get isPlayingForward() { return this.animData.isPlaying && this.forward; } destroy(reparentChildren) { super.destroy(reparentChildren); this.animData = null; } }