PageRenderTime 30ms CodeModel.GetById 20ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 0ms

/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
 31package de.nulldesign.nd2d.materials.texture {
 32
 33	import de.nulldesign.nd2d.events.SpriteSheetAnimationEvent;
 34	import de.nulldesign.nd2d.materials.texture.SpriteSheetAnimation;
 35
 36	import flash.events.EventDispatcher;
 37
 38	import flash.geom.Point;
 39	import flash.geom.Rectangle;
 40	import flash.utils.Dictionary;
 41
 42	public class ASpriteSheetBase extends EventDispatcher {
 43
 44		protected var frames:Vector.<Rectangle> = new Vector.<Rectangle>();
 45		protected var offsets:Vector.<Point> = new Vector.<Point>();
 46		protected var frameNameToIndex:Dictionary = new Dictionary();
 47		protected var uvRects:Vector.<Rectangle>;
 48		protected var animationMap:Dictionary = new Dictionary();
 49		protected var activeAnimation:SpriteSheetAnimation;
 50
 51		protected var spritesPackedWithoutSpace:Boolean;
 52
 53		protected var ctime:Number = 0.0;
 54		protected var otime:Number = 0.0;
 55		protected var interp:Number = 0.0;
 56
 57		protected var triggerEventOnLastFrame:Boolean = false;
 58
 59		protected var frameIdx:uint = 0;
 60
 61		public var frameUpdated:Boolean = true;
 62
 63		protected var fps:uint;
 64
 65		protected var _spriteWidth:Number;
 66		protected var _spriteHeight:Number;
 67		protected var _sheetWidth:Number;
 68		protected var _sheetHeight:Number;
 69
 70		public function get spriteWidth():Number {
 71			return _spriteWidth;
 72		}
 73
 74		public function get spriteHeight():Number {
 75			return _spriteHeight;
 76		}
 77
 78		protected var _frame:uint = int.MAX_VALUE;
 79
 80		public function get frame():uint {
 81			return _frame;
 82		}
 83
 84		public function set frame(value:uint):void {
 85			if(frame != value) {
 86				_frame = value;
 87				frameUpdated = true;
 88
 89				if(frames.length - 1 >= _frame) {
 90					_spriteWidth = frames[_frame].width;
 91					_spriteHeight = frames[_frame].height;
 92				}
 93			}
 94		}
 95
 96		/**
 97		 * returns the total number of frames (sprites) in a spritesheet
 98		 */
 99		public function get totalFrames():uint {
100			return frames.length;
101		}
102
103		public function ASpriteSheetBase() {
104
105		}
106
107		public function update(t:Number):void {
108
109			if(!activeAnimation) return;
110
111			var prevFrameIdx:int = frameIdx;
112
113			ctime = t;
114
115			// Update the timer part, to get time based animation
116			interp += fps * (ctime - otime);
117			if(interp >= 1.0) {
118				frameIdx++;
119				interp = 0;
120			}
121
122			if(activeAnimation.loop) {
123				frameIdx = frameIdx % activeAnimation.numFrames;
124			} else {
125				frameIdx = Math.min(frameIdx, activeAnimation.numFrames - 1);
126			}
127
128			frame = activeAnimation.frames[frameIdx];
129
130			otime = ctime;
131
132			// skipped frames
133			if(triggerEventOnLastFrame && (frameIdx == activeAnimation.numFrames - 1 || frameIdx < prevFrameIdx)) {
134				if(!activeAnimation.loop) {
135					triggerEventOnLastFrame = false;
136				}
137				dispatchEvent(new SpriteSheetAnimationEvent(SpriteSheetAnimationEvent.ANIMATION_FINISHED));
138			}
139		}
140
141		public function stopCurrentAnimation():void {
142			activeAnimation = null;
143		}
144
145		public function playAnimation(name:String, startIdx:uint = 0, restart:Boolean = false, triggerEventOnLastFrame:Boolean = false):void {
146
147			this.triggerEventOnLastFrame = triggerEventOnLastFrame;
148
149			if(restart || activeAnimation != animationMap[name]) {
150				frameIdx = startIdx;
151				activeAnimation = animationMap[name];
152				frame = activeAnimation.frames[0];
153			}
154		}
155
156		public function addAnimation(name:String, keyFrames:Array, loop:Boolean):void {
157
158		}
159
160		public function clone():ASpriteSheetBase {
161			return null;
162		}
163
164		public function getOffsetForFrame():Point {
165			return offsets[frame];
166		}
167
168		/**
169		 * Returns the current selected frame rectangle if no frameIdx is specified, otherwise the rect of the given frameIdx
170		 * @param frameIdx
171		 * @return
172		 */
173		public function getDimensionForFrame(frameIdx:int = -1):Rectangle {
174			return frames[frameIdx > -1 ? frameIdx : frame];
175		}
176
177		/**
178		 * converts a frame name to a index
179		 * @param name
180		 * @return
181		 */
182		public function getIndexForFrame(name:String):uint {
183			return frameNameToIndex[name];
184		}
185
186		/**
187		 * sets an a frame by a given name
188		 * @param value
189		 */
190		public function setFrameByName(value:String):void {
191			frame = getIndexForFrame(value);
192		}
193
194		/**
195		 * Convenience method to directly set an animation frame by name
196		 * @param name of the animation to set
197		 * @param index frame in the animation to set
198		 */
199		public function setFrameByAnimationName(name:String, index:uint = 0):void {
200			if(animationMap[name]) {
201				frame = animationMap[name].frames[index];
202			}
203		}
204
205		public function getUVRectForFrame(textureWidth:Number, textureHeight:Number):Rectangle {
206
207			if(uvRects[frame]) {
208				return uvRects[frame];
209			}
210
211			var rect:Rectangle = frames[frame].clone();
212			var texturePixelOffset:Point = new Point((textureWidth - _sheetWidth) / 2.0, (textureHeight - _sheetHeight) / 2.0);
213
214			rect.x += texturePixelOffset.x;
215			rect.y += texturePixelOffset.y;
216
217			if(spritesPackedWithoutSpace) {
218				rect.x += 0.5;
219				rect.y += 0.5;
220
221				rect.width -= 1.0;
222				rect.height -= 1.0;
223			}
224
225			rect.x /= textureWidth;
226			rect.y /= textureHeight;
227			rect.width /= textureWidth;
228			rect.height /= textureHeight;
229
230			uvRects[frame] = rect;
231
232			return rect;
233		}
234		
235		public function dispose():void
236		{
237			frames = null;
238			offsets = null;
239			frameNameToIndex = null;
240			uvRects = null;
241			animationMap = null;
242			
243			if(activeAnimation)
244			{
245				activeAnimation.dispose();
246				activeAnimation = null;
247			}
248		}
249	}
250}