diff --git a/CHANGELOG b/CHANGELOG
index 0a20099afd..2db55747fa 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
Version History
---------------
0.9.8
+* Renderable : added ShoeBox Packed Texture Support (see `me.TextureAtlas`)
0.9.7
* General : melonJS now uses Grunt, the task manager, for the build system
diff --git a/examples/platformer/data/gfx/shoebox.json b/examples/platformer/data/gfx/shoebox.json
new file mode 100644
index 0000000000..4a907759d9
--- /dev/null
+++ b/examples/platformer/data/gfx/shoebox.json
@@ -0,0 +1,153 @@
+{"frames": [
+ {
+ "filename": "coin.png",
+ "frame": {"x":258,"y":196,"w":35,"h":35},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":35,"h":35},
+ "sourceSize": {"w":35,"h":35}
+ },
+ {
+ "filename": "fly_dead.png",
+ "frame": {"x":0,"y":196,"w":69,"h":32},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":69,"h":32},
+ "sourceSize": {"w":69,"h":32}
+ },
+ {
+ "filename": "fly_fly.png",
+ "frame": {"x":71,"y":196,"w":69,"h":31},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":69,"h":31},
+ "sourceSize": {"w":69,"h":31}
+ },
+ {
+ "filename": "fly_normal.png",
+ "frame": {"x":142,"y":196,"w":69,"h":32},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":69,"h":32},
+ "sourceSize": {"w":69,"h":32}
+ },
+ {
+ "filename": "slime_dead.png",
+ "frame": {"x":0,"y":230,"w":54,"h":8},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":54,"h":8},
+ "sourceSize": {"w":54,"h":8}
+ },
+ {
+ "filename": "slime_normal.png",
+ "frame": {"x":213,"y":196,"w":43,"h":28},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":43,"h":28},
+ "sourceSize": {"w":43,"h":28}
+ },
+ {
+ "filename": "slime_walk.png",
+ "frame": {"x":213,"y":226,"w":43,"h":26},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":43,"h":26},
+ "sourceSize": {"w":43,"h":26}
+ },
+ {
+ "filename": "walk0001.png",
+ "frame": {"x":77,"y":0,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0002.png",
+ "frame": {"x":77,"y":98,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0003.png",
+ "frame": {"x":154,"y":0,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0004.png",
+ "frame": {"x":154,"y":98,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0005.png",
+ "frame": {"x":308,"y":0,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0006.png",
+ "frame": {"x":231,"y":98,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0007.png",
+ "frame": {"x":308,"y":98,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0008.png",
+ "frame": {"x":0,"y":0,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0009.png",
+ "frame": {"x":0,"y":98,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0010.png",
+ "frame": {"x":231,"y":0,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {
+ "filename": "walk0011.png",
+ "frame": {"x":77,"y":0,"w":75,"h":96},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":75,"h":96},
+ "sourceSize": {"w":75,"h":96}
+ },
+ {"EOL":"true"}
+],
+"meta": {
+ "app": "ShoeBox",
+ "exporter": "melonJS",
+ "size": {"w":512,"h":256}
+}
+}
\ No newline at end of file
diff --git a/examples/platformer/data/gfx/shoebox.png b/examples/platformer/data/gfx/shoebox.png
new file mode 100644
index 0000000000..06ee4c20b2
Binary files /dev/null and b/examples/platformer/data/gfx/shoebox.png differ
diff --git a/examples/platformer/main.js b/examples/platformer/main.js
index e4104909f1..f438f18819 100644
--- a/examples/platformer/main.js
+++ b/examples/platformer/main.js
@@ -23,6 +23,9 @@ var game = {
// texturePacker
{name: "texture", type: "tps", src: "data/gfx/texture.json"},
{name: "texture", type:"image", src: "data/gfx/texture.png"}
+ // ShoeBox
+ //{name: "texture", type: "tps", src: "data/gfx/shoebox.json"},
+ //{name: "texture", type:"image", src: "data/gfx/shoebox.png"}
],
/* ---
diff --git a/media/shoebox_JSON_export.sbx b/media/shoebox_JSON_export.sbx
new file mode 100644
index 0000000000..45ef72e1c2
--- /dev/null
+++ b/media/shoebox_JSON_export.sbx
@@ -0,0 +1 @@
+::ShoeBox:shoebox.plugin.createSpriteSheet::PluginCreateSpriteSheet:{"texPowerOfTwo":true,"fileGenerate2xSize":false,"texPadding":2,"scale":1,"texMaxSize":2048,"texExtrudeSize":1,"useCssOverHack":false,"fileFormatLoop":"\\t{\\n\\t\\t\"filename\": \"@id\",\\n\\t\\t\"frame\": {\"x\":@x,\"y\":@y,\"w\":@w,\"h\":@h},\\n\\t\\t\"rotated\": false,\\n\\t\\t\"trimmed\": true,\\n\\t\\t\"spriteSourceSize\": {\"x\":@fx,\"y\":@fy,\"w\":@fw,\"h\":@fh},\\n\\t\\t\"sourceSize\": {\"w\":@fw,\"h\":@fh}\\n\\t},\\n","renderDebugLayer":false,"animationFrameIdStart":0,"texSquare":false,"fileName":"shoebox.json","texCropAlpha":false,"animationMaxFrames":100,"animationNameIds":"@name_###.png","fileFormatOuter":"{\"frames\": [\\n@loop\\t{\"EOL\":\"true\"}\\n],\\n\"meta\": {\\n\\t\"app\": \"ShoeBox\",\\n\\t\"exporter\": \"melonJS\",\\n\\t\"size\": {\"w\":@W,\"h\":@H}\\n}\\n}"}
diff --git a/src/renderable/texturepacker.js b/src/renderable/texturepacker.js
index 3ab5e2ac91..59b23914a9 100644
--- a/src/renderable/texturepacker.js
+++ b/src/renderable/texturepacker.js
@@ -14,7 +14,10 @@
var nhPI = -(Math.PI / 2);
/**
- * A Texture atlas object.
+ * A Texture atlas object
+ * Currently support :
+ * - [TexturePacker]{@link http://www.codeandweb.com/texturepacker/} : through JSON export
+ * - [ShoeBox]{@link http://renderhjs.net/shoebox/} : through JSON export using the melonJS setting [file]{@link https://github.com/melonjs/melonJS/tree/master/media/shoebox_JSON_export.sbx}
* @class
* @extends Object
* @memberOf me
@@ -53,16 +56,28 @@
* @ignore
*/
init : function(atlas, texture) {
- if (atlas && atlas.meta && atlas.meta.app.contains("texturepacker")) {
- this.format = "texturepacker";
- // set the texture
- if (texture===undefined) {
- var name = me.utils.getBasename(atlas.meta.image);
- this.texture = me.loader.getImage(name);
- if (this.texture === null) {
- throw "melonjs: Atlas texture '" + name + "' not found";
+ if (atlas && atlas.meta) {
+ // Texture Packer
+ if (atlas.meta.app.contains("texturepacker")) {
+ this.format = "texturepacker";
+ // set the texture
+ if (texture===undefined) {
+ var name = me.utils.getBasename(atlas.meta.image);
+ this.texture = me.loader.getImage(name);
+ if (this.texture === null) {
+ throw "melonjs: Atlas texture '" + name + "' not found";
+ }
+ } else {
+ this.texture = texture;
}
- } else {
+ }
+ // ShoeBox
+ if (atlas.meta.app.contains("ShoeBox")) {
+ if (!atlas.meta.exporter || !atlas.meta.exporter.contains("melonJS")) {
+ throw "melonjs: ShoeBox requires the JSON exporter : https://github.com/melonjs/melonJS/tree/master/media/shoebox_JSON_export.sbx";
+ }
+ this.format = "ShoeBox";
+ // set the texture
this.texture = texture;
}
// initialize the atlas
@@ -81,20 +96,23 @@
initFromTexturePacker : function (data) {
var atlas = {};
data.frames.forEach(function(frame) {
- atlas[frame.filename] = {
- frame: new me.Rect(
- new me.Vector2d(frame.frame.x, frame.frame.y),
- frame.frame.w, frame.frame.h
- ),
- source: new me.Rect(
- new me.Vector2d(frame.spriteSourceSize.x, frame.spriteSourceSize.y),
- frame.spriteSourceSize.w, frame.spriteSourceSize.h
- ),
- // non trimmed size, but since we don't support trimming both value are the same
- //sourceSize: new me.Vector2d(frame.sourceSize.w,frame.sourceSize.h),
- rotated : frame.rotated===true,
- trimmed : frame.trimmed===true
- };
+ // fix wrongly formatted JSON (e.g. last dummy object in ShoeBox)
+ if (frame.hasOwnProperty("filename")) {
+ atlas[frame.filename] = {
+ frame: new me.Rect(
+ new me.Vector2d(frame.frame.x, frame.frame.y),
+ frame.frame.w, frame.frame.h
+ ),
+ source: new me.Rect(
+ new me.Vector2d(frame.spriteSourceSize.x, frame.spriteSourceSize.y),
+ frame.spriteSourceSize.w, frame.spriteSourceSize.h
+ ),
+ // non trimmed size, but since we don't support trimming both value are the same
+ //sourceSize: new me.Vector2d(frame.sourceSize.w,frame.sourceSize.h),
+ rotated : frame.rotated===true,
+ trimmed : frame.trimmed===true
+ };
+ }
});
return atlas;
},