/src/de/nulldesign/nd2d/materials/texture/ASpriteSheetBase.as

https://bitbucket.org/HopeSky/mars_nd2d · ActionScript · 250 lines · 143 code · 54 blank · 53 comment · 19 complexity · 163c1c4a5ec2469017a16c1bb298446a MD5 · raw file

  1. /*
  2. * ND2D - A Flash Molehill GPU accelerated 2D engine
  3. *
  4. * Author: Lars Gerckens
  5. * Copyright (c) nulldesign 2011
  6. * Repository URL: http://github.com/nulldesign/nd2d
  7. * Getting started: https://github.com/nulldesign/nd2d/wiki
  8. *
  9. *
  10. * Licence Agreement
  11. *
  12. * Permission is hereby granted, free of charge, to any person obtaining a copy
  13. * of this software and associated documentation files (the "Software"), to deal
  14. * in the Software without restriction, including without limitation the rights
  15. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  16. * copies of the Software, and to permit persons to whom the Software is
  17. * furnished to do so, subject to the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be included in
  20. * all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  28. * THE SOFTWARE.
  29. */
  30. package de.nulldesign.nd2d.materials.texture {
  31. import de.nulldesign.nd2d.events.SpriteSheetAnimationEvent;
  32. import de.nulldesign.nd2d.materials.texture.SpriteSheetAnimation;
  33. import flash.events.EventDispatcher;
  34. import flash.geom.Point;
  35. import flash.geom.Rectangle;
  36. import flash.utils.Dictionary;
  37. public class ASpriteSheetBase extends EventDispatcher {
  38. protected var frames:Vector.<Rectangle> = new Vector.<Rectangle>();
  39. protected var offsets:Vector.<Point> = new Vector.<Point>();
  40. protected var frameNameToIndex:Dictionary = new Dictionary();
  41. protected var uvRects:Vector.<Rectangle>;
  42. protected var animationMap:Dictionary = new Dictionary();
  43. protected var activeAnimation:SpriteSheetAnimation;
  44. protected var spritesPackedWithoutSpace:Boolean;
  45. protected var ctime:Number = 0.0;
  46. protected var otime:Number = 0.0;
  47. protected var interp:Number = 0.0;
  48. protected var triggerEventOnLastFrame:Boolean = false;
  49. protected var frameIdx:uint = 0;
  50. public var frameUpdated:Boolean = true;
  51. protected var fps:uint;
  52. protected var _spriteWidth:Number;
  53. protected var _spriteHeight:Number;
  54. protected var _sheetWidth:Number;
  55. protected var _sheetHeight:Number;
  56. public function get spriteWidth():Number {
  57. return _spriteWidth;
  58. }
  59. public function get spriteHeight():Number {
  60. return _spriteHeight;
  61. }
  62. protected var _frame:uint = int.MAX_VALUE;
  63. public function get frame():uint {
  64. return _frame;
  65. }
  66. public function set frame(value:uint):void {
  67. if(frame != value) {
  68. _frame = value;
  69. frameUpdated = true;
  70. if(frames.length - 1 >= _frame) {
  71. _spriteWidth = frames[_frame].width;
  72. _spriteHeight = frames[_frame].height;
  73. }
  74. }
  75. }
  76. /**
  77. * returns the total number of frames (sprites) in a spritesheet
  78. */
  79. public function get totalFrames():uint {
  80. return frames.length;
  81. }
  82. public function ASpriteSheetBase() {
  83. }
  84. public function update(t:Number):void {
  85. if(!activeAnimation) return;
  86. var prevFrameIdx:int = frameIdx;
  87. ctime = t;
  88. // Update the timer part, to get time based animation
  89. interp += fps * (ctime - otime);
  90. if(interp >= 1.0) {
  91. frameIdx++;
  92. interp = 0;
  93. }
  94. if(activeAnimation.loop) {
  95. frameIdx = frameIdx % activeAnimation.numFrames;
  96. } else {
  97. frameIdx = Math.min(frameIdx, activeAnimation.numFrames - 1);
  98. }
  99. frame = activeAnimation.frames[frameIdx];
  100. otime = ctime;
  101. // skipped frames
  102. if(triggerEventOnLastFrame && (frameIdx == activeAnimation.numFrames - 1 || frameIdx < prevFrameIdx)) {
  103. if(!activeAnimation.loop) {
  104. triggerEventOnLastFrame = false;
  105. }
  106. dispatchEvent(new SpriteSheetAnimationEvent(SpriteSheetAnimationEvent.ANIMATION_FINISHED));
  107. }
  108. }
  109. public function stopCurrentAnimation():void {
  110. activeAnimation = null;
  111. }
  112. public function playAnimation(name:String, startIdx:uint = 0, restart:Boolean = false, triggerEventOnLastFrame:Boolean = false):void {
  113. this.triggerEventOnLastFrame = triggerEventOnLastFrame;
  114. if(restart || activeAnimation != animationMap[name]) {
  115. frameIdx = startIdx;
  116. activeAnimation = animationMap[name];
  117. frame = activeAnimation.frames[0];
  118. }
  119. }
  120. public function addAnimation(name:String, keyFrames:Array, loop:Boolean):void {
  121. }
  122. public function clone():ASpriteSheetBase {
  123. return null;
  124. }
  125. public function getOffsetForFrame():Point {
  126. return offsets[frame];
  127. }
  128. /**
  129. * Returns the current selected frame rectangle if no frameIdx is specified, otherwise the rect of the given frameIdx
  130. * @param frameIdx
  131. * @return
  132. */
  133. public function getDimensionForFrame(frameIdx:int = -1):Rectangle {
  134. return frames[frameIdx > -1 ? frameIdx : frame];
  135. }
  136. /**
  137. * converts a frame name to a index
  138. * @param name
  139. * @return
  140. */
  141. public function getIndexForFrame(name:String):uint {
  142. return frameNameToIndex[name];
  143. }
  144. /**
  145. * sets an a frame by a given name
  146. * @param value
  147. */
  148. public function setFrameByName(value:String):void {
  149. frame = getIndexForFrame(value);
  150. }
  151. /**
  152. * Convenience method to directly set an animation frame by name
  153. * @param name of the animation to set
  154. * @param index frame in the animation to set
  155. */
  156. public function setFrameByAnimationName(name:String, index:uint = 0):void {
  157. if(animationMap[name]) {
  158. frame = animationMap[name].frames[index];
  159. }
  160. }
  161. public function getUVRectForFrame(textureWidth:Number, textureHeight:Number):Rectangle {
  162. if(uvRects[frame]) {
  163. return uvRects[frame];
  164. }
  165. var rect:Rectangle = frames[frame].clone();
  166. var texturePixelOffset:Point = new Point((textureWidth - _sheetWidth) / 2.0, (textureHeight - _sheetHeight) / 2.0);
  167. rect.x += texturePixelOffset.x;
  168. rect.y += texturePixelOffset.y;
  169. if(spritesPackedWithoutSpace) {
  170. rect.x += 0.5;
  171. rect.y += 0.5;
  172. rect.width -= 1.0;
  173. rect.height -= 1.0;
  174. }
  175. rect.x /= textureWidth;
  176. rect.y /= textureHeight;
  177. rect.width /= textureWidth;
  178. rect.height /= textureHeight;
  179. uvRects[frame] = rect;
  180. return rect;
  181. }
  182. public function dispose():void
  183. {
  184. frames = null;
  185. offsets = null;
  186. frameNameToIndex = null;
  187. uvRects = null;
  188. animationMap = null;
  189. if(activeAnimation)
  190. {
  191. activeAnimation.dispose();
  192. activeAnimation = null;
  193. }
  194. }
  195. }
  196. }