Lots of work on the new Texture classes.

This commit is contained in:
photonstorm 2016-09-29 16:10:22 +01:00
parent 2590e67e2b
commit f993769336
11 changed files with 804 additions and 441 deletions

View file

@ -123,6 +123,11 @@ EOL;
<script src="$path/src/input/Touch.js"></script>
<script src="$path/src/input/InputHandler.js"></script>
<script src="$path/src/textures/TextureManager.js"></script>
<script src="$path/src/textures/Texture.js"></script>
<script src="$path/src/textures/Frame.js"></script>
<script src="$path/src/textures/parsers/JSONArray.js"></script>
EOL;

View file

@ -1,327 +0,0 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* A Frame is a section of a Texture.
*
* TODO:
*
* See if we can't consolidate all the crop, trim and frame values.
* Ideally TextureFrame.x/y/w/h should be the adjusted (cropped, trimmed, etc) values that the
* renderer and Sprites can use. Then all the original values can be stored internally.
*
* @class Phaser.TextureFrame
* @constructor
* @param {number} index - The index of this Frame within the FrameData set it is being added to.
* @param {number} x - X position of the frame within the texture image.
* @param {number} y - Y position of the frame within the texture image.
* @param {number} width - Width of the frame within the texture image.
* @param {number} height - Height of the frame within the texture image.
* @param {string} name - The name of the frame. In Texture Atlas data this is usually set to the filename.
*/
Phaser.TextureFrame = function (texture, name, x, y, width, height) {
/**
* @property {Phaser.Texture} texture - The Texture this frame belongs to.
*/
this.texture = texture;
/**
* @property {string} name - The name of this frame within the Texture.
*/
this.name = name;
// x, y, width, height = PIXI.Texture.frame
/**
* @property {number} x - X position within the image to cut from.
*/
this.x = x;
/**
* @property {number} y - Y position within the image to cut from.
*/
this.y = y;
/**
* @property {number} width - Width of the frame.
*/
this.width = width;
/**
* @property {number} height - Height of the frame.
*/
this.height = height;
/**
* Is this frame is rotated or not in the Texture?
* Rotation allows you to use rotated frames in texture atlas packing.
* It has nothing to do with Sprite rotation.
* @property {boolean} rotated
* @default
*/
this.rotated = false;
/**
* @property {boolean} trimmed - Was it trimmed when packed?
* @default
*/
this.trimmed = false;
/**
* @property {Object} trim - The trim area.
*/
this.trim = {
x: 0,
y: 0,
width: 0,
height: 0
};
/**
* @property {object} sourceSize - The width and height of the original sprite before it was trimmed.
*/
this.sourceSize = {
w: width,
h: height
};
/**
* @property {object} spriteSourceSize - The position of the trimmed frame data.
*/
this.spriteSourceSize = {
x: 0,
y: 0,
w: 0,
h: 0
};
/**
* @property {number} spriteSourceSize.x - X position of the trimmed frame inside original texture.
*/
/**
* @property {number} spriteSourceSize.y - Y position of the trimmed frame inside original texture.
*/
/**
* @property {number} spriteSourceSize.w - Width of the trimmed frame.
*/
/**
* @property {number} spriteSourceSize.h - Height of the trimmed frame.
*/
/**
* @property {number} right - The right of the Frame (x + width).
*/
this.right = this.x + this.width;
/**
* @property {number} bottom - The bottom of the frame (y + height).
*/
this.bottom = this.y + this.height;
/**
* Is this a tiling texture? As used by the likes of a TilingSprite.
*
* @property isTiling
* @type Boolean
*/
this.isTiling = false;
/**
* This will let a renderer know that a tinted parent has updated its texture.
*
* @property requiresReTint
* @type Boolean
*/
this.requiresReTint = false;
/**
* This is the area of the Texture image to actually copy to the Canvas / WebGL when rendering,
* irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases)
*
* @property crop
* @type Rectangle
*/
this.crop = {
x: 0,
y: 0,
width: this.width,
height: this.height
};
/**
* The WebGL UV data cache.
*
* @property _uvs
* @type Object
* @private
*/
this._uvs = {
x0: 0,
y0: 0,
x1: 0,
y1: 0,
x2: 0,
y2: 0,
x3: 0,
y3: 0
};
};
Phaser.TextureFrame.prototype = {
/**
* Adjusts of all the Frame properties based on the given width and height values.
*
* @method Phaser.TextureFrame#resize
* @param {integer} width - The new width of the Frame.
* @param {integer} height - The new height of the Frame.
*/
resize: function (width, height) {
this.width = width;
this.height = height;
this.sourceSize.w = width;
this.sourceSize.h = height;
this.right = this.x + width;
this.bottom = this.y + height;
},
/**
* If the frame was trimmed when added to the Texture Atlas this records the trim and source data.
*
* @method Phaser.TextureFrame#setTrim
* @param {boolean} trimmed - If this frame was trimmed or not.
* @param {number} actualWidth - The width of the frame before being trimmed.
* @param {number} actualHeight - The height of the frame before being trimmed.
* @param {number} destX - The destination X position of the trimmed frame for display.
* @param {number} destY - The destination Y position of the trimmed frame for display.
* @param {number} destWidth - The destination width of the trimmed frame for display.
* @param {number} destHeight - The destination height of the trimmed frame for display.
*/
setTrim: function (trimmed, actualWidth, actualHeight, destX, destY, destWidth, destHeight) {
this.trimmed = trimmed;
if (trimmed)
{
this.sourceSize.w = actualWidth;
this.sourceSize.h = actualHeight;
this.spriteSourceSize.x = destX;
this.spriteSourceSize.y = destY;
this.spriteSourceSize.w = destWidth;
this.spriteSourceSize.h = destHeight;
this.trim.x = destX;
this.trim.y = destY;
this.trim.width = destWidth;
this.trim.height = destHeight;
}
},
/**
* Clones this Frame into a new Phaser.TextureFrame object and returns it.
* Note that all properties are cloned, including the name and index.
*
* @method Phaser.TextureFrame#clone
* @return {Phaser.TextureFrame} An exact copy of this Frame object.
*/
clone: function () {
var output = new Phaser.TextureFrame(this.texture, this.name, this.x, this.y, this.width, this.height);
for (var prop in this)
{
if (this.hasOwnProperty(prop))
{
output[prop] = this[prop];
}
}
return output;
},
/**
* Returns a Rectangle set to the dimensions of this Frame.
*
* @method Phaser.TextureFrame#getRect
* @param {Phaser.Rectangle} [out] - A rectangle to copy the frame dimensions to.
* @return {Phaser.Rectangle} A rectangle.
*/
getRect: function (out) {
if (out === undefined)
{
out = new Phaser.Rectangle(this.x, this.y, this.width, this.height);
}
else
{
out.setTo(this.x, this.y, this.width, this.height);
}
return out;
},
updateUVs: function () {
var frame = this.crop;
var tw = this.texture.width;
var th = this.texture.height;
this._uvs.x0 = frame.x / tw;
this._uvs.y0 = frame.y / th;
this._uvs.x1 = (frame.x + frame.width) / tw;
this._uvs.y1 = frame.y / th;
this._uvs.x2 = (frame.x + frame.width) / tw;
this._uvs.y2 = (frame.y + frame.height) / th;
this._uvs.x3 = frame.x / tw;
this._uvs.y3 = (frame.y + frame.height) / th;
},
/**
* Updates the internal WebGL UV cache.
*
* @method _updateUvsInverted
* @private
*/
updateUVsInverted: function () {
var frame = this.crop;
var tw = this.texture.width;
var th = this.texture.height;
this._uvs.x0 = frame.x / tw;
this._uvs.y0 = frame.y / th;
this._uvs.x1 = (frame.x + frame.height) / tw;
this._uvs.y1 = frame.y / th;
this._uvs.x2 = (frame.x + frame.height) / tw;
this._uvs.y2 = (frame.y + frame.width) / th;
this._uvs.x3 = frame.x / tw;
this._uvs.y3 = (frame.y + frame.width) / th;
},
destroy: function () {
// TODO?
}
};
Phaser.TextureFrame.prototype.constructor = Phaser.TextureFrame;

View file

@ -1,31 +0,0 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
*
* @class Phaser.TextureManager
* @constructor
* @param {Phaser.Game} game
*/
Phaser.TextureManager = function (game) {
this.game = game;
this.list = new Phaser.ArraySet();
};
Phaser.TextureManager.prototype.constructor = Phaser.TextureManager;
Phaser.TextureManager.prototype = {
add: function (texture) {
return this.list.add(texture);
}
};

326
src/textures/Frame.js Normal file
View file

@ -0,0 +1,326 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* A Frame is a section of a Texture.
*
* Called TextureFrame during integration, will rename to Frame later.
*
* @class Phaser.TextureFrame
* @constructor
* @param {Phaser.Texture} texture - The Texture this Frame belongs to.
* @param {string} name - The unique (within the Texture) name of this Frame.
* @param {number} x - X position of the frame within the Texture.
* @param {number} y - Y position of the frame within the Texture.
* @param {number} width - Width of the frame within the Texture.
* @param {number} height - Height of the frame within the Texture.
*/
Phaser.TextureFrame = function (texture, name, x, y, width, height)
{
/**
* @property {Phaser.Texture} texture - The Texture this frame belongs to.
*/
this.texture = texture;
this.source = texture.source;
/**
* @property {string} name - The name of this frame within the Texture.
*/
this.name = name;
/**
* @property {number} cutX - X position within the source image to cut from.
*/
this.cutX = x;
/**
* @property {number} cutY - Y position within the source image to cut from.
*/
this.cutY = y;
/**
* @property {number} cutWidth - The width of the area in the source image to cut.
*/
this.cutWidth = width;
/**
* @property {number} cutHeight - The height of the area in the source image to cut.
*/
this.cutHeight = height;
/**
* @property {number} x - The X rendering offset of this Frame, taking trim into account.
*/
this.x = 0;
/**
* @property {number} y - The Y rendering offset of this Frame, taking trim into account.
*/
this.y = 0;
/**
* @property {number} width - The rendering width of this Frame, taking trim into account.
*/
this.width = width;
/**
* @property {number} height - The rendering height of this Frame, taking trim into account.
*/
this.height = height;
/**
* Is this frame is rotated or not in the Texture?
* Rotation allows you to use rotated frames in texture atlas packing.
* It has nothing to do with Sprite rotation.
* @property {boolean} rotated
* @default
*/
this.rotated = false;
/**
* Is this a tiling texture? As used by the likes of a TilingSprite.
*
* @property {boolean} isTiling
* @default
*/
this.isTiling = false;
/**
* This will let a renderer know that a tinted parent has updated its texture.
*
* @property {boolean} requiresReTint
* @default
*/
this.requiresReTint = false;
/**
* The un-modified source frame, trim and UV data.
*
* @private
* @property {object} data
*/
this.data = {
cut: {
x: x,
y: y,
w: width,
h: height,
r: x + width,
b: y + height
},
sourceSize: {
w: width,
h: height
},
spriteSourceSize: {
x: 0,
y: 0,
w: width,
h: height
},
uvs: {
x0: 0,
y0: 0,
x1: 0,
y1: 0,
x2: 0,
y2: 0,
x3: 0,
y3: 0
}
};
};
Phaser.TextureFrame.prototype.constructor = Phaser.TextureFrame;
Phaser.TextureFrame.prototype = {
crop: function (width, height, x, y)
{
if (width === undefined) { width = this.data.cut.w; }
if (height === undefined) { height = this.data.cut.h; }
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (width === undefined)
{
// No arguments means reset the crop
this.cutX = this.data.cut.x;
this.cutY = this.data.cut.y;
this.cutWidth = this.data.cut.w;
this.cutHeight = this.data.cut.h;
}
else if (width !== this.cutWidth || height !== this.cutHeight || x !== this.cutX || y !== this.cutY)
{
this.cutX = Phaser.Math.clamp(x, this.data.cut.x, this.data.cut.r);
this.cutY = Phaser.Math.clamp(y, this.data.cut.y, this.data.cut.b);
this.cutWidth = Phaser.Math.clamp(width, 0, this.data.cut.w - this.cutX);
this.cutHeight = Phaser.Math.clamp(height, 0, this.data.cut.h - this.cutY);
}
return this;
},
/**
* If the frame was trimmed when added to the Texture Atlas, this records the trim and source data.
*
* @method Phaser.TextureFrame#setTrim
* @param {number} actualWidth - The width of the frame before being trimmed.
* @param {number} actualHeight - The height of the frame before being trimmed.
* @param {number} destX - The destination X position of the trimmed frame for display.
* @param {number} destY - The destination Y position of the trimmed frame for display.
* @param {number} destWidth - The destination width of the trimmed frame for display.
* @param {number} destHeight - The destination height of the trimmed frame for display.
*/
setTrim: function (actualWidth, actualHeight, destX, destY, destWidth, destHeight)
{
// Store actual values
this.data.sourceSize.w = actualWidth;
this.data.sourceSize.h = actualHeight;
this.data.spriteSourceSize.x = destX;
this.data.spriteSourceSize.y = destY;
this.data.spriteSourceSize.w = destWidth;
this.data.spriteSourceSize.h = destHeight;
// Adjust properties
this.x = destX;
this.y = destY;
this.width = destWidth;
this.height = destHeight;
return this;
},
/**
* Updates the internal WebGL UV cache.
*
* @method updateUVs
* @private
*/
updateUVs: function ()
{
var tw = this.texture.width;
var th = this.texture.height;
var uvs = this.data.uvs;
uvs.x0 = this.x / tw;
uvs.y0 = this.y / th;
uvs.x1 = (this.x + this.width) / tw;
uvs.y1 = this.y / th;
uvs.x2 = (this.x + this.width) / tw;
uvs.y2 = (this.y + this.height) / th;
uvs.x3 = this.x / tw;
uvs.y3 = (this.y + this.height) / th;
return this;
},
/**
* Updates the internal WebGL UV cache.
*
* @method updateUVsInverted
* @private
*/
updateUVsInverted: function ()
{
var tw = this.texture.width;
var th = this.texture.height;
var uvs = this.data.uvs;
uvs.x0 = this.x / tw;
uvs.y0 = this.y / th;
uvs.x1 = (this.x + this.height) / tw;
uvs.y1 = this.y / th;
uvs.x2 = (this.x + this.height) / tw;
uvs.y2 = (this.y + this.width) / th;
uvs.x3 = this.x / tw;
uvs.y3 = (this.y + this.width) / th;
return this;
},
/**
* Adjusts of all the Frame properties based on the given width and height values.
*
* @method Phaser.TextureFrame#resize
* @param {integer} width - The new width of the Frame.
* @param {integer} height - The new height of the Frame.
*/
resize: function (width, height)
{
},
clone: function ()
{
},
right: function ()
{
},
bottom: function ()
{
},
destroy: function ()
{
}
};
Object.defineProperties(Phaser.TextureFrame.prototype, {
/**
* The width of the Frame in its un-trimmed, un-padded state, as prepared in the art package,
* before being packed.
*
* @name Phaser.TextureFrame#realWidth
* @property {any} realWidth
*/
realWidth: {
enumerable: true,
get: function ()
{
return this.data.sourceSize.w;
}
},
/**
* The height of the Frame in its un-trimmed, un-padded state, as prepared in the art package,
* before being packed.
*
* @name Phaser.TextureFrame#realHeight
* @property {any} realHeight
*/
realHeight: {
enumerable: true,
get: function ()
{
return this.data.sourceSize.h;
}
}
});

View file

@ -20,7 +20,18 @@
* @param {object} source
* @param {number} scaleMode
*/
Phaser.Texture = function (source, scaleMode) {
Phaser.Texture = function (key, source, scaleMode)
{
this.key = key;
/**
* The source that is used to create the texture.
* Usually an Image, but can also be a Canvas.
*
* @property source
* @type Image
*/
this.source = source;
/**
* The Resolution of the texture.
@ -37,7 +48,7 @@ Phaser.Texture = function (source, scaleMode) {
* @type Number
* @readOnly
*/
this.width = 0;
this.width = source.naturalWidth || source.width || 0;
/**
* The height of the Texture.
@ -46,7 +57,7 @@ Phaser.Texture = function (source, scaleMode) {
* @type Number
* @readOnly
*/
this.height = 0;
this.height = source.naturalHeight || source.height || 0;
/**
* The scale mode to apply when scaling this texture
@ -57,15 +68,6 @@ Phaser.Texture = function (source, scaleMode) {
*/
this.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT;
/**
* The source that is used to create the texture.
* Usually an Image, but can also be a Canvas.
*
* @property source
* @type Image
*/
this.source = source;
/**
* Controls if RGB channels should be pre-multiplied by Alpha (WebGL only)
*
@ -75,13 +77,6 @@ Phaser.Texture = function (source, scaleMode) {
*/
this.premultipliedAlpha = true;
/**
* @property _glTextures
* @type Array
* @private
*/
this._glTextures = [];
/**
* Set this to true if a mipmap of this texture needs to be generated. This value needs to be set before the texture is used
* Also the texture must be a power of two size to work
@ -98,6 +93,30 @@ Phaser.Texture = function (source, scaleMode) {
*/
this.textureIndex = 0;
/**
* A BaseTexture can be set to skip the rendering phase in the WebGL Sprite Batch.
*
* You may want to do this if you have a parent Sprite with no visible texture (i.e. uses the internal `__default` texture)
* that has children that you do want to render, without causing a batch flush in the process.
*
* @property renderable
* @type Boolean
*/
this.renderable = false;
/**
* @property isPowerOf2
* @type boolean
*/
this.isPowerOf2 = Phaser.Math.isPowerOfTwo(this.width, this.height);
/**
* @property {object} frames - Frames
*/
this.frames = {
__BASE: new Phaser.TextureFrame(this, '__BASE', 0, 0, this.width, this.height)
};
/**
* @property _dirty
* @type Array
@ -106,35 +125,11 @@ Phaser.Texture = function (source, scaleMode) {
this._dirty = [ true, true, true, true ];
/**
* A BaseTexture can be set to skip the rendering phase in the WebGL Sprite Batch.
*
* You may want to do this if you have a parent Sprite with no visible texture (i.e. uses the internal `__default` texture)
* that has children that you do want to render, without causing a batch flush in the process.
*
* @property skipRender
* @type Boolean
*/
this.skipRender = false;
/**
* @property _powerOf2
* @type Boolean
* @property _glTextures
* @type Array
* @private
*/
this._powerOf2 = false;
if (!source)
{
return;
}
if ((this.source.complete || this.source.getContext) && this.source.width && this.source.height)
{
this.width = this.source.naturalWidth || this.source.width;
this.height = this.source.naturalHeight || this.source.height;
this._powerOf2 = Phaser.Math.isPowerOfTwo(this.width, this.height);
this.dirty();
}
this._glTextures = [];
};
@ -142,38 +137,20 @@ Phaser.Texture.prototype.constructor = Phaser.Texture;
Phaser.Texture.prototype = {
/**
* Forces this BaseTexture to be set as loaded, with the given width and height.
* Then calls BaseTexture.dirty.
* Important for when you don't want to modify the source object by forcing in `complete` or dimension properties it may not have.
*
* @method forceLoaded
* @param {number} width - The new width to force the BaseTexture to be.
* @param {number} height - The new height to force the BaseTexture to be.
*/
forceLoaded: function(width, height) {
add: function (name, x, y, width, height)
{
var frame = new Phaser.TextureFrame(this, name, x, y, width, height);
this.width = width;
this.height = height;
this.dirty();
this.frames[name] = frame;
return frame;
},
/**
* Destroys this base texture
*
* @method destroy
*/
destroy: function() {
if (this.source)
get: function (name)
{
Phaser.CanvasPool.removeByCanvas(this.source);
}
if (name === undefined) { name = '__BASE'; }
this.source = null;
this.unloadFromGPU();
return this.frames[name];
},
@ -182,23 +159,22 @@ Phaser.Texture.prototype = {
*
* @method dirty
*/
dirty: function() {
dirty: function ()
{
for (var i = 0; i < this._glTextures.length; i++)
{
this._dirty[i] = true;
}
},
/**
* Removes the base texture from the GPU, useful for managing resources on the GPU.
* Atexture is still 100% usable and will simply be reuploaded if there is a sprite on screen that is using it.
* A texture is still 100% usable and will simply be re-uploaded if there is a sprite on screen that is using it.
*
* @method unloadFromGPU
*/
unloadFromGPU: function () {
unloadFromGPU: function ()
{
this.dirty();
// delete the webGL textures if any.
@ -216,10 +192,26 @@ Phaser.Texture.prototype = {
this._glTextures.length = 0;
this.dirty();
},
/**
* Destroys this base texture
*
* @method destroy
*/
destroy: function ()
{
if (this.source)
{
Phaser.CanvasPool.removeByCanvas(this.source);
}
this.source = null;
this.unloadFromGPU();
// TODO: Clear out the Frames
}
};
@ -232,8 +224,8 @@ Phaser.Texture.prototype = {
* @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values
* @return {BaseTexture}
*/
Phaser.Texture.fromCanvas = function (canvas, scaleMode) {
Phaser.Texture.fromCanvas = function (canvas, scaleMode)
{
if (canvas.width === 0)
{
canvas.width = 1;
@ -245,5 +237,4 @@ Phaser.Texture.fromCanvas = function (canvas, scaleMode) {
}
return new Phaser.Texture(canvas, scaleMode);
};

View file

@ -0,0 +1,63 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Textures are managed by the global TextureManager. This is a singleton class that is
* responsible for creating and delivering Textures and their corresponding Frames to Game Objects.
*
* Sprites and other Game Objects get the texture data they need from the TextureManager.
*
* Access it via `state.textures`.
*
* @class Phaser.TextureManager
* @constructor
* @param {Phaser.Game} game
*/
Phaser.TextureManager = function (game)
{
this.game = game;
this.list = {
// Empty by default
};
};
Phaser.TextureManager.prototype.constructor = Phaser.TextureManager;
Phaser.TextureManager.prototype = {
create: function (key, source, scaleMode)
{
var texture = new Phaser.Texture(key, source, scaleMode);
this.list[key] = texture;
return texture;
},
get: function (key, frame)
{
if (this.list[key])
{
if (frame)
{
return this.list[key].get(frame);
}
else
{
return this.list[key];
}
}
}
};
Phaser.TextureManager.Parsers = {
};

View file

@ -0,0 +1,57 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Parses a JSON Array and extracts the frame data from it.
*
* @class Phaser.TextureParser.JSONArray
* @static
* @param {Phaser.Texture} texture - The parent Texture.
* @param {object} json - The JSON data from the Texture Atlas. Must be in Array format.
* @return {Phaser.FrameData} A FrameData object containing the parsed frames.
*/
Phaser.TextureManager.Parsers.JSONArray = function (texture, json)
{
// Malformed?
if (!json['frames'])
{
// console.warn("Phaser.AnimationParser.JSONData: Invalid Texture Atlas JSON given, missing 'frames' array");
// console.log(json);
return;
}
// By this stage frames is a fully parsed array
var frames = json['frames'];
var newFrame;
for (var i = 0; i < frames.length; i++)
{
var src = frames[i];
// The frame values are the exact coordinates to cut the frame out of the atlas from
newFrame = texture.add(src.filename, src.frame.x, src.frame.y, src.frame.w, src.frame.h);
// These are the original (non-trimmed) sprite values
if (src.trimmed)
{
newFrame.setTrim(
src.sourceSize.w,
src.sourceSize.h,
src.spriteSourceSize.x,
src.spriteSourceSize.y,
src.spriteSourceSize.w,
src.spriteSourceSize.h
);
}
if (src.rotated)
{
newFrame.rotated = true;
}
}
return texture;
};

View file

@ -0,0 +1,57 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Parses a JSON Array and extracts the frame data from it.
*
* @class Phaser.TextureParser.JSONArray
* @static
* @param {Phaser.Texture} texture - The parent Texture.
* @param {object} json - The JSON data from the Texture Atlas. Must be in JSON Hash format.
* @return {Phaser.FrameData} A FrameData object containing the parsed frames.
*/
Phaser.TextureParser.JSONHash = function (texture, json)
{
// Malformed?
if (!json['frames'])
{
// console.warn("Phaser.AnimationParser.JSONDataHash: Invalid Texture Atlas JSON given, missing 'frames' object");
// console.log(json);
return;
}
// By this stage frames is a fully parsed array
var frames = json['frames'];
var newFrame;
for (var key in frames)
{
var src = frames[key];
// The frame values are the exact coordinates to cut the frame out of the atlas from
newFrame = texture.add(key, src.frame.x, src.frame.y, src.frame.w, src.frame.h);
// These are the original (non-trimmed) sprite values
if (src.trimmed)
{
newFrame.setTrim(
src.sourceSize.w,
src.sourceSize.h,
src.spriteSourceSize.x,
src.spriteSourceSize.y,
src.spriteSourceSize.w,
src.spriteSourceSize.h
);
}
if (src.rotated)
{
newFrame.rotated = true;
}
}
return data;
};

View file

@ -0,0 +1,63 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Parses a Pyxel JSON File and extracts the frame data from it.
*
* @class Phaser.TextureParser.JSONArray
* @static
* @param {Phaser.Texture} texture - The parent Texture.
* @param {object} json - The JSON data from the Texture Atlas. Must be in Pyxel JSON format.
* @return {Phaser.FrameData} A FrameData object containing the parsed frames.
*/
Phaser.TextureParser.Pyxel = function (texture, json)
{
// Malformed? There are a few keys to check here.
var signature = [ 'layers', 'tilewidth', 'tileheight', 'tileswide', 'tileshigh' ];
signature.forEach(function (key)
{
if (!json[key])
{
// console.warn('Phaser.AnimationParser.JSONDataPyxel: Invalid Pyxel Tilemap JSON given, missing "' + key + '" key.');
// console.log(json);
return;
}
});
// For this purpose, I only care about parsing tilemaps with a single layer.
if (json['layers'].length !== 1)
{
// console.warn('Phaser.AnimationParser.JSONDataPyxel: Too many layers, this parser only supports flat Tilemaps.');
// console.log(json);
return;
}
var data = new Phaser.FrameData();
var tileheight = json['tileheight'];
var tilewidth = json['tilewidth'];
var frames = json['layers'][0]['tiles'];
var newFrame;
for (var i = 0; i < frames.length; i++)
{
newFrame = data.addFrame(new Phaser.Frame(
i,
frames[i].x,
frames[i].y,
tilewidth,
tileheight,
"frame_" + i // No names are included in pyxel tilemap data.
));
// No trim data is included.
newFrame.setTrim(false);
}
return data;
};

View file

@ -0,0 +1,86 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Parse a Sprite Sheet and extracts the frame data from it.
*
* @class Phaser.TextureParser.SpriteSheet
* @static
* @param {Phaser.Texture} texture - The parent Texture.
* @param {string} key - The key of the Frame within the Texture that the Sprite Sheet is stored in.
* @param {number} frameWidth - The fixed width of each frame.
* @param {number} frameHeight - The fixed height of each frame.
* @param {number} [frameMax=-1] - The total number of frames to extract from the Sprite Sheet. The default value of -1 means "extract all frames".
* @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
* @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
* @param {number} [skipFrames=0] - Skip a number of frames. Useful when there are multiple sprite sheets in one Texture.
* @return {Phaser.FrameData} A FrameData object containing the parsed frames.
*/
Phaser.TextureParser.SpriteSheet = function (texture, frameWidth, frameHeight, frameMax, margin, spacing, skipFrames)
{
var width = texture.width;
var height = texture.height;
if (frameWidth <= 0)
{
frameWidth = Math.floor(-width / Math.min(-1, frameWidth));
}
if (frameHeight <= 0)
{
frameHeight = Math.floor(-height / Math.min(-1, frameHeight));
}
var row = Math.floor((width - margin) / (frameWidth + spacing));
var column = Math.floor((height - margin) / (frameHeight + spacing));
var total = row * column;
if (skipFrames > total || skipFrames < -total)
{
console.warn(
'Phaser.AnimationParser.spriteSheet: skipFrames = ' +
skipFrames.toString() + ' is larger than total sprite number ' +
total.toString());
return null;
}
if (skipFrames < 0)
{
// Allow negative skipframes.
skipFrames = total + skipFrames;
}
if (frameMax !== -1)
{
total = skipFrames + frameMax;
}
// Zero or smaller than frame sizes?
if (width === 0 || height === 0 || width < frameWidth || height < frameHeight || total === 0)
{
// console.warn('Phaser.AnimationParser.spriteSheet: ' + key + ' width / height zero or < given frameWidth / frameHeight');
return null;
}
// Let's create some frames then
var x = margin;
var y = margin;
for (var i = 0; i < total; i++)
{
texture.addFrame(i.toString(), x, y, frameWidth, frameHeight);
x += frameWidth + spacing;
if (x + frameWidth > width)
{
x = margin;
y += frameHeight + spacing;
}
}
return texture;
};

View file

@ -0,0 +1,73 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* Parses the XML and extracts the frame data from it.
*
* @class Phaser.TextureParser.StarlingXML
* @static
* @param {Phaser.Texture} texture - The parent Texture.
* @param {object} xml - The XML data from the Texture Atlas. Must be in Starling XML format.
* @return {Phaser.FrameData} A FrameData object containing the parsed frames.
*/
Phaser.TextureParser.StarlingXML = function (texture, xml)
{
// Malformed?
if (!xml.getElementsByTagName('TextureAtlas'))
{
// console.warn("Phaser.AnimationParser.XMLData: Invalid Texture Atlas XML given, missing <TextureAtlas> tag");
return;
}
// Let's create some frames then
var data = new Phaser.FrameData();
var frames = xml.getElementsByTagName('SubTexture');
var newFrame;
var name;
var frame;
var x;
var y;
var width;
var height;
var frameX;
var frameY;
var frameWidth;
var frameHeight;
for (var i = 0; i < frames.length; i++)
{
frame = frames[i].attributes;
name = frame.name.value;
x = parseInt(frame.x.value, 10);
y = parseInt(frame.y.value, 10);
width = parseInt(frame.width.value, 10);
height = parseInt(frame.height.value, 10);
frameX = null;
frameY = null;
if (frame.frameX)
{
frameX = Math.abs(parseInt(frame.frameX.value, 10));
frameY = Math.abs(parseInt(frame.frameY.value, 10));
frameWidth = parseInt(frame.frameWidth.value, 10);
frameHeight = parseInt(frame.frameHeight.value, 10);
}
newFrame = data.addFrame(new Phaser.Frame(i, x, y, width, height, name));
// Trimmed?
if (frameX !== null || frameY !== null)
{
newFrame.setTrim(true, width, height, frameX, frameY, frameWidth, frameHeight);
}
}
return data;
};