playable.js
Version:
A lightweight HTML5 game engine.
124 lines (105 loc) • 2.71 kB
text/typescript
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
}