Animation.looped has been renamed to Animation.loop. It's a boolean you can toggle at run-time to turn on/off animation looping.

A single Animation object now has 3 new events: onStart, onLoop and onComplete.
Animation.loopCount holds the number of times the animation has looped since it last started.
Animation.stop has a new parameter: dispatchComplete. If true it'll dispatch an Animation.onComplete event.
This commit is contained in:
photonstorm
2014-03-03 16:05:55 +00:00
parent 4a370c82cf
commit 833960b3c8
9 changed files with 292 additions and 24 deletions
+4 -1
View File
@@ -85,6 +85,7 @@ Significant API changes:
* Game no longer pauses if you've forced orientation and change it, also doesn't resize a NO_SCALE game.
* All the Debug methods have had the word 'render' removed from the start. So where you did `debug.renderSpriteInfo` before, it's now just `debug.spriteInfo`.
* Debug methods that rendered geometry (Rectangle, Circle, Line, Point) have been merged into the single method: `Debug.geom`.
* Animation.looped has been renamed to Animation.loop. It's a boolean you can toggle at run-time to turn on/off animation looping.
New features:
@@ -136,7 +137,8 @@ New features:
* Device.windowsPhone is now tested for.
* The Debug panel now works in WebGL mode. Pay attention to the warning at the top of the Debug docs (feature request #499)
* You can now create blank Tilemaps and then populate them with data later.
* A single Animation object now has 3 new events: onStart, onLoop and onComplete.
* Animation.loopCount holds the number of times the animation has looped since it last started.
Updates:
@@ -163,6 +165,7 @@ Updates:
* Tween no longer copies all the object properties into the `_valuesStart` object on creation.
* Completely empty Tilemaps can now be created. This allows for dynamic map generation at runtime.
* Keyboard.event now stores the most recent DOM keyboard event.
* Animation.stop has a new parameter: dispatchComplete. If true it'll dispatch an Animation.onComplete event.
Bug Fixes:
+69
View File
@@ -0,0 +1,69 @@
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update });
function preload() {
game.load.image('lazur', 'assets/pics/thorn_lazur.png');
game.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', 37, 45, 18);
}
var back;
var mummy;
var anim;
var loopText;
function create() {
game.stage.smoothed = false;
back = game.add.image(0, -400, 'lazur');
back.scale.set(2);
mummy = game.add.sprite(200, 360, 'mummy', 5);
mummy.scale.set(4);
anim = mummy.animations.add('walk');
anim.onStart.add(animationStarted, this);
anim.onLoop.add(animationLooped, this);
anim.onComplete.add(animationStopped, this);
anim.play(10, true);
}
function animationStarted(sprite, animation) {
game.add.text(32, 32, 'Animation started', { fill: 'white' });
}
function animationLooped(sprite, animation) {
if (animation.loopCount === 1)
{
loopText = game.add.text(32, 64, 'Animation looped', { fill: 'white' });
}
else
{
loopText.text = 'Animation looped x2';
animation.loop = false;
}
}
function animationStopped(sprite, animation) {
game.add.text(32, 64+32, 'Animation stopped', { fill: 'white' });
}
function update() {
if (anim.isPlaying)
{
back.x -= 1;
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

+2 -3
View File
@@ -42,9 +42,7 @@ function update() {
// This creates a simple sine-wave effect running through our BitmapData.
// This is then duplicated across all 100 sprites using it, meaning we only have to calculate it and upload it to the GPU once.
function updateWobblyBall()
{
function updateWobblyBall() {
var s = 0;
var copyRect = { x: 0, y: 0, w: wavePixelChunk, h: 32 };
@@ -76,4 +74,5 @@ function updateWobblyBall()
{
waveDataCounter = 0;
}
}
+69
View File
@@ -0,0 +1,69 @@
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update });
function preload() {
game.load.image('lazur', 'assets/pics/thorn_lazur.png');
game.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', 37, 45, 18);
}
var back;
var mummy;
var anim;
var loopText;
function create() {
game.stage.smoothed = false;
back = game.add.image(0, -400, 'lazur');
back.scale.set(2);
mummy = game.add.sprite(200, 360, 'mummy', 5);
mummy.scale.set(4);
anim = mummy.animations.add('walk');
anim.onStart.add(animationStarted, this);
anim.onLoop.add(animationLooped, this);
anim.onComplete.add(animationStopped, this);
anim.play(10, true);
}
function animationStarted(sprite, animation) {
game.add.text(32, 32, 'Animation started', { fill: 'white' });
}
function animationLooped(sprite, animation) {
if (animation.loopCount === 1)
{
loopText = game.add.text(32, 64, 'Animation looped', { fill: 'white' });
}
else
{
loopText.text = 'Animation looped x2';
animation.loop = false;
}
}
function animationStopped(sprite, animation) {
game.add.text(32, 64+32, 'Animation stopped', { fill: 'white' });
}
function update() {
if (anim.isPlaying)
{
back.x -= 1;
}
}
+89
View File
@@ -0,0 +1,89 @@
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
// var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.tilemap('map', 'assets/tilemaps/maps/collision_test.json', null, Phaser.Tilemap.TILED_JSON);
game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png');
game.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png');
game.load.image('tiles2', 'assets/tilemaps/tiles/tiles2.png');
game.load.image('player', 'assets/sprites/phaser-dude.png');
game.load.image('box', 'assets/sprites/ufo.png');
game.load.image('ship', 'assets/sprites/thrust_ship2.png');
}
var ship;
var map;
var tileset;
var layer;
var p;
var b;
var cursors;
var box2;
var dump;
function create() {
game.renderer.roundPixels = true;
// game.stage.backgroundColor = '#787878';
map = game.add.tilemap('map');
map.addTilesetImage('ground_1x1');
map.addTilesetImage('walls_1x2');
map.addTilesetImage('tiles2');
layer = map.createLayer('Tile Layer 1');
layer.resizeWorld();
map.setCollisionBetween(1, 12);
layer.debug = true;
// dump = map.generateCollisionData(layer);
box2 = game.add.sprite(200, 200, 'box');
box2.physicsEnabled = true;
box2.body.fixedRotation = true;
game.camera.follow(box2);
cursors = game.input.keyboard.createCursorKeys();
}
function update() {
if (cursors.left.isDown)
{
box2.body.moveLeft(200);
}
else if (cursors.right.isDown)
{
box2.body.moveRight(200);
}
else
{
box2.body.setZeroVelocity();
}
if (cursors.up.isDown)
{
box2.body.moveUp(200);
}
else if (cursors.down.isDown)
{
box2.body.moveDown(200);
}
}
function render() {
}
+58 -19
View File
@@ -16,9 +16,9 @@
* @param {Phaser.FrameData} frameData - The FrameData object that contains all frames used by this Animation.
* @param {(Array.<number>|Array.<string>)} frames - An array of numbers or strings indicating which frames to play in which order.
* @param {number} delay - The time between each frame of the animation, given in ms.
* @param {boolean} looped - Should this animation loop or play through once.
* @param {boolean} loop - Should this animation loop when it reaches the end or play through once.
*/
Phaser.Animation = function (game, parent, name, frameData, frames, delay, looped) {
Phaser.Animation = function (game, parent, name, frameData, frames, delay, loop) {
/**
* @property {Phaser.Game} game - A reference to the currently running Game.
@@ -55,9 +55,14 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope
this.delay = 1000 / delay;
/**
* @property {boolean} looped - The loop state of the Animation.
* @property {boolean} loop - The loop state of the Animation.
*/
this.looped = looped;
this.loop = loop;
/**
* @property {number} loopCount - The number of times the animation has looped since it was last started.
*/
this.loopCount = 0;
/**
* @property {boolean} killOnComplete - Should the parent of this Animation be killed when the animation completes?
@@ -116,9 +121,26 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope
*/
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
/**
* @property {Phaser.Signal} onStart - This event is dispatched when this Animation starts playback.
*/
this.onStart = new Phaser.Signal();
/**
* @property {Phaser.Signal} onComplete - This event is dispatched when this Animation completes playback. If the animation is set to loop this is never fired, listen for onAnimationLoop instead.
*/
this.onComplete = new Phaser.Signal();
/**
* @property {Phaser.Signal} onLoop - This event is dispatched when this Animation loops.
*/
this.onLoop = new Phaser.Signal();
// Set-up some event listeners
this.game.onPause.add(this.onPause, this);
this.game.onResume.add(this.onResume, this);
console.log('animation created', this);
};
@@ -145,7 +167,7 @@ Phaser.Animation.prototype = {
if (typeof loop === 'boolean')
{
// If they set a new loop value then use it, otherwise use the one set on creation
this.looped = loop;
this.loop = loop;
}
if (typeof killOnComplete !== 'undefined')
@@ -157,6 +179,7 @@ Phaser.Animation.prototype = {
this.isPlaying = true;
this.isFinished = false;
this.paused = false;
this.loopCount = 0;
this._timeLastFrame = this.game.time.now;
this._timeNextFrame = this.game.time.now + this.delay;
@@ -173,10 +196,8 @@ Phaser.Animation.prototype = {
this._parent.tilingTexture = false;
}
if (this._parent.events)
{
this._parent.events.onAnimationStart.dispatch(this._parent, this);
}
this._parent.events.onAnimationStart.dispatch(this._parent, this);
this.onStart.dispatch(this._parent, this);
return this;
@@ -193,6 +214,7 @@ Phaser.Animation.prototype = {
this.isPlaying = true;
this.isFinished = false;
this.paused = false;
this.loopCount = 0;
this._timeLastFrame = this.game.time.now;
this._timeNextFrame = this.game.time.now + this.delay;
@@ -201,18 +223,23 @@ Phaser.Animation.prototype = {
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
this.onStart.dispatch(this._parent, this);
},
/**
* Stops playback of this animation and set it to a finished state. If a resetFrame is provided it will stop playback and set frame to the first in the animation.
* If `dispatchComplete` is true it will dispatch the complete events, otherwise they'll be ignored.
*
* @method Phaser.Animation#stop
* @memberof Phaser.Animation
* @param {boolean} [resetFrame=false] - If true after the animation stops the currentFrame value will be set to the first frame in this animation.
* @param {boolean} [dispatchComplete=false] - Dispatch the Animation.onComplete and parent.onAnimationComplete events?
*/
stop: function (resetFrame) {
stop: function (resetFrame, dispatchComplete) {
if (typeof resetFrame === 'undefined') { resetFrame = false; }
if (typeof dispatchComplete === 'undefined') { dispatchComplete = false; }
this.isPlaying = false;
this.isFinished = true;
@@ -223,6 +250,12 @@ Phaser.Animation.prototype = {
this.currentFrame = this._frameData.getFrame(this._frames[0]);
}
if (dispatchComplete)
{
this._parent.events.onAnimationComplete.dispatch(this._parent, this);
this.onComplete.dispatch(this._parent, this);
}
},
/**
@@ -292,7 +325,7 @@ Phaser.Animation.prototype = {
if (this._frameIndex >= this._frames.length)
{
if (this.looped)
if (this.loop)
{
this._frameIndex %= this._frames.length;
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
@@ -308,11 +341,13 @@ Phaser.Animation.prototype = {
}
}
this.loopCount++;
this._parent.events.onAnimationLoop.dispatch(this._parent, this);
this.onLoop.dispatch(this._parent, this);
}
else
{
this.onComplete();
this.complete();
}
}
else
@@ -353,27 +388,31 @@ Phaser.Animation.prototype = {
this.currentFrame = null;
this.isPlaying = false;
this.onStart.destroy();
this.onLoop.destroy();
this.onComplete.destroy();
this.game.onPause.remove(this.onPause, this);
this.game.onResume.remove(this.onResume, this);
},
/**
* Called internally when the animation finishes playback. Sets the isPlaying and isFinished states and dispatches the onAnimationComplete event if it exists on the parent.
* Called internally when the animation finishes playback.
* Sets the isPlaying and isFinished states and dispatches the onAnimationComplete event if it exists on the parent and local onComplete event.
*
* @method Phaser.Animation#onComplete
* @method Phaser.Animation#complete
* @memberof Phaser.Animation
*/
onComplete: function () {
complete: function () {
this.isPlaying = false;
this.isFinished = true;
this.paused = false;
if (this._parent.events)
{
this._parent.events.onAnimationComplete.dispatch(this._parent, this);
}
this._parent.events.onAnimationComplete.dispatch(this._parent, this);
this.onComplete.dispatch(this._parent, this);
if (this.killOnComplete)
{
+1 -1
View File
@@ -11,7 +11,7 @@
*
* For example to tell when a Sprite has been added to a new group:
*
* ```sprite.events.onAddedToGroup.add(yourFunction, this);```
* `sprite.events.onAddedToGroup.add(yourFunction, this);`
*
* Where `yourFunction` is the function you want called when this event occurs.
*