From 12011b1743a8feec2cc5cf8b09c87a7faf227e7a Mon Sep 17 00:00:00 2001 From: PrimaryFeather Date: Tue, 26 Jul 2011 22:13:41 +0200 Subject: [PATCH] added MovieClip class (closes #5) --- samples/demo/media/audio/step.mp3 | Bin 0 -> 2750 bytes samples/demo/src/Assets.as | 19 ++ samples/demo/src/Game.as | 5 + samples/demo/src/scenes/MovieScene.as | 61 +++++ starling/src/starling/display/Image.as | 6 +- starling/src/starling/display/MovieClip.as | 228 ++++++++++++++++++ starling/src/starling/events/Event.as | 1 + .../src/starling/textures/TextureAtlas.as | 6 +- tests/src/tests/TextureAtlasTest.as | 2 +- 9 files changed, 323 insertions(+), 5 deletions(-) create mode 100644 samples/demo/media/audio/step.mp3 create mode 100644 samples/demo/src/scenes/MovieScene.as create mode 100644 starling/src/starling/display/MovieClip.as diff --git a/samples/demo/media/audio/step.mp3 b/samples/demo/media/audio/step.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..33d2692f06debc531598e152e0c1bc34f6a30c55 GIT binary patch literal 2750 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 + private var mSounds:Vector.; + private var mDurations:Vector.; + + private var mDefaultFrameDuration:Number; + private var mTotalTime:Number; + private var mCurrentTime:Number; + private var mCurrentFrame:int; + private var mLoop:Boolean; + private var mPlaying:Boolean; + + public function MovieClip(textures:Array, fps:Number=12) + { + if (textures.length > 0) + { + super(textures[0]); + mDefaultFrameDuration = 1.0 / fps; + mLoop = true; + mPlaying = true; + mTotalTime = 0.0; + mCurrentTime = 0.0; + mCurrentFrame = 0; + mTextures = new []; + mSounds = new []; + mDurations = new []; + + for each (var texture:Texture in textures) + addFrame(texture); + } + else + { + throw new ArgumentError("Empty texture array"); + } + } + + // frame manipulation + + public function addFrame(texture:Texture, sound:Sound=null, duration:Number=-1):void + { + addFrameAt(numFrames, texture, sound, duration); + } + + public function addFrameAt(frameID:int, texture:Texture, sound:Sound=null, + duration:Number=-1):void + { + if (frameID < 0 || frameID > numFrames) throw new ArgumentError("Invalid frame id"); + if (duration < 0) duration = mDefaultFrameDuration; + mTextures.splice(frameID, 0, texture); + mSounds.splice(frameID, 0, sound); + mDurations.splice(frameID, 0, duration); + mTotalTime += duration; + } + + public function removeFrameAt(frameID:int):void + { + if (frameID < 0 || frameID >= numFrames) throw new ArgumentError("Invalid frame id"); + mTotalTime -= getFrameDuration(frameID); + mTextures.splice(frameID, 1); + mSounds.splice(frameID, 1); + mDurations.splice(frameID, 1); + } + + public function getFrameTexture(frameID:int):Texture + { + if (frameID < 0 || frameID >= numFrames) throw new ArgumentError("Invalid frame id"); + return mTextures[frameID]; + } + + public function setFrameTexture(frameID:int, texture:Texture):void + { + if (frameID < 0 || frameID >= numFrames) throw new ArgumentError("Invalid frame id"); + mTextures[frameID] = texture; + } + + public function getFrameSound(frameID:int):Sound + { + if (frameID < 0 || frameID >= numFrames) throw new ArgumentError("Invalid frame id"); + return mSounds[frameID]; + } + + public function setFrameSound(frameID:int, sound:Sound):void + { + if (frameID < 0 || frameID >= numFrames) throw new ArgumentError("Invalid frame id"); + mSounds[frameID] = sound; + } + + public function getFrameDuration(frameID:int):Number + { + if (frameID < 0 || frameID >= numFrames) throw new ArgumentError("Invalid frame id"); + return mDurations[frameID]; + } + + public function setFrameDuration(frameID:int, duration:Number):void + { + if (frameID < 0 || frameID >= numFrames) throw new ArgumentError("Invalid frame id"); + mTotalTime -= getFrameDuration(frameID); + mTotalTime += duration; + mDurations[frameID] = duration; + } + + // helper methods + + private function updateCurrentFrame():void + { + texture = mTextures[mCurrentFrame]; + } + + private function playCurrentSound():void + { + var sound:Sound = mSounds[mCurrentFrame]; + if (sound) sound.play(); + } + + // playback methods + + public function play():void + { + mPlaying = true; + } + + public function pause():void + { + mPlaying = false; + } + + public function stop():void + { + mPlaying = false; + currentFrame = 0; + } + + // IAnimatable + + public function advanceTime(passedTime:Number):void + { + if (mLoop && mCurrentTime == mTotalTime) mCurrentTime = 0.0; + if (!mPlaying || passedTime == 0.0 || mCurrentTime == mTotalTime) return; + + var i:int = 0; + var durationSum:Number = 0.0; + var previousTime:Number = mCurrentTime; + var restTime:Number = mTotalTime - mCurrentTime; + var carryOverTime:Number = passedTime > restTime ? passedTime - restTime : 0.0; + mCurrentTime = Math.min(mTotalTime, mCurrentTime + passedTime); + + for each (var duration:Number in mDurations) + { + if (durationSum + duration >= mCurrentTime) + { + if (mCurrentFrame != i) + { + mCurrentFrame = i; + updateCurrentFrame(); + playCurrentSound(); + } + break; + } + + ++i; + durationSum += duration; + } + + if (previousTime < mTotalTime && mCurrentTime == mTotalTime && + hasEventListener(Event.MOVIE_COMPLETED)) + { + dispatchEvent(new Event(Event.MOVIE_COMPLETED)); + } + + advanceTime(carryOverTime); + } + + public function get isComplete():Boolean + { + return false; + } + + // properties + + public function get totalTime():Number { return mTotalTime; } + public function get numFrames():int { return mTextures.length; } + + public function get loop():Boolean { return mLoop; } + public function set loop(value:Boolean):void { mLoop = value; } + + public function get currentFrame():int { return mCurrentFrame; } + public function set currentFrame(value:int):void + { + mCurrentFrame = value; + mCurrentTime = 0.0; + + for each (var duration:Number in mDurations) + mCurrentTime += duration; + + updateCurrentFrame(); + } + + public function get fps():Number { return 1.0 / mDefaultFrameDuration; } + public function set fps(value:Number):void + { + var newFrameDuration:Number = value == 0.0 ? Number.MAX_VALUE : 1.0 / value; + var acceleration:Number = newFrameDuration / mDefaultFrameDuration; + mCurrentTime *= acceleration; + mDefaultFrameDuration = newFrameDuration; + + for (var i:int=0; i + public function getTextures(prefix:String=""):Array { - var textures:Vector. = new []; - var names:Vector. = new []; + var textures:Array = []; + var names:Array = []; var name:String; for (name in mTextureRegions) diff --git a/tests/src/tests/TextureAtlasTest.as b/tests/src/tests/TextureAtlasTest.as index 32520f220..31685f7f4 100644 --- a/tests/src/tests/TextureAtlasTest.as +++ b/tests/src/tests/TextureAtlasTest.as @@ -74,7 +74,7 @@ package tests atlas.addRegion("bob", new Rectangle(24, 0, 8, 8)); atlas.addRegion("prefix_2", new Rectangle(32, 0, 2, 8)); - var textures:Vector. = atlas.getTextures("prefix_"); + var textures:Array = atlas.getTextures("prefix_"); Assert.assertEquals(3, textures.length); Assert.assertEquals(1, textures[0].width);