From 667e41664d80475b8d2ba04df3e2df9170bb754c Mon Sep 17 00:00:00 2001 From: newagebegins Date: Fri, 15 Jun 2012 00:18:25 +1100 Subject: [PATCH] refactoring - use Animation --- SpecRunner.html | 1 + spec/AnimationSpec.js | 40 +++++++++++++++++++++++++++++++++ spec/ExplosionSpec.js | 26 +++------------------ spec/TankStateAppearingSpec.js | 1 + spec/TankStateInvincibleSpec.js | 21 ----------------- spec/TankStateNormalSpec.js | 18 +++++---------- src/Animation.js | 31 ++++++++++++++++++++++--- src/Explosion.js | 27 ++++++---------------- src/TankStateAppearing.js | 6 ++++- src/TankStateInvincible.js | 18 ++++----------- src/TankStateNormal.js | 16 ++++--------- 11 files changed, 99 insertions(+), 106 deletions(-) create mode 100644 spec/AnimationSpec.js diff --git a/SpecRunner.html b/SpecRunner.html index 3d75d0f..6f295ae 100644 --- a/SpecRunner.html +++ b/SpecRunner.html @@ -43,6 +43,7 @@ + diff --git a/spec/AnimationSpec.js b/spec/AnimationSpec.js new file mode 100644 index 0000000..ecdd5a0 --- /dev/null +++ b/spec/AnimationSpec.js @@ -0,0 +1,40 @@ +describe("Animation", function () { + it("no loop", function () { + var animation = new Animation([1,2]); + expect(animation.getFrame()).toEqual(1); + expect(animation.isCompleted()).toBeFalsy(); + animation.update(); + expect(animation.getFrame()).toEqual(2); + expect(animation.isCompleted()).toBeFalsy(); + animation.update(); + expect(animation.getFrame()).toEqual(2); + expect(animation.isCompleted()).toBeTruthy(); + }); + + it("loop", function () { + var animation = new Animation([1,2], 1, true); + expect(animation.getFrame()).toEqual(1); + expect(animation.isCompleted()).toBeFalsy(); + animation.update(); + expect(animation.getFrame()).toEqual(2); + expect(animation.isCompleted()).toBeFalsy(); + animation.update(); + expect(animation.getFrame()).toEqual(1); + expect(animation.isCompleted()).toBeFalsy(); + }); + + it("duration", function () { + var animation = new Animation([1,2], 2); + expect(animation.getFrame()).toEqual(1); + animation.update(); + expect(animation.getFrame()).toEqual(1); + animation.update(); + expect(animation.getFrame()).toEqual(2); + animation.update(); + expect(animation.getFrame()).toEqual(2); + expect(animation.isCompleted()).toBeFalsy(); + animation.update(); + expect(animation.getFrame()).toEqual(2); + expect(animation.isCompleted()).toBeTruthy(); + }); +}); diff --git a/spec/ExplosionSpec.js b/spec/ExplosionSpec.js index bf43ffe..d6a1a22 100644 --- a/spec/ExplosionSpec.js +++ b/spec/ExplosionSpec.js @@ -1,32 +1,12 @@ describe("Explosion", function () { - var eventManager, explosion; - - beforeEach(function () { - eventManager = new EventManager(); - explosion = new Explosion(eventManager); - }); - - it("default state", function () { - expect(explosion.getFramesCount()).toEqual(3); - }); - - it("should be animated", function () { - expect(explosion.getFrame()).toEqual(1); - explosion.update(); - expect(explosion.getFrame()).toEqual(2); - explosion.update(); - expect(explosion.getFrame()).toEqual(3); - }); - it("should be destroyed when animation is finished", function () { - var FRAMES_COUNT = 3; + var eventManager = new EventManager(); + var explosion = new Explosion(eventManager); spyOn(explosion, 'destroy'); - explosion.setFramesCount(FRAMES_COUNT); - explosion.setFrame(FRAMES_COUNT - 1); + explosion.setFrames([1]); explosion.update(); expect(explosion.destroy).not.toHaveBeenCalled(); explosion.update(); expect(explosion.destroy).toHaveBeenCalled(); - expect(explosion.getFrame()).toEqual(FRAMES_COUNT); }); }); diff --git a/spec/TankStateAppearingSpec.js b/spec/TankStateAppearingSpec.js index d6e8d91..c3582c5 100644 --- a/spec/TankStateAppearingSpec.js +++ b/spec/TankStateAppearingSpec.js @@ -10,6 +10,7 @@ describe("TankStateAppearing", function () { it("animation", function () { spyOn(eventManager, 'fireEvent'); state.setFrames([1,2]); + state.setFrameDuration(1); expect(state.getImage()).toEqual('appear_1'); state.update(); expect(state.getImage()).toEqual('appear_2'); diff --git a/spec/TankStateInvincibleSpec.js b/spec/TankStateInvincibleSpec.js index f723eb8..7d780d0 100644 --- a/spec/TankStateInvincibleSpec.js +++ b/spec/TankStateInvincibleSpec.js @@ -7,25 +7,6 @@ describe("TankStateInvincible", function () { state = new TankStateInvincible(tank); }); - it("shield animation", function () { - state.setShieldFrameDuration(2); - expect(state.getShieldImage()).toEqual('shield_1'); - state.updateShieldFrame(); - expect(state.getShieldImage()).toEqual('shield_1'); - state.updateShieldFrame(); - expect(state.getShieldImage()).toEqual('shield_2'); - state.updateShieldFrame(); - expect(state.getShieldImage()).toEqual('shield_2'); - state.updateShieldFrame(); - expect(state.getShieldImage()).toEqual('shield_1'); - state.updateShieldFrame(); - expect(state.getShieldImage()).toEqual('shield_1'); - state.updateShieldFrame(); - expect(state.getShieldImage()).toEqual('shield_2'); - state.updateShieldFrame(); - expect(state.getShieldImage()).toEqual('shield_2'); - }); - it("state duration", function () { spyOn(eventManager, 'fireEvent'); state.setStateDuration(3); @@ -41,10 +22,8 @@ describe("TankStateInvincible", function () { }); it("#update", function () { - spyOn(state, 'updateShieldFrame'); spyOn(state, 'updateStateTimer'); state.update(); - expect(state.updateShieldFrame).toHaveBeenCalled(); expect(state.updateStateTimer).toHaveBeenCalled(); }); }); diff --git a/spec/TankStateNormalSpec.js b/spec/TankStateNormalSpec.js index 5a03589..4855a19 100644 --- a/spec/TankStateNormalSpec.js +++ b/spec/TankStateNormalSpec.js @@ -11,18 +11,18 @@ describe("TankStateNormal", function () { it("animate when tank is moving", function () { tank.setSpeed(1); expect(state.getTrackFrame()).toEqual(1); - state.updateTrackFrame(); + state.update(); expect(state.getTrackFrame()).toEqual(2); - state.updateTrackFrame(); + state.update(); expect(state.getTrackFrame()).toEqual(1); }); it("don't animate when tank is not moving", function () { tank.setSpeed(0); expect(state.getTrackFrame()).toEqual(1); - state.updateTrackFrame(); + state.update(); expect(state.getTrackFrame()).toEqual(1); - state.updateTrackFrame(); + state.update(); expect(state.getTrackFrame()).toEqual(1); }); }); @@ -30,22 +30,16 @@ describe("TankStateNormal", function () { describe("#getImage", function () { it("RIGHT", function () { tank.setDirection(Sprite.Direction.RIGHT); - state.setTrackFrame(1); expect(state.getImage()).toEqual('tank_player1_right_1'); }); it("LEFT", function () { + tank.toNormalSpeed(); tank.setDirection(Sprite.Direction.LEFT); - state.setTrackFrame(2); + state.update(); expect(state.getImage()).toEqual('tank_player1_left_2'); }); }); - it("#update", function () { - spyOn(state, 'updateTrackFrame'); - state.update(); - expect(state.updateTrackFrame).toHaveBeenCalled(); - }); - it("#canMove", function () { expect(state.canMove()).toBeTruthy(); }); diff --git a/src/Animation.js b/src/Animation.js index 862e66e..c104d41 100644 --- a/src/Animation.js +++ b/src/Animation.js @@ -1,10 +1,31 @@ -function Animation(frames) { +function Animation(frames, frameDuration, loop) { this._frames = frames; + this._frameDuration = frameDuration !== undefined ? frameDuration : 1; + this._loop = loop !== undefined ? loop : false; this._frame = 0; + this._timer = 0; + this._completed = false; } Animation.prototype.update = function () { - this._frame++; + if (this._completed) { + return; + } + + this._timer++; + if (this._timer >= this._frameDuration) { + this._timer = 0; + this._frame++; + if (this._frame >= this._frames.length) { + if (this._loop) { + this._frame = 0; + } + else { + this._frame = this._frames.length - 1; + this._completed = true; + } + } + } }; Animation.prototype.getFrame = function () { @@ -15,6 +36,10 @@ Animation.prototype.setFrames = function (frames) { this._frames = frames; }; +Animation.prototype.setFrameDuration = function (duration) { + this._frameDuration = duration; +}; + Animation.prototype.isCompleted = function () { - return this._frame >= this._frames.length; + return this._completed; }; diff --git a/src/Explosion.js b/src/Explosion.js index 1e40ade..cd498bc 100644 --- a/src/Explosion.js +++ b/src/Explosion.js @@ -1,37 +1,24 @@ function Explosion(eventManager) { Sprite.call(this, eventManager); - this._framesCount = 3; - this._frame = 1; + this._animation = new Animation([1,2,3]); } Explosion.subclass(Sprite); -Explosion.prototype.setFramesCount = function (count) { - this._framesCount = count; -}; - -Explosion.prototype.getFramesCount = function () { - return this._framesCount; -}; - -Explosion.prototype.setFrame = function (frame) { - this._frame = frame; -}; - -Explosion.prototype.getFrame = function () { - return this._frame; +Explosion.prototype.setFrames = function (frames) { + this._animation.setFrames(frames); }; Explosion.prototype.getImage = function () { - return 'explosion_' + this._frame; + return 'explosion_' + this._animation.getFrame(); }; Explosion.prototype.updateHook = function () { - this._frame++; - if (this._frame > this._framesCount) { - this._frame = this._framesCount; + if (this._animation.isCompleted()) { this.destroy(); + return; } + this._animation.update(); }; Explosion.prototype.draw = function (ctx) { diff --git a/src/TankStateAppearing.js b/src/TankStateAppearing.js index 96f8b5c..7fe74fe 100644 --- a/src/TankStateAppearing.js +++ b/src/TankStateAppearing.js @@ -1,7 +1,7 @@ function TankStateAppearing(tank) { this._tank = tank; this._eventManager = this._tank.getEventManager(); - this._animation = new Animation([1,1,1,2,2,2,3,3,3,4,4,4,3,3,3,2,2,2,1,1,1,2,2,2,3,3,3,4,4,4,3,3,3,2,2,2,1,1,1]); + this._animation = new Animation([1,2,3,4,3,2,1,2,3,4,3,2,1], 3); } TankStateAppearing.Event = {}; @@ -33,3 +33,7 @@ TankStateAppearing.prototype.canShoot = function () { TankStateAppearing.prototype.setFrames = function (frames) { this._animation.setFrames(frames); }; + +TankStateAppearing.prototype.setFrameDuration = function (duration) { + this._animation.setFrameDuration(duration); +}; diff --git a/src/TankStateInvincible.js b/src/TankStateInvincible.js index 7a79690..993befb 100644 --- a/src/TankStateInvincible.js +++ b/src/TankStateInvincible.js @@ -3,9 +3,7 @@ function TankStateInvincible(tank) { this._eventManager = this._tank.getEventManager(); - this._shieldFrame = 1; - this._shieldFrameDuration = 2; - this._shieldFrameTimer = 0; + this._shieldAnimation = new Animation([1,2], 2, true); this._stateDuration = 110; this._stateTimer = 0; @@ -18,7 +16,7 @@ TankStateInvincible.Event.END = 'TankStateInvincible.Event.END'; TankStateInvincible.prototype.update = function () { TankStateNormal.prototype.update.call(this); - this.updateShieldFrame(); + this._shieldAnimation.update(); this.updateStateTimer(); }; @@ -28,15 +26,7 @@ TankStateInvincible.prototype.draw = function (ctx) { }; TankStateInvincible.prototype.getShieldImage = function () { - return 'shield_' + this._shieldFrame; -}; - -TankStateInvincible.prototype.updateShieldFrame = function () { - this._shieldFrameTimer++; - if (this._shieldFrameTimer >= this._shieldFrameDuration) { - this._shieldFrameTimer = 0; - this._shieldFrame = this._shieldFrame == 1 ? 2 : 1; - } + return 'shield_' + this._shieldAnimation.getFrame(); }; TankStateInvincible.prototype.updateStateTimer = function () { @@ -51,5 +41,5 @@ TankStateInvincible.prototype.setStateDuration = function (duration) { }; TankStateInvincible.prototype.setShieldFrameDuration = function (duration) { - this._shieldFrameDuration = duration; + this._shieldAnimation.setFrameDuration(duration); }; diff --git a/src/TankStateNormal.js b/src/TankStateNormal.js index 9acac30..a8aff98 100644 --- a/src/TankStateNormal.js +++ b/src/TankStateNormal.js @@ -1,21 +1,17 @@ function TankStateNormal(tank) { this._tank = tank; - this._trackFrame = 1; + this._trackAnimation = new Animation([1,2], 1, true); } TankStateNormal.prototype.getImage = function () { - return 'tank_' + this._tank.getType() + '_' + this._tank.getDirection() + '_' + this._trackFrame; + return 'tank_' + this._tank.getType() + '_' + this._tank.getDirection() + '_' + this._trackAnimation.getFrame(); }; TankStateNormal.prototype.update = function () { - this.updateTrackFrame(); -}; - -TankStateNormal.prototype.updateTrackFrame = function () { if (this._tank.getSpeed() == 0) { return; } - this._trackFrame = this._trackFrame == 1 ? 2 : 1; + this._trackAnimation.update() }; TankStateNormal.prototype.draw = function (ctx) { @@ -31,9 +27,5 @@ TankStateNormal.prototype.canShoot = function () { }; TankStateNormal.prototype.getTrackFrame = function () { - return this._trackFrame; -}; - -TankStateNormal.prototype.setTrackFrame = function (frame) { - this._trackFrame = frame; + return this._trackAnimation.getFrame(); };