diff --git a/README.md b/README.md
index 84a35d9b..209c479e 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,8 @@ Change Log
Version 1.1.3 - in build
+* New: The object returned by Math.sinCosGenerator now contains a length property.
+* New: Phaser.BitmapData object. Can be used as a texture for a Sprite or Tiling Sprite. See the new examples and docs for details.
* New: RenderTexture.render now takes a Phaser.Group. Also added renderXY for when you don't want to make a new Point object.
* New: Implementing PluginManager.remove, added PluginManager.removeAll (thanks crazysam)
* New: Added scrollFactorX/scrollFactorY to TilemapLayers (thanks jcd-as)
diff --git a/build/config.php b/build/config.php
index f6d76bc4..bc765321 100644
--- a/build/config.php
+++ b/build/config.php
@@ -59,7 +59,6 @@
-
@@ -91,6 +90,7 @@
+
diff --git a/examples/tilemaps/sci fly.js b/examples/tilemaps/sci fly.js
index fb2ea411..76b599c1 100644
--- a/examples/tilemaps/sci fly.js
+++ b/examples/tilemaps/sci fly.js
@@ -52,6 +52,7 @@ function create() {
sprite = game.add.sprite(450, 80, 'phaser');
sprite.anchor.setTo(0.5, 0.5);
+ sprite.angle = 45;
game.camera.follow(sprite);
// game.camera.deadzone = new Phaser.Rectangle(160, 160, layer.renderWidth-320, layer.renderHeight-320);
@@ -111,7 +112,7 @@ function update() {
function render() {
- // game.debug.renderSpriteCorners(sprite);
+ game.debug.renderSpriteBounds(sprite);
// game.debug.renderSpriteInfo(sprite, 32, 32);
// game.debug.renderSpriteCoords(sprite, 32, 32);
diff --git a/examples/wip/bmd.js b/examples/wip/bmd.js
new file mode 100644
index 00000000..dda21b51
--- /dev/null
+++ b/examples/wip/bmd.js
@@ -0,0 +1,82 @@
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('atari1', 'assets/sprites/atari130xe.png');
+ game.load.image('coke', 'assets/sprites/cokecan.png');
+ game.load.image('mushroom', 'assets/sprites/mushroom2.png');
+ game.load.image('ball', 'assets/sprites/shinyball.png');
+
+}
+
+var bmd;
+
+function create() {
+
+ bmd = game.add.bitmapData('ball', 32, 64);
+
+ console.log(bmd);
+
+ // And apply it to 100 randomly positioned sprites
+ for (var i = 0; i < 100; i++)
+ {
+ game.add.sprite(game.world.randomX - 32, game.world.randomY - 64, bmd);
+ }
+
+ // Populate the wave with some data
+ waveData = game.math.sinCosGenerator(32, 8, 8, 2);
+
+}
+
+function update() {
+
+ bmd.clear();
+
+ updateWobblyBall();
+
+}
+
+// This creates a simple sine-wave effect running through our DynamicTexture.
+// This is then duplicated across all sprites using it, meaning we only have to calculate it once.
+
+var waveSize = 8;
+var wavePixelChunk = 2;
+var waveData;
+var waveDataCounter;
+
+function updateWobblyBall()
+{
+ var s = 0;
+ var copyRect = { x: 0, y: 0, w: wavePixelChunk, h: 32 };
+ var copyPoint = { x: 0, y: 0 };
+
+ for (var x = 0; x < 32; x += wavePixelChunk)
+ {
+ copyPoint.x = x;
+ copyPoint.y = waveSize + (waveSize / 2) + waveData.sin[s];
+
+ bmd.context.drawImage(game.cache.getImage('ball'), copyRect.x, copyRect.y, copyRect.w, copyRect.h, copyPoint.x, copyPoint.y, copyRect.w, copyRect.h);
+
+ copyRect.x += wavePixelChunk;
+
+ s++;
+ }
+
+ // Cycle through the wave data - this is what causes the image to "undulate"
+ game.math.shift(waveData.sin);
+
+ waveDataCounter++;
+
+ if (waveDataCounter == waveData.length)
+ {
+ waveDataCounter = 0;
+ }
+}
+
+
+function render() {
+
+ bmd.render();
+
+}
diff --git a/examples/wip/index.php b/examples/wip/index.php
index 5f7a6174..3db7c03a 100644
--- a/examples/wip/index.php
+++ b/examples/wip/index.php
@@ -77,7 +77,6 @@
phaser
-
+* @copyright 2013 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* Creates a new `BitmapData` object.
+*
+* @class Phaser.BitmapData
+* @constructor
+* @param {Phaser.Game} game - A reference to the currently running game.
+* @param {string} [key] - A key the BitmapData will use when added to the Phaser.Cache. If none is given a UUID is generated.
+* @param {number} [width=256] - The width of the BitmapData in pixels.
+* @param {number} [height=256] - The height of the BitmapData in pixels.
+*/
+Phaser.BitmapData = function (game, key, width, height) {
+
+ if (typeof key === 'undefined') { key = 'bitmapData' . game.rnd.uuid(); }
+ if (typeof width === 'undefined') { width = 256; }
+ if (typeof height === 'undefined') { height = 256; }
+
+ /**
+ * @property {Phaser.Game} game - A reference to the currently running game.
+ */
+ this.game = game;
+
+ /**
+ * @property {string} name - The name of the BitmapData.
+ */
+ this.name = key;
+
+ /**
+ * @property {number} width - The width of the BitmapData in pixels.
+ */
+ this.width = width;
+
+ /**
+ * @property {number} height - The height of the BitmapData in pixels.
+ */
+ this.height = height;
+
+ /**
+ * @property {HTMLCanvasElement} canvas - The canvas to which this BitmapData draws.
+ * @default
+ */
+ this.canvas = Phaser.Canvas.create(width, height);
+
+ /**
+ * @property {HTMLCanvasContextElement} context - The 2d context of the canvas.
+ * @default
+ */
+ this.context = this.canvas.getContext('2d');
+
+ /**
+ * @property {PIXI.BaseTexture} baseTexture - The PIXI.BaseTexture.
+ * @default
+ */
+ this.baseTexture = new PIXI.BaseTexture(this.canvas);
+
+ /**
+ * @property {PIXI.Texture} texture - The PIXI.Texture.
+ * @default
+ */
+ this.texture = new PIXI.Texture(this.baseTexture);
+
+ /**
+ * @property {Phaser.Frame} textureFrame - The Frame this BitmapData uses for rendering.
+ * @default
+ */
+ this.textureFrame = new Phaser.Frame(0, 0, 0, width, height, 'bitmapData', game.rnd.uuid());
+
+ /**
+ * @property {number} type - The const type of this object.
+ * @default
+ */
+ this.type = Phaser.BITMAPDATA;
+
+}
+
+Phaser.BitmapData.prototype = {
+
+ clear: function () {
+
+ this.context.clearRect(0, 0, this.width, this.height);
+
+ },
+
+ render: function () {
+
+ // Only needed if running in WebGL, otherwise this array will never get cleared down I don't think!
+ if (this.game.renderType == Phaser.WEBGL)
+ {
+ PIXI.texturesToUpdate.push(this.baseTexture);
+ }
+
+ }
+
+}
+
diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js
index 9f1fd101..c753018f 100644
--- a/src/gameobjects/GameObjectFactory.js
+++ b/src/gameobjects/GameObjectFactory.js
@@ -274,6 +274,23 @@ Phaser.GameObjectFactory.prototype = {
return texture;
+ },
+
+ /**
+ * A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites.
+ *
+ * @method Phaser.GameObjectFactory#bitmapData
+ * @param {string} [key] - A key the BitmapData will use when added to the Phaser.Cache. If none is given a UUID is generated.
+ * @param {number} [width=256] - The width of the BitmapData in pixels.
+ * @param {number} [height=256] - The height of the BitmapData in pixels.
+ * @return {Phaser.BitmapData} The newly created BitmapData object.
+ */
+ bitmapData: function (key, width, height) {
+
+ var bmd = new Phaser.BitmapData(this.game, key, width, height);
+
+ return this.game.cache.addBitmapData(bmd.name, bmd);
+
}
};
\ No newline at end of file
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index d95b03b2..30c324a1 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -15,7 +15,7 @@
* @param {Phaser.Game} game - A reference to the currently running game.
* @param {number} x - The x coordinate (in world space) to position the Sprite at.
* @param {number} y - The y coordinate (in world space) to position the Sprite at.
-* @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
*/
Phaser.Sprite = function (game, x, y, key, frame) {
@@ -89,7 +89,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.input = new Phaser.InputHandler(this);
/**
- * @property {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
+ * @property {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
*/
this.key = key;
@@ -104,6 +104,12 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.currentFrame = this.game.cache.getTextureFrame(key.name);
}
+ else if (key instanceof Phaser.BitmapData)
+ {
+ PIXI.Sprite.call(this, key.texture, key.textureFrame);
+
+ this.currentFrame = key.textureFrame;
+ }
else if (key instanceof PIXI.Texture)
{
PIXI.Sprite.call(this, key);
diff --git a/src/loader/Cache.js b/src/loader/Cache.js
index 90cb2af2..764666f5 100644
--- a/src/loader/Cache.js
+++ b/src/loader/Cache.js
@@ -62,6 +62,12 @@ Phaser.Cache = function (game) {
*/
this._tilesets = {};
+ /**
+ * @property {object} _bitmapDatas - BitmapData key-value container.
+ * @private
+ */
+ this._bitmapDatas = {};
+
this.addDefaultImage();
/**
@@ -86,12 +92,27 @@ Phaser.Cache.prototype = {
},
+ /**
+ * Add a BitmapData object in to the cache.
+ * @method Phaser.Cache#addBitmapData
+ * @param {string} key - Asset key for this BitmapData.
+ * @param {Phaser.BitmapData} bitmapData - The BitmapData object to be addded to the cache.
+ * @return {Phaser.BitmapData} The BitmapData object to be addded to the cache.
+ */
+ addBitmapData: function (key, bitmapData) {
+
+ this._bitmapDatas[key] = bitmapData;
+
+ return bitmapData;
+
+ },
+
/**
* Add a new Phaser.RenderTexture in to the cache.
*
* @method Phaser.Cache#addRenderTexture
* @param {string} key - The unique key by which you will reference this object.
- * @param {Phaser.Texture} textue - The texture to use as the base of the RenderTexture.
+ * @param {Phaser.Texture} texture - The texture to use as the base of the RenderTexture.
*/
addRenderTexture: function (key, texture) {
@@ -364,7 +385,7 @@ Phaser.Cache.prototype = {
},
/**
- * Get acanvas object from the cache by its key.
+ * Get a canvas object from the cache by its key.
*
* @method Phaser.Cache#getCanvas
* @param {string} key - Asset key of the canvas you want.
@@ -378,6 +399,25 @@ Phaser.Cache.prototype = {
}
return null;
+
+ },
+
+ /**
+ * Get a BitmapData object from the cache by its key.
+ *
+ * @method Phaser.Cache#getBitmapData
+ * @param {string} key - Asset key of the BitmapData object you want.
+ * @return {Phaser.BitmapData} The requested BitmapData object if found, or null if not.
+ */
+ getBitmapData: function (key) {
+
+ if (this._bitmapDatas[key])
+ {
+ return this._bitmapDatas[key];
+ }
+
+ return null;
+
},
/**
@@ -413,6 +453,7 @@ Phaser.Cache.prototype = {
}
return null;
+
},
/**
diff --git a/src/math/Math.js b/src/math/Math.js
index 086d622d..45e3cb10 100644
--- a/src/math/Math.js
+++ b/src/math/Math.js
@@ -938,7 +938,7 @@ Phaser.Math = {
}
- return { sin: sinTable, cos: cosTable };
+ return { sin: sinTable, cos: cosTable, length: length };
},
diff --git a/src/tilemap/TilemapLayer.js b/src/tilemap/TilemapLayer.js
index 6a5c6747..1d6b014b 100644
--- a/src/tilemap/TilemapLayer.js
+++ b/src/tilemap/TilemapLayer.js
@@ -249,52 +249,75 @@ Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) {
* @param {number} x - x coordinate in camera space
* @return {number} x coordinate in scrollFactor-adjusted dimensions
*/
-Phaser.TilemapLayer.prototype._fixX = function( x )
-{
- if( this.scrollFactorX === 1 )
- return x;
+Phaser.TilemapLayer.prototype._fixX = function(x) {
+
+ if (this.scrollFactorX === 1)
+ {
+ return x;
+ }
+
var left_edge = x - (this._x / this.scrollFactorX);
+
return this._x + left_edge;
-};
+
+}
+
/**
* Take an x coordinate that _does_ account for scrollFactorY and 'unfix' it
* back to camera space. Used primarily internally
* @param {number} x - x coordinate in scrollFactor-adjusted dimensions
* @return {number} x coordinate in camera space
*/
-Phaser.TilemapLayer.prototype._unfixX = function( x )
-{
- if( this.scrollFactorX === 1 )
- return x;
+Phaser.TilemapLayer.prototype._unfixX = function(x) {
+
+ if (this.scrollFactorX === 1)
+ {
+ return x;
+ }
+
var left_edge = x - this._x;
+
return (this._x / this.scrollFactorX) + left_edge;
-};
+
+}
+
/**
* Take a y coordinate that doesn't account for scrollFactorY and 'fix' it
* into a scrolled local space. Used primarily internally
* @param {number} y - y coordinate in camera space
* @return {number} y coordinate in scrollFactor-adjusted dimensions
*/
-Phaser.TilemapLayer.prototype._fixY = function( y )
-{
- if( this.scrollFactorY === 1 )
- return y;
+Phaser.TilemapLayer.prototype._fixY = function(y) {
+
+ if (this.scrollFactorY === 1)
+ {
+ return y;
+ }
+
var top_edge = y - (this._y / this.scrollFactorY);
+
return this._y + top_edge;
-};
+
+}
+
/**
* Take a y coordinate that _does_ account for scrollFactorY and 'unfix' it
* back to camera space. Used primarily internally
* @param {number} y - y coordinate in scrollFactor-adjusted dimensions
* @return {number} y coordinate in camera space
*/
-Phaser.TilemapLayer.prototype._unfixY = function( y )
-{
- if( this.scrollFactorY === 1 )
- return y;
+Phaser.TilemapLayer.prototype._unfixY = function(y) {
+
+ if (this.scrollFactorY === 1)
+ {
+ return y;
+ }
+
var top_edge = y - this._y;
+
return (this._y / this.scrollFactorY) + top_edge;
-};
+
+}
/**
* Convert a pixel value to a tile coordinate.