UNPKG

7.93 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return function (d, b) {
7 extendStatics(d, b);
8 function __() { this.constructor = d; }
9 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10 };
11})();
12Object.defineProperty(exports, "__esModule", { value: true });
13var Module_1 = require("./../Module");
14var Tool_1 = require("./../Tool");
15var index_1 = require("./../index");
16/**
17 * Sprite module to generate animations from spritesheets
18 */
19var Sprite = (function (_super) {
20 __extends(Sprite, _super);
21 /* LIFECYCLE */
22 /**
23 * @constructor
24 */
25 function Sprite() {
26 var _this = _super.call(this) || this;
27 /**
28 * Know if the sprite is loaded and can be animated
29 * @readonly
30 */
31 _this.loaded = false;
32 /**
33 * List of all animations
34 * @readonly
35 */
36 _this.animations = [];
37 /**
38 * The PIXI Container
39 * @readonly
40 */
41 _this.container = new index_1.PIXI.Sprite();
42 _this.signals.propChange.bind("imageId", _this.onImageIdChange.bind(_this));
43 _this.signals.propChange.bind("centered", _this.onCenteredChange.bind(_this));
44 return _this;
45 }
46 /**
47 * @initialize
48 * @lifecycle
49 * @override
50 */
51 Sprite.prototype.initialize = function (props) {
52 if (props === void 0) { props = {}; }
53 var width = props.width || this.props.width, height = props.height || this.props.height, centered = typeof props.centered !== "undefined" ? props.centered : this.props.centered;
54 if (centered) {
55 props.x = (props.x || 0) + (width / 2);
56 props.y = (props.y || 0) + (height / 2);
57 }
58 _super.prototype.initialize.call(this, props);
59 this.onCenteredChange();
60 };
61 /* METHODS */
62 /**
63 * Add an animation for the current sprite
64 * @param name - Name of the animation
65 * @param duration - Duration of the animation (in ms)
66 * @param frames - Array of frames to be displayed during the animation
67 * @param maxLoop - number of loop. If loop === -1, there will be no limit of loop
68 * @param offset - offset x and y related to the position of the Entity
69 * @returns current instance to chain this function
70 */
71 Sprite.prototype.addAnimation = function (name, duration, frames, maxLoop, offset) {
72 if (maxLoop === void 0) { maxLoop = -1; }
73 if (!name || !frames) {
74 throw new Error("Sprite.addAnimation: You must set a name, duration and frames.");
75 }
76 this.animations.push({
77 name: name,
78 duration: duration,
79 frames: frames,
80 frameIndex: 0,
81 loop: 0,
82 maxLoop: maxLoop,
83 offset: offset,
84 textureFrames: this._framesToRectangles(frames)
85 });
86 if (this.animations.length === 1 && this.loaded) {
87 this.setAnimation(name);
88 }
89 return this;
90 };
91 /**
92 * Set the current animation for the sprite
93 * @param name - Name of the animation
94 * @param restart - If true, restart the entire information about the animation such as number of loop
95 */
96 Sprite.prototype.setAnimation = function (name, restart) {
97 if (restart === void 0) { restart = false; }
98 if (!restart && this.animation && this.animation.name === name) {
99 return null;
100 }
101 this.animation = this.getAnimation(name);
102 if (this.animation) {
103 this.animation.loop = 0;
104 this.animation.frameIndex = 0;
105 if (this.animation.offset) {
106 this.setProps({
107 x: this.animation.offset.x,
108 y: this.animation.offset.y
109 });
110 }
111 if (this.loaded) {
112 this.container.texture.frame = this.animation.textureFrames[this.animation.frameIndex];
113 this.timers.addTimer("sprite", this.animation.duration, this.onNextSprite.bind(this));
114 }
115 }
116 };
117 /**
118 * Get an existing animation for the sprite
119 * @param name - Name of the animation
120 * @returns The animation object
121 */
122 Sprite.prototype.getAnimation = function (name) {
123 return this.animations.find(function (animation) { return animation.name === name; });
124 };
125 /**
126 * Remove the animation by its name
127 * @param name - Name of the animation to remove
128 */
129 Sprite.prototype.removeAnimation = function (name) {
130 this.animations = this.animations.filter(function (animation) { return animation.name === name; });
131 };
132 /**
133 * Convert frame indexes to pixi rectangles
134 * @private
135 * @param frames - Frames to convert
136 * @returns Frames converted to pixi rectangles
137 */
138 Sprite.prototype._framesToRectangles = function (frames) {
139 var _this = this;
140 if (!this.image) {
141 return [];
142 }
143 return frames.map(function (frame) { return new index_1.PIXI.Rectangle(Math.floor(frame * _this.props.width) % _this.image.width, Math.floor(frame * _this.props.width / _this.image.width) * _this.props.height, _this.props.width, _this.props.height); });
144 };
145 /* EVENTS */
146 /**
147 * When "centered" attributes has changed
148 */
149 Sprite.prototype.onCenteredChange = function () {
150 if (this.props.centered) {
151 this.container.anchor.set(0.5, 0.5);
152 }
153 else {
154 this.container.anchor.set(0, 0);
155 }
156 };
157 /**
158 * When timer of a frame is finished
159 */
160 Sprite.prototype.onNextSprite = function () {
161 if (this.animation.frameIndex >= (this.animation.frames.length - 1)) {
162 this.animation.loop++;
163 this.animation.frameIndex = this.animation.maxLoop > -1 && this.animation.loop > this.animation.maxLoop ? this.animation.frames.length - 1 : 0;
164 }
165 else {
166 this.animation.frameIndex++;
167 }
168 if (this.animation.maxLoop < 0 || this.animation.loop < this.animation.maxLoop) {
169 this.container.texture.frame = this.animation.textureFrames[this.animation.frameIndex];
170 this.timers.getTimer("sprite").restart();
171 }
172 else if (this.props.autoKill) {
173 this.kill();
174 }
175 };
176 /**
177 * When "imageId" attributes change
178 */
179 Sprite.prototype.onImageIdChange = function () {
180 var _this = this;
181 Tool_1.Assets.get(this.props.imageId, function (resource) {
182 var texture = new index_1.PIXI.Texture(resource.texture);
183 _this.container.texture = texture;
184 _this.image = resource.data;
185 if (!_this.props.width && !_this.props.height) {
186 _this.addAnimation("idle", 1, [0]);
187 _this.props.width = _this.image.width;
188 _this.props.height = _this.image.height;
189 }
190 texture.frame = new index_1.PIXI.Rectangle(0, 0, _this.props.width, _this.props.height);
191 _this.animations.forEach(function (animation) { return animation.textureFrames = _this._framesToRectangles(animation.frames); });
192 _this.loaded = true;
193 if (_this.animations.length && !_this.animation) {
194 _this.setAnimation(_this.animations[0].name, true);
195 }
196 });
197 };
198 /**
199 * @override
200 */
201 Sprite.prototype.onFlipChange = function () {
202 this.container.anchor.x = this.props.flip ? -0.5 : 0.5;
203 _super.prototype.onFlipChange.call(this);
204 };
205 return Sprite;
206}(Module_1.Module));
207exports.Sprite = Sprite;