PageRenderTime 212ms CodeModel.GetById 100ms app.highlight 11ms RepoModel.GetById 60ms app.codeStats 0ms

/AnimViewTool/src/fw/anim/AnimSprite.as

https://bitbucket.org/ntibor22/spritesheet
ActionScript | 251 lines | 157 code | 61 blank | 33 comment | 27 complexity | fd258269d77a558f5ce1e49d418051d1 MD5 | raw file
  1package fw.anim
  2{
  3	import flash.display.Bitmap;
  4	import flash.display.BitmapData;
  5	
  6	// =============================  Created by: Amos Laber, Dec 2, 2011
  7	
  8	//
  9	// AnimSprite is a class to diplay an animated sprite sheet
 10	// it is initialized with a sprite sheet and can hold multiple 
 11	// animation sequnces that can be switched anytime
 12	//
 13	
 14	public class AnimSprite extends Bitmap 
 15	{
 16		protected var mAnimSheet:AnimTextureSheet;
 17		protected var mSequences:Array;
 18		
 19		protected var curAnim:AnimSeqData;  // current sequence
 20		protected var dirty:Boolean;
 21		protected var donePlaying:Boolean;
 22		protected var curIndex:uint;  // Frame index into tile sheet 
 23		protected var curFrame:uint;  // Frame index in a sequence (local)
 24		
 25		protected var frameDelay:Number; // for fps 
 26		
 27		
 28		
 29		// Internal, used to time each frame of animation.
 30		protected var frameTimer:Number;
 31		
 32		public static const LEFT:uint= 1;
 33		public static const RIGHT:uint= 2;
 34		
 35		
 36		
 37		public function AnimSprite(bitmapData:BitmapData=null)
 38		{
 39			super(bitmapData);
 40			
 41			frameTimer= 0;
 42			mSequences= [];
 43			
 44		}
 45		
 46		//
 47		// Initialize the sprite with the texture sheet.
 48		//  supportFlip: set to true if you intend to use right/left flipping
 49		//
 50		public function initialize(sheet:AnimTextureSheet):void
 51		{
 52			if (!sheet) return;
 53			
 54			mAnimSheet= sheet;
 55			frameDelay=0;
 56			
 57			// Create the frame buffer
 58			bitmapData = new BitmapData(mAnimSheet.maxRect.width, mAnimSheet.maxRect.height); 
 59			smoothing= true;
 60			
 61			curAnim = null;
 62			this.frame= 0;
 63			
 64			drawFrame(true);
 65		}
 66		
 67		private var _fps:int;
 68		
 69		public function get fps():int { return _fps; }
 70		public function forceFrameRate(fps:int):void
 71		{
 72			_fps = fps;
 73			frameDelay= 1.0 / fps;
 74		}
 75		
 76		public function destroy():void
 77		{
 78			if (bitmapData) {
 79				bitmapData.dispose();
 80			}
 81		}
 82		
 83		// Check if we are playing a sequence
 84		//
 85		public function isPlaying(index:int=0):Boolean
 86		{
 87			return !donePlaying;
 88		}
 89		
 90		public function get tileSheet():AnimTextureSheet { return mAnimSheet; }
 91		
 92		public function get numFrames():int { return mAnimSheet.numFrames; }
 93		public function get numSequences():int { return mSequences.length; }
 94		
 95		public function get seqFrame():uint { return curFrame; }
 96		
 97		public function get frame():uint { return curIndex; }
 98		
 99		public function set frame(val:uint):void
100		{
101			curFrame = val;
102			
103			if (curAnim)
104				curIndex= curAnim.arFrames[curFrame];
105			else curIndex= val;
106			
107			//curAnim = null;
108			dirty = true;
109		}
110		
111		
112		
113		public function getSequenceData(seq:int):AnimSeqData { return mSequences[seq]; }
114		public function getSequence(seq:int):String { return mSequences[seq].seqName; }
115		
116		public function addSequence(name:String, frames:Array, frameRate:Number=0, looped:Boolean=true):void
117		{
118			mSequences.push(new AnimSeqData(name, frames, frameRate, looped));
119		}
120		
121		public function findSequence(name:String):AnimSeqData
122		{
123			return findSequenceByName(name);
124		}
125		
126		private function findSequenceByName(name:String):AnimSeqData
127		{
128			var aSeq:AnimSeqData;
129			for (var i:int = 0; i < mSequences.length; i++) {
130				aSeq = AnimSeqData(mSequences[i]);
131				if (aSeq.seqName == name) {
132					return aSeq;
133				}
134			}
135			return null;
136		}
137		
138		// Start playing a sequence
139		//
140		public function play(name:String=null):void
141		{
142			// Continue playing from last frame
143			if (name == null) {
144				donePlaying= false;
145				dirty= true;
146				frameTimer = 0;
147				
148				return;
149			}
150			
151			curFrame = 0;
152			curIndex = 0;
153			frameTimer = 0;
154			
155			curAnim= findSequenceByName(name);
156			if (!curAnim) {
157				trace("play: cannot find sequence: " + name);
158				return;
159			}
160			
161			// trace("playing " + name +", frames: " + curAnim.arFrames.length);
162			
163			// Set to first frame
164			curIndex= curAnim.arFrames[0];
165			
166			if (frameDelay==0) frameDelay= curAnim.delay;
167			donePlaying= false;
168			dirty= true;
169			
170			// Stop if we only have a single frame
171			if (curAnim.arFrames.length==1) donePlaying= true;
172		}
173		
174		
175		// External use only (editor) 
176		//
177		public function stop():void
178		{
179			donePlaying= true;
180		}
181		
182		// Manually advance one frame forwards or back
183		// Used by the viewer (not the game)
184		//
185		public function frameAdvance(next:Boolean):void
186		{
187			if (next) {
188				if (curFrame < curAnim.arFrames.length -1) ++curFrame;
189			}
190			else {
191				if (curFrame > 0) --curFrame;
192			}
193			
194			curIndex= curAnim.arFrames[curFrame];
195			dirty= true;
196		}
197		
198		
199		public function drawFrame(force:Boolean=false):void
200		{
201			if(force || dirty)
202				drawFrameInternal();
203		}
204		
205	
206		
207		//  Call this function on every frame update
208		//  
209		public function updateAnimation(delta:int):void
210		{
211			//trace("updateAnimation delta=" + delta + ", frd=" + frameDelay)
212			if (curAnim!=null && frameDelay > 0 && !donePlaying) {
213				
214				// Check elapsed time and adjust to sequence rate 
215				frameTimer += (delta/1000.0);
216				while(frameTimer > frameDelay) {
217					frameTimer = frameTimer - frameDelay;
218					advanceFrame();
219				}
220			}
221			
222			if (dirty) drawFrameInternal();
223		}
224		
225		// 
226		//
227		protected function advanceFrame():void
228		{
229			if (curFrame == curAnim.arFrames.length -1) {
230				if (curAnim.loop)
231					curFrame = 0;
232				else donePlaying= true; 
233				
234			}
235			else ++curFrame;
236			
237			curIndex= curAnim.arFrames[curFrame];
238			dirty= true;
239		}
240		
241		// Internal function to update the current animation frame
242		protected function drawFrameInternal():void
243		{
244			dirty = false;
245			
246			bitmapData.fillRect(bitmapData.rect, 0);
247			mAnimSheet.drawFrame(curIndex, bitmapData);
248		}
249		
250	}
251}