UNPKG

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