UNPKG

playable.js

Version:

A lightweight HTML5 game engine.

124 lines (105 loc) 2.71 kB
import {Image} from './Image'; import {Event} from '../event/Event'; import {Texture} from '../media/Texture'; import {Rectangle} from '../geom/Rectangle'; export class MovieClip extends Image { protected $loop: boolean = true; protected $interval: number = 30; protected $paused: boolean = false; protected $currentFrame: number = 0; protected $frames: Array<MovieClipFrame> = null; protected $timer: number; protected $boundNextFrame: Function; public constructor(texture: Texture, frames: Array<MovieClipFrame>) { super(texture); this.$frames = frames; this.$boundNextFrame = this.nextFrame.bind(this); this.play(); } public get loop(): boolean { return this.$loop; } public set loop(loop: boolean) { this.$loop = loop; } public get interval(): number { return this.$interval; } public set interval(interval: number) { this.$interval = interval; } public get paused(): boolean { return this.$paused; } public get currentFrame(): number { return this.$currentFrame; } public get totalFrames(): number { return this.$frames.length; } public play(): this { this.off(Event.ADDED_TO_STAGE, this.play); return this.gotoAndPlay(this.$currentFrame); } public pause(): this { let ticker = this.ticker; this.$paused = true; if (ticker) { ticker.clearTimeout(this.$timer); } this.off(Event.ADDED_TO_STAGE, this.play); return this; } public nextFrame(): this { return this.gotoAndPlay(this.$currentFrame + 1); } public gotoAndPlay(frame: number): this { this.$paused = false; this.$gotoFrame(frame); let loop = this.$loop; let ticker = this.ticker; let frames = this.$frames; let totalFrames = frames.length; let frameData = frames[this.$currentFrame]; if (!frameData) { return; } if (ticker) { ticker.clearTimeout(this.$timer); if (frame < totalFrames - 1 || loop) { this.$timer = ticker.setTimeout(this.$boundNextFrame, frameData.interval || this.$interval); } } else { this.on(Event.ADDED_TO_STAGE, this.play); } return this; } public gotoAndStop(frame: number): this { this.$paused = true; this.$gotoFrame(frame); return this; } protected $gotoFrame(frame: number): void { let totalFrames = this.$frames.length; if (frame < 0 || frame >= totalFrames) { frame = (frame + totalFrames) % totalFrames; } if (frame < 0) { frame = 0; } let frameData = this.$frames[frame]; if (!frameData) { return; } this.$currentFrame = frame; this.clipRect = frameData.clip; if (this.stage && frameData.callback) { frameData.callback.call(this); } } } export interface MovieClipFrame { clip: Rectangle, interval?: number, callback?: Function }