Loader.physics now lets you load Lime + Corona JSON Physics data, which can be used with Body.loadPolygon and Body.loadData.

Cache.addPhysicsData and Cache.getPhysicsData allow you to store parsed JSON physics data in the cache, for sharing between Bodies.
This commit is contained in:
photonstorm 2014-02-14 23:51:49 +00:00
parent b94c78cf61
commit e5a4620b87
6 changed files with 365 additions and 105 deletions

View file

@ -87,6 +87,7 @@ Significant API changes:
* BitmapData has had all of the EaselJS functions removed. It was just taking up space and you can do it all via BitmapData.context directly.
* BitmapText has had a bit of an overhaul - the signature for adding a BitmapText has changed to: x, y, font, text, size. See the docs and examples for details.
* World preUpdate, update and postUpdate have all been moved to Stage. So all children are updated regardless where on the display list they live.
* Cache.getImageKeys and similar has been removed, please use Cache.getKeys(Phaser.Cache.IMAGE) instead, this now supports all 10 Cache data types.
New features:
@ -112,6 +113,8 @@ New features:
* Loader.bitmapFont now has 2 extra parameters: xSpacing and ySpacing. These allow you to add extra spacing to each letter or line of the font.
* Added the new BitmapFont class. This is for rendering retro style fixed-width bitmap fonts into an Image object. It's a texture you can apply to a Sprite/Image.
* Added Cache.updateFrameData which is really useful for swapping FrameData blocks in the cache.
* Loader.physics now lets you load Lime + Corona JSON Physics data, which can be used with Body.loadPolygon and Body.loadData.
* Cache.addPhysicsData and Cache.getPhysicsData allow you to store parsed JSON physics data in the cache, for sharing between Bodies.
Updates:

View file

@ -3,8 +3,8 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload:
function preload() {
// game.load.image('box', 'assets/sprites/block.png');
game.load.image('box', 'assets/sprites/diamond.png');
game.load.physics('physobjects', 'assets/physics/diamond.json');
}
@ -24,8 +24,14 @@ function create() {
box.physicsEnabled = true;
box.body.clearShapes();
box.body.loadPolygon('physobjects', 'diamond');
box.body.rotateLeft(20);
// console.log(game.cache.getPhysicsData('physobjects', 'diamond'));
// 95x95
// box.body.setRectangle(64, 64);
@ -41,7 +47,9 @@ function create() {
// Works
// box.body.addPolygon({}, -100, 100, -100, 0, 100, 0, 100, 100, 50, 50);
box.body.addPolygon({}, 32, 13 , 17, 28 , 15, 28 , 0, 13 , 0, 7 , 7, 0 , 25, 0 , 32, 7 );
// box.body.addPolygon({}, -100, 100, -100, 0, 100, 0, 100, 100, 50, 50 );
// box.body.addPolygon({}, 32, 13 , 17, 28 , 15, 28 , 0, 13 , 0, 7 , 7, 0 , 25, 0 , 32, 7 );
// Works
// box.body.setPolygon({}, -1, 1, -1, 0, 1, 0, 1, 1, 0.5, 0.5);

View file

@ -49,6 +49,12 @@ Phaser.Cache = function (game) {
*/
this._text = {};
/**
* @property {object} _physics - Physics data key-value container.
* @private
*/
this._physics = {};
/**
* @property {object} _tilemaps - Tilemap key-value container.
* @private
@ -83,10 +89,71 @@ Phaser.Cache = function (game) {
};
/**
* @constant
* @type {number}
*/
Phaser.Cache.CANVAS = 1;
/**
* @constant
* @type {number}
*/
Phaser.Cache.IMAGE = 2;
/**
* @constant
* @type {number}
*/
Phaser.Cache.TEXTURE = 3;
/**
* @constant
* @type {number}
*/
Phaser.Cache.SOUND = 4;
/**
* @constant
* @type {number}
*/
Phaser.Cache.TEXT = 5;
/**
* @constant
* @type {number}
*/
Phaser.Cache.PHYSICS = 6;
/**
* @constant
* @type {number}
*/
Phaser.Cache.TILEMAP = 7;
/**
* @constant
* @type {number}
*/
Phaser.Cache.BINARY = 8;
/**
* @constant
* @type {number}
*/
Phaser.Cache.BITMAPDATA = 9;
/**
* @constant
* @type {number}
*/
Phaser.Cache.BITMAPFONT = 10;
Phaser.Cache.prototype = {
/**
* Add a new canvas object in to the cache.
*
* @method Phaser.Cache#addCanvas
* @param {string} key - Asset key for this canvas.
* @param {HTMLCanvasElement} canvas - Canvas DOM element.
@ -100,6 +167,7 @@ Phaser.Cache.prototype = {
/**
* Add a binary object in to the cache.
*
* @method Phaser.Cache#addBinary
* @param {string} key - Asset key for this binary data.
* @param {object} binaryData - The binary object to be addded to the cache.
@ -112,6 +180,7 @@ 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.
@ -178,7 +247,7 @@ Phaser.Cache.prototype = {
},
/**
* Add a new tilemap.
* Add a new tilemap to the Cache.
*
* @method Phaser.Cache#addTilemap
* @param {string} key - The unique key by which you will reference this object.
@ -193,7 +262,7 @@ Phaser.Cache.prototype = {
},
/**
* Add a new texture atlas.
* Add a new texture atlas to the Cache.
*
* @method Phaser.Cache#addTextureAtlas
* @param {string} key - The unique key by which you will reference this object.
@ -225,7 +294,7 @@ Phaser.Cache.prototype = {
},
/**
* Add a new Bitmap Font.
* Add a new Bitmap Font to the Cache.
*
* @method Phaser.Cache#addBitmapFont
* @param {string} key - The unique key by which you will reference this object.
@ -246,10 +315,26 @@ Phaser.Cache.prototype = {
},
/**
* Add a new physics data object to the Cache.
*
* @method Phaser.Cache#addTilemap
* @param {string} key - The unique key by which you will reference this object.
* @param {string} url - URL of the physics json data.
* @param {object} JSONData - The physics data object (a JSON file).
* @param {number} format - The format of the physics data.
*/
addPhysicsData: function (key, url, JSONData, format) {
this._physics[key] = { url: url, data: JSONData, format: format };
},
/**
* Adds a default image to be used in special cases such as WebGL Filters. Is mapped to the key __default.
*
* @method Phaser.Cache#addDefaultImage
* @protected
*/
addDefaultImage: function () {
@ -268,6 +353,7 @@ Phaser.Cache.prototype = {
* Adds an image to be used when a key is wrong / missing. Is mapped to the key __missing.
*
* @method Phaser.Cache#addMissingImage
* @protected
*/
addMissingImage: function () {
@ -292,10 +378,7 @@ Phaser.Cache.prototype = {
*/
addText: function (key, url, data) {
this._text[key] = {
url: url,
data: data
};
this._text[key] = { url: url, data: data };
},
@ -318,23 +401,6 @@ Phaser.Cache.prototype = {
},
/**
* Replaces a set of frameData with a new Phaser.FrameData object.
*
* @method Phaser.Cache#updateFrameData
* @param {string} key - The unique key by which you will reference this object.
* @param {number} frameData - The new FrameData.
*/
updateFrameData: function (key, frameData) {
if (this._images[key])
{
this._images[key].spriteSheet = true;
this._images[key].frameData = frameData;
}
},
/**
* Add a new sound.
*
@ -489,6 +555,44 @@ Phaser.Cache.prototype = {
},
/**
* Get a physics data object from the cache by its key. You can get either the entire data set or just a single object from it.
*
* @method Phaser.Cache#getPhysicsData
* @param {string} key - Asset key of the physics data object to retrieve from the Cache.
* @param {string} [object=null] - If specified it will return just the physics object that is part of the given key, if null it will return them all.
* @return {object} The requested physics object data if found.
*/
getPhysicsData: function (key, object) {
if (typeof object === 'undefined' || object === null)
{
// Get 'em all
if (this._physics[key])
{
return this._physics[key].data;
}
else
{
console.warn('Phaser.Cache.getPhysicsData: Invalid key: "' + key + '"');
}
}
else
{
if (this._physics[key] && this._physics[key].data[object])
{
return this._physics[key].data[object][0];
}
else
{
console.warn('Phaser.Cache.getPhysicsData: Invalid key/object: "' + key + ' / ' + object + '"');
}
}
return null;
},
/**
* Checks if an image key exists.
*
@ -564,6 +668,23 @@ Phaser.Cache.prototype = {
return null;
},
/**
* Replaces a set of frameData with a new Phaser.FrameData object.
*
* @method Phaser.Cache#updateFrameData
* @param {string} key - The unique key by which you will reference this object.
* @param {number} frameData - The new FrameData.
*/
updateFrameData: function (key, frameData) {
if (this._images[key])
{
this._images[key].spriteSheet = true;
this._images[key].frameData = frameData;
}
},
/**
* Get a single frame out of a frameData set by key.
*
@ -780,14 +901,63 @@ Phaser.Cache.prototype = {
},
/**
* Get the cache keys from a given array of objects.
* Normally you don't call this directly but instead use getImageKeys, getSoundKeys, etc.
* Gets all keys used by the Cache for the given data type.
*
* @method Phaser.Cache#getKeys
* @param {Array} array - An array of items to return the keys for.
* @param {number} [type=Phaser.Cache.IMAGE] - The type of Cache keys you wish to get. Can be Cache.CANVAS, Cache.IMAGE, Cache.SOUND, etc.
* @return {Array} The array of item keys.
*/
getKeys: function (array) {
getKeys: function (type) {
var array = null;
switch (type)
{
case Phaser.Cache.CANVAS:
array = this._canvases;
break;
case Phaser.Cache.IMAGE:
array = this._images;
break;
case Phaser.Cache.TEXTURE:
array = this._textures;
break;
case Phaser.Cache.SOUND:
array = this._sounds;
break;
case Phaser.Cache.TEXT:
array = this._text;
break;
case Phaser.Cache.PHYSICS:
array = this._physics;
break;
case Phaser.Cache.TILEMAP:
array = this._tilemaps;
break;
case Phaser.Cache.BINARY:
array = this._binary;
break;
case Phaser.Cache.BITMAPDATA:
array = this._bitmapDatas;
break;
case Phaser.Cache.BITMAPFONT:
array = this._bitmapFont;
break;
}
if (!array)
{
return;
}
var output = [];
@ -803,36 +973,6 @@ Phaser.Cache.prototype = {
},
/**
* Returns an array containing all of the keys of Images in the Cache.
*
* @method Phaser.Cache#getImageKeys
* @return {Array} The string based keys in the Cache.
*/
getImageKeys: function () {
return this.getKeys(this._images);
},
/**
* Returns an array containing all of the keys of Sounds in the Cache.
*
* @method Phaser.Cache#getSoundKeys
* @return {Array} The string based keys in the Cache.
*/
getSoundKeys: function () {
return this.getKeys(this._sounds);
},
/**
* Returns an array containing all of the keys of Text Files in the Cache.
*
* @method Phaser.Cache#getTextKeys
* @return {Array} The string based keys in the Cache.
*/
getTextKeys: function () {
return this.getKeys(this._text);
},
/**
* Removes a canvas from the cache.
*
@ -873,6 +1013,56 @@ Phaser.Cache.prototype = {
delete this._text[key];
},
/**
* Removes a physics data file from the cache.
*
* @method Phaser.Cache#removePhysics
* @param {string} key - Key of the asset you want to remove.
*/
removePhysics: function (key) {
delete this._text[key];
},
/**
* Removes a tilemap from the cache.
*
* @method Phaser.Cache#removeTilemap
* @param {string} key - Key of the asset you want to remove.
*/
removeTilemap: function (key) {
delete this._text[key];
},
/**
* Removes a binary file from the cache.
*
* @method Phaser.Cache#removeBinary
* @param {string} key - Key of the asset you want to remove.
*/
removeBinary: function (key) {
delete this._text[key];
},
/**
* Removes a bitmap data from the cache.
*
* @method Phaser.Cache#removeBitmapData
* @param {string} key - Key of the asset you want to remove.
*/
removeBitmapData: function (key) {
delete this._text[key];
},
/**
* Removes a bitmap font from the cache.
*
* @method Phaser.Cache#removeBitmapFont
* @param {string} key - Key of the asset you want to remove.
*/
removeBitmapFont: function (key) {
delete this._text[key];
},
/**
* Clears the cache. Removes every local cache object reference.
*
@ -899,6 +1089,37 @@ Phaser.Cache.prototype = {
{
delete this._text[item['key']];
}
for (var item in this._textures)
{
delete this._textures[item['key']];
}
for (var item in this._physics)
{
delete this._physics[item['key']];
}
for (var item in this._tilemaps)
{
delete this._tilemaps[item['key']];
}
for (var item in this._binary)
{
delete this._binary[item['key']];
}
for (var item in this._bitmapDatas)
{
delete this._bitmapDatas[item['key']];
}
for (var item in this._bitmapFont)
{
delete this._bitmapFont[item['key']];
}
}
};

View file

@ -133,6 +133,12 @@ Phaser.Loader.TEXTURE_ATLAS_JSON_HASH = 1;
*/
Phaser.Loader.TEXTURE_ATLAS_XML_STARLING = 2;
/**
* @constant
* @type {number}
*/
Phaser.Loader.PHYSICS_LIME_CORONA = 3;
Phaser.Loader.prototype = {
/**
@ -489,6 +495,49 @@ Phaser.Loader.prototype = {
},
/**
* Add a new physics data object loading request.
* The data must be in Lime + Corona JSON format. Physics Editor by code'n'web exports in this format natively.
*
* @method Phaser.Loader#physics
* @param {string} key - Unique asset key of the physics json data.
* @param {string} [dataURL] - The url of the map data file (csv/json)
* @param {object} [jsonData] - An optional JSON data object. If given then the dataURL is ignored and this JSON object is used for physics data instead.
* @param {string} [format=Phaser.Physics.LIME_CORONA_JSON] - The format of the physics data.
* @return {Phaser.Loader} This Loader instance.
*/
physics: function (key, dataURL, jsonData, format) {
if (typeof dataURL === "undefined") { dataURL = null; }
if (typeof jsonData === "undefined") { jsonData = null; }
if (typeof format === "undefined") { format = Phaser.Physics.LIME_CORONA_JSON; }
if (dataURL == null && jsonData == null)
{
console.warn('Phaser.Loader.physics - Both dataURL and jsonData are null. One must be set.');
return this;
}
// A map data object has been given
if (jsonData)
{
if (typeof jsonData === 'string')
{
jsonData = JSON.parse(jsonData);
}
this.game.cache.addPhysicsData(key, null, jsonData, format);
}
else
{
this.addToFileList('physics', key, dataURL, { format: format });
}
return this;
},
/**
* Add a new bitmap font loading request.
*
@ -863,6 +912,7 @@ Phaser.Loader.prototype = {
case 'text':
case 'script':
case 'physics':
this._xhr.open("GET", this.baseURL + file.url, true);
this._xhr.responseType = "text";
this._xhr.onload = function () {
@ -1065,6 +1115,11 @@ Phaser.Loader.prototype = {
this.game.cache.addText(file.key, file.url, file.data);
break;
case 'physics':
var data = JSON.parse(this._xhr.responseText);
this.game.cache.addPhysicsData(file.key, file.url, data, file.format);
break;
case 'script':
file.data = document.createElement('script');
file.data.language = 'javascript';

View file

@ -534,7 +534,7 @@ Phaser.Physics.Body.prototype = {
var path;
// Did they pass in a single array of points?
if (points.length === 1)
if (points.length === 1 && Array.isArray(points[0]))
{
path = points[0];
}
@ -643,69 +643,37 @@ Phaser.Physics.Body.prototype = {
},
/**
* Reads a polygon shape path, and assembles convex shapes from that and puts them at proper offset points. The shape must be simple and without holes.
* This function expects the x.y values to be given in pixels. If you want to provide them at p2 world scales then call Body.data.fromPolygon directly.
* Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body.
*
* @method Phaser.Physics.Body#setPolygon
* @method Phaser.Physics.Body#loadPolygon
* @param {string} key - The key of the Physics Data file as stored in Game.Cache.
* @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from.
* @param {object} options - An object containing the build options:
* @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices.
* @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself.
* @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points.
* @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon.
* Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...],
* or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers.
* @return {boolean} True on success, else false.
setPolygon: function (options, points) {
*/
loadPolygon: function (key, object, options) {
options = options || {};
var data = game.cache.getPhysicsData(key, object);
points = Array.prototype.slice.call(arguments, 1);
var path;
// Did they pass in a single array of points?
if (points.length === 1)
if (data && data.shape)
{
// console.log('part 1', points.length);
path = points[0];
}
else if (Array.isArray(points[0]))
{
// console.log('part 2', points.length);
path = points;
}
else if (typeof points[0] === 'number')
{
// A list of numbers?
// console.log('part 3');
var temp = [];
// We've a list of numbers
for (var i = 0, len = points.length; i < len; i += 2)
for (var i = 0, len = data.shape.length; i < len; i += 2)
{
temp.push([points[i], points[i + 1]]);
temp.push([data.shape[i], data.shape[i + 1]]);
}
path = temp;
return this.addPolygon(options, temp);
}
// Now process them into p2 values
for (var p = 0; p < path.length; p++)
{
path[p][0] = this.px2p(path[p][0]);
path[p][1] = this.px2p(path[p][1]);
}
// console.log('points');
// console.table(points);
// console.log('PATH');
// console.log(path);
return this.data.fromPolygon(path, options);
return false;
},
*/
/**
* Convert p2 physics value to pixel scale.

View file

@ -9,6 +9,11 @@
*/
Phaser.Physics = {};
/**
* @const
*/
Phaser.Physics.LIME_CORONA_JSON = 0;
// Add an extra property to p2.Body
p2.Body.prototype.parent = null;