diff --git a/README.md b/README.md index ce4d5b282..3e800c73d 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,9 @@ Version 1.1.2 * New: Physics.Body now has a center property (issue 142, thanks MikeMnD) * New: Lots of fixes across Full Screen Mode support. Input now works, scaling restores properly, world scale is correct and anti-alias support added. * New: Added Group.cursor. This points to the first item added to a Group. You can move the cursor with Group.next() and Group.previous(). +* New: Added Tween.isTweening(object) to check if an object is currently being tweened or not (thanks mikehamil10) +* New: Added getMagnitude, setMagnitude, normalize and isZero methods to Point (thanks beeglebug) +* New: Group.callAll now supports nested functions and a context, making it really powerful! * Updated: Fixed a few final bugs in the Sprite body and bounds calculations, in turn this resolved the Tilemap collision issues in the 1.1 release. * Updated: Finished documentation for the Phaser.Button class. * Updated: Fixed the Invaders game sample and enhanced it. diff --git a/examples/games/breakout.js b/examples/games/breakout.js index 981681f77..6c4c6962f 100644 --- a/examples/games/breakout.js +++ b/examples/games/breakout.js @@ -164,7 +164,7 @@ function ballHitBrick (_ball, _brick) { ball.animations.stop(); // And bring the bricks back from the dead :) - bricks.callAll('revive', this); + bricks.callAll('revive'); } } diff --git a/examples/input/keyboard justpressed.js b/examples/input/keyboard justpressed.js index fd7226b2f..8eb6321e5 100644 --- a/examples/input/keyboard justpressed.js +++ b/examples/input/keyboard justpressed.js @@ -1,32 +1,72 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); -var phaser; - function preload() { game.load.image('phaser', 'assets/sprites/phaser-dude.png'); + game.load.image('bullet', 'assets/misc/bullet0.png'); } +var sprite; +var bullet; +var bullets; +var bulletTime = 0; + function create() { - game.stage.backgroundColor = '#736357'; + game.stage.backgroundColor = '#2d2d2d'; - phaser = game.add.sprite(300, 300, 'phaser'); + bullets = game.add.group(); + bullets.createMultiple(10, 'bullet'); + bullets.callAll('events.onOutOfBounds.add', 'events.onOutOfBounds', resetBullet, this); + + sprite = game.add.sprite(400, 550, 'phaser'); + + // Stop the following keys from propagating up to the browser + game.input.keyboard.addKeyCapture([ Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT, Phaser.Keyboard.SPACEBAR ]); } function update() { - if (game.input.keyboard.justPressed(Phaser.Keyboard.UP)) + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { - phaser.y--; + sprite.body.velocity.x = -200; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + sprite.body.velocity.x = 200; } - if (game.input.keyboard.justPressed(Phaser.Keyboard.DOWN)) + if (game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)) { - phaser.y++; + fireBullet(); } } + +function fireBullet () { + + if (game.time.now > bulletTime) + { + bullet = bullets.getFirstExists(false); + + if (bullet) + { + bullet.reset(sprite.x + 6, sprite.y - 8); + bullet.body.velocity.y = -300; + bulletTime = game.time.now + 250; + } + } + +} + +// Called if the bullet goes out of the screen +function resetBullet (bullet) { + bullet.kill(); +} + diff --git a/src/core/Group.js b/src/core/Group.js index 7f2c72118..dd77f5a98 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -524,7 +524,9 @@ Phaser.Group.prototype = { // 3 = Multiply // 4 = Divide - if (key.length == 1) + var len = key.length; + + if (len == 1) { if (operation == 0) { child[key[0]] = value; } else if (operation == 1) { child[key[0]] += value; } @@ -532,7 +534,7 @@ Phaser.Group.prototype = { else if (operation == 3) { child[key[0]] *= value; } else if (operation == 4) { child[key[0]] /= value; } } - else if (key.length == 2) + else if (len == 2) { if (operation == 0) { child[key[0]][key[1]] = value; } else if (operation == 1) { child[key[0]][key[1]] += value; } @@ -540,7 +542,7 @@ Phaser.Group.prototype = { else if (operation == 3) { child[key[0]][key[1]] *= value; } else if (operation == 4) { child[key[0]][key[1]] /= value; } } - else if (key.length == 3) + else if (len == 3) { if (operation == 0) { child[key[0]][key[1]][key[2]] = value; } else if (operation == 1) { child[key[0]][key[1]][key[2]] += value; } @@ -548,7 +550,7 @@ Phaser.Group.prototype = { else if (operation == 3) { child[key[0]][key[1]][key[2]] *= value; } else if (operation == 4) { child[key[0]][key[1]][key[2]] /= value; } } - else if (key.length == 4) + else if (len == 4) { if (operation == 0) { child[key[0]][key[1]][key[2]][key[3]] = value; } else if (operation == 1) { child[key[0]][key[1]][key[2]][key[3]] += value; } @@ -697,32 +699,119 @@ Phaser.Group.prototype = { }, + /** + * Calls a function on all of the children that have exists=true in this Group. + * + * @method Phaser.Group#callbackFromArray + * @param {object} child - The object to inspect. + * @param {array} callback - The array of function names. + * @param {number} length - The size of the array (pre-calculated in callAll). + * @protected + */ + callbackFromArray: function (child, callback, length) { + + // Kinda looks like a Christmas tree + + if (length == 1) + { + if (child[callback[0]]) + { + return child[callback[0]]; + } + } + else if (length == 2) + { + if (child[callback[0]][callback[1]]) + { + return child[callback[0]][callback[1]]; + } + } + else if (length == 3) + { + if (child[callback[0]][callback[1]][callback[2]]) + { + return child[callback[0]][callback[1]][callback[2]]; + } + } + else if (length == 4) + { + if (child[callback[0]][callback[1]][callback[2]][callback[3]]) + { + return child[callback[0]][callback[1]][callback[2]][callback[3]]; + } + } + else + { + if (child[callback]) + { + return child[callback]; + } + } + + return false; + + }, + /** * Calls a function on all of the children regardless if they are dead or alive (see callAllExists if you need control over that) - * After the callback parameter you can add as many extra parameters as you like, which will all be passed to the child. + * After the method parameter you can add as many extra parameters as you like, which will all be passed to the child. * * @method Phaser.Group#callAll - * @param {function} callback - The function that exists on the children that will be called. - * @param {...*} parameter - Additional parameters that will be passed to the callback. + * @param {string} method - A string containing the name of the function that will be called. The function must exist on the child. + * @param {string} [context=''] - A string containing the context under which the method will be executed. Leave to '' to default to the child. + * @param {...*} parameter - Additional parameters that will be passed to the method. */ - callAll: function (callback) { + callAll: function (method, context) { - var args = Array.prototype.splice.call(arguments, 1); + if (typeof method == 'undefined') + { + return; + } + + // Extract the method into an array + method = method.split('.'); + + var methodLength = method.length; + + if (typeof context == 'undefined') + { + context = null; + } + else + { + // Extract the context into an array + context = context.split('.'); + var contextLength = context.length; + } + + var args = Array.prototype.splice.call(arguments, 2); + var callback = null; if (this._container.children.length > 0 && this._container.first._iNext) { - var currentNode = this._container.first._iNext; + var child = this._container.first._iNext; do { - if (currentNode[callback]) + callback = this.callbackFromArray(child, method, methodLength); + + if (context && callback) { - currentNode[callback].apply(currentNode, args); + callbackContext = this.callbackFromArray(child, context, contextLength); + + if (callback) + { + callback.apply(callbackContext, args); + } + } + else if (callback) + { + callback.apply(child, args); } - currentNode = currentNode._iNext; + child = child._iNext; } - while (currentNode != this._container.last._iNext) + while (child != this._container.last._iNext) } diff --git a/src/gameobjects/BitmapText.js b/src/gameobjects/BitmapText.js index 8090d8f84..d9671e373 100644 --- a/src/gameobjects/BitmapText.js +++ b/src/gameobjects/BitmapText.js @@ -5,7 +5,10 @@ */ /** -* Creates a new BitmapText. +* Creates a new `BitmapText` object. BitmapText work by taking a texture file and an XML file that describes the font layout. +* On Windows you can use the free app BMFont: http://www.angelcode.com/products/bmfont/ +* On OS X we recommend Glyph Designer: http://www.71squared.com/en/glyphdesigner +* * @class Phaser.BitmapText * @constructor * @param {Phaser.Game} game - A reference to the currently running game. diff --git a/src/tween/TweenManager.js b/src/tween/TweenManager.js index cb340a944..3e94fe5ed 100644 --- a/src/tween/TweenManager.js +++ b/src/tween/TweenManager.js @@ -158,6 +158,21 @@ Phaser.TweenManager.prototype = { }, + /** + * Checks to see if a particular Sprite is currently being tweened. + * + * @method Phaser.TweenManager#isTweening + * @param {object} object - The object to check for tweens against. + * @returns {boolean} Returns true if the object is currently being tweened, false if not. + */ + isTweening: function(object) { + + return this._tweens.some(function(tween) { + return tween._object === object; + }); + + }, + /** * Pauses all currently running tweens. *