sprite.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import { Vector3 } from "../Maths/math.vector";
  2. import { Nullable } from "../types";
  3. import { ActionManager } from "../Actions/actionManager";
  4. import { ISpriteManager, SpriteManager } from "./spriteManager";
  5. import { Color4 } from '../Maths/math.color';
  6. import { Observable } from '../Misc/observable';
  7. import { IAnimatable } from '../Animations/animatable.interface';
  8. declare type Animation = import("../Animations/animation").Animation;
  9. /**
  10. * Class used to represent a sprite
  11. * @see http://doc.babylonjs.com/babylon101/sprites
  12. */
  13. export class Sprite implements IAnimatable {
  14. /** Gets or sets the current world position */
  15. public position: Vector3;
  16. /** Gets or sets the main color */
  17. public color = new Color4(1.0, 1.0, 1.0, 1.0);
  18. /** Gets or sets the width */
  19. public width = 1.0;
  20. /** Gets or sets the height */
  21. public height = 1.0;
  22. /** Gets or sets rotation angle */
  23. public angle = 0;
  24. /** Gets or sets the cell index in the sprite sheet */
  25. public cellIndex: number;
  26. /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */
  27. public cellRef: string;
  28. /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
  29. public invertU = false;
  30. /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
  31. public invertV = false;
  32. /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */
  33. public disposeWhenFinishedAnimating: boolean;
  34. /** Gets the list of attached animations */
  35. public animations: Nullable<Array<Animation>> = new Array<Animation>();
  36. /** Gets or sets a boolean indicating if the sprite can be picked */
  37. public isPickable = false;
  38. /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */
  39. public useAlphaForPicking = false;
  40. /** @hidden */
  41. public _xOffset: number;
  42. /** @hidden */
  43. public _yOffset: number;
  44. /** @hidden */
  45. public _xSize: number;
  46. /** @hidden */
  47. public _ySize: number;
  48. /**
  49. * Gets or sets the associated action manager
  50. */
  51. public actionManager: Nullable<ActionManager>;
  52. /**
  53. * An event triggered when the control has been disposed
  54. */
  55. public onDisposeObservable = new Observable<Sprite>();
  56. private _animationStarted = false;
  57. private _loopAnimation = false;
  58. private _fromIndex = 0;
  59. private _toIndex = 0;
  60. private _delay = 0;
  61. private _direction = 1;
  62. private _manager: ISpriteManager;
  63. private _time = 0;
  64. private _onAnimationEnd: Nullable<() => void> = null;
  65. /**
  66. * Gets or sets a boolean indicating if the sprite is visible (renderable). Default is true
  67. */
  68. public isVisible = true;
  69. /**
  70. * Gets or sets the sprite size
  71. */
  72. public get size(): number {
  73. return this.width;
  74. }
  75. public set size(value: number) {
  76. this.width = value;
  77. this.height = value;
  78. }
  79. /**
  80. * Returns a boolean indicating if the animation is started
  81. */
  82. public get animationStarted() {
  83. return this._animationStarted;
  84. }
  85. /**
  86. * Gets or sets the unique id of the sprite
  87. */
  88. public uniqueId: number;
  89. /**
  90. * Gets the manager of this sprite
  91. */
  92. public get manager() {
  93. return this._manager;
  94. }
  95. /**
  96. * Creates a new Sprite
  97. * @param name defines the name
  98. * @param manager defines the manager
  99. */
  100. constructor(
  101. /** defines the name */
  102. public name: string,
  103. manager: ISpriteManager) {
  104. this._manager = manager;
  105. this._manager.sprites.push(this);
  106. this.uniqueId = this._manager.scene.getUniqueId();
  107. this.position = Vector3.Zero();
  108. }
  109. /**
  110. * Returns the string "Sprite"
  111. * @returns "Sprite"
  112. */
  113. public getClassName(): string {
  114. return "Sprite";
  115. }
  116. /** Gets or sets the initial key for the animation (setting it will restart the animation) */
  117. public get fromIndex() {
  118. return this._fromIndex;
  119. }
  120. public set fromIndex(value: number) {
  121. this.playAnimation(value, this._toIndex, this._loopAnimation, this._delay, this._onAnimationEnd);
  122. }
  123. /** Gets or sets the end key for the animation (setting it will restart the animation) */
  124. public get toIndex() {
  125. return this._toIndex;
  126. }
  127. public set toIndex(value: number) {
  128. this.playAnimation(this._fromIndex, value, this._loopAnimation, this._delay, this._onAnimationEnd);
  129. }
  130. /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation) */
  131. public get loopAnimation() {
  132. return this._loopAnimation;
  133. }
  134. public set loopAnimation(value: boolean) {
  135. this.playAnimation(this._fromIndex, this._toIndex, value, this._delay, this._onAnimationEnd);
  136. }
  137. /** Gets or sets the delay between cell changes (setting it will restart the animation) */
  138. public get delay() {
  139. return Math.max(this._delay, 1);
  140. }
  141. public set delay(value: number) {
  142. this.playAnimation(this._fromIndex, this._toIndex, this._loopAnimation, value, this._onAnimationEnd);
  143. }
  144. /**
  145. * Starts an animation
  146. * @param from defines the initial key
  147. * @param to defines the end key
  148. * @param loop defines if the animation must loop
  149. * @param delay defines the start delay (in ms)
  150. * @param onAnimationEnd defines a callback to call when animation ends
  151. */
  152. public playAnimation(from: number, to: number, loop: boolean, delay: number, onAnimationEnd: Nullable<() => void> = null): void {
  153. this._fromIndex = from;
  154. this._toIndex = to;
  155. this._loopAnimation = loop;
  156. this._delay = delay || 1;
  157. this._animationStarted = true;
  158. if (from < to) {
  159. this._direction = 1;
  160. } else {
  161. this._direction = -1;
  162. this._toIndex = from;
  163. this._fromIndex = to;
  164. }
  165. this.cellIndex = from;
  166. this._time = 0;
  167. this._onAnimationEnd = onAnimationEnd;
  168. }
  169. /** Stops current animation (if any) */
  170. public stopAnimation(): void {
  171. this._animationStarted = false;
  172. }
  173. /** @hidden */
  174. public _animate(deltaTime: number): void {
  175. if (!this._animationStarted) {
  176. return;
  177. }
  178. this._time += deltaTime;
  179. if (this._time > this._delay) {
  180. this._time = this._time % this._delay;
  181. this.cellIndex += this._direction;
  182. if (this._direction > 0 && this.cellIndex > this._toIndex || this._direction < 0 && this.cellIndex < this._fromIndex) {
  183. if (this._loopAnimation) {
  184. this.cellIndex = this._direction > 0 ? this._fromIndex : this._toIndex;
  185. } else {
  186. this.cellIndex = this._toIndex;
  187. this._animationStarted = false;
  188. if (this._onAnimationEnd) {
  189. this._onAnimationEnd();
  190. }
  191. if (this.disposeWhenFinishedAnimating) {
  192. this.dispose();
  193. }
  194. }
  195. }
  196. }
  197. }
  198. /** Release associated resources */
  199. public dispose(): void {
  200. for (var i = 0; i < this._manager.sprites.length; i++) {
  201. if (this._manager.sprites[i] == this) {
  202. this._manager.sprites.splice(i, 1);
  203. }
  204. }
  205. // Callback
  206. this.onDisposeObservable.notifyObservers(this);
  207. this.onDisposeObservable.clear();
  208. }
  209. /**
  210. * Serializes the sprite to a JSON object
  211. * @returns the JSON object
  212. */
  213. public serialize(): any {
  214. var serializationObject: any = {};
  215. serializationObject.name = this.name;
  216. serializationObject.position = this.position.asArray();
  217. serializationObject.color = this.color.asArray();
  218. serializationObject.width = this.width;
  219. serializationObject.height = this.height;
  220. serializationObject.angle = this.angle;
  221. serializationObject.cellIndex = this.cellIndex;
  222. serializationObject.cellRef = this.cellRef;
  223. serializationObject.invertU = this.invertU;
  224. serializationObject.invertV = this.invertV;
  225. serializationObject.disposeWhenFinishedAnimating = this.disposeWhenFinishedAnimating;
  226. serializationObject.isPickable = this.isPickable;
  227. serializationObject.isVisible = this.isVisible;
  228. serializationObject.useAlphaForPicking = this.useAlphaForPicking;
  229. serializationObject.animationStarted = this.animationStarted;
  230. serializationObject.fromIndex = this.fromIndex;
  231. serializationObject.toIndex = this.toIndex;
  232. serializationObject.loopAnimation = this.loopAnimation;
  233. serializationObject.delay = this.delay;
  234. return serializationObject;
  235. }
  236. /**
  237. * Parses a JSON object to create a new sprite
  238. * @param parsedSprite The JSON object to parse
  239. * @param manager defines the hosting manager
  240. * @returns the new sprite
  241. */
  242. public static Parse(parsedSprite: any, manager: SpriteManager): Sprite {
  243. var sprite = new Sprite(parsedSprite.name, manager);
  244. sprite.position = Vector3.FromArray(parsedSprite.position);
  245. sprite.color = Color4.FromArray(parsedSprite.color);
  246. sprite.width = parsedSprite.width;
  247. sprite.height = parsedSprite.height;
  248. sprite.angle = parsedSprite.angle;
  249. sprite.cellIndex = parsedSprite.cellIndex;
  250. sprite.cellRef = parsedSprite.cellRef;
  251. sprite.invertU = parsedSprite.invertU;
  252. sprite.invertV = parsedSprite.invertV;
  253. sprite.disposeWhenFinishedAnimating = parsedSprite.disposeWhenFinishedAnimating;
  254. sprite.isPickable = parsedSprite.isPickable;
  255. sprite.isVisible = parsedSprite.isVisible;
  256. sprite.useAlphaForPicking = parsedSprite.useAlphaForPicking;
  257. sprite.fromIndex = parsedSprite.fromIndex;
  258. sprite.toIndex = parsedSprite.toIndex;
  259. sprite.loopAnimation = parsedSprite.loopAnimation;
  260. sprite.delay = parsedSprite.delay;
  261. if (parsedSprite.animationStarted) {
  262. sprite.playAnimation(sprite.fromIndex, sprite.toIndex, sprite.loopAnimation, sprite.delay);
  263. }
  264. return sprite;
  265. }
  266. }