phaser-ce
Version:
Phaser CE (Community Edition) is a fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.
189 lines (149 loc) • 6.15 kB
JavaScript
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
/**
* The SpriteBatch class is a really fast version of the DisplayObjectContainer built purely for speed, so use when you need a lot of sprites or particles.
* It's worth mentioning that by default sprite batches are used through-out the renderer, so you only really need to use a SpriteBatch if you have over
* 1000 sprites that all share the same texture (or texture atlas). It's also useful if running in Canvas mode and you have a lot of un-rotated or un-scaled
* Sprites as it skips all of the Canvas setTransform calls, which helps performance, especially on mobile devices.
*
* Please note that any Sprite that is part of a SpriteBatch will not have its bounds updated, so will fail checks such as outOfBounds.
*
* @class Phaser.SpriteBatch
* @extends Phaser.Group
* @constructor
* @param {Phaser.Game} game - A reference to the currently running game.
* @param {Phaser.Group|Phaser.Sprite|null} parent - The parent Group, DisplayObject or DisplayObjectContainer that this Group will be added to. If `undefined` or `null` it will use game.world.
* @param {string} [name=group] - A name for this Group. Not used internally but useful for debugging.
* @param {boolean} [addToStage=false] - If set to true this Group will be added directly to the Game.Stage instead of Game.World.
*/
Phaser.SpriteBatch = function (game, parent, name, addToStage) {
if (parent === undefined || parent === null) { parent = game.world; }
Phaser.Group.call(this, game, parent, name, addToStage);
/**
* @property {number} type - Internal Phaser Type value.
* @protected
*/
this.type = Phaser.SPRITEBATCH;
/**
* @property {Object} fastSpriteBatch - WebGL Batch Shader.
* @private
*/
this.fastSpriteBatch = null;
/**
* @property {boolean} ready - Internal flag.
* @private
*/
this.ready = false;
};
Phaser.SpriteBatch.prototype = Object.create(Phaser.Group.prototype);
Phaser.SpriteBatch.prototype.constructor = Phaser.SpriteBatch;
/**
* Renders the Sprite Batch using the WebGL renderer.
*
* @private
* @method
* @memberof Phaser.SpriteBatch
* @param {RenderSession} renderSession
*/
Phaser.SpriteBatch.prototype._renderWebGL = function (renderSession) {
if (!this.visible || this.alpha <= 0 || !this.children.length)
{
return;
}
if (!this.ready)
{
this.fastSpriteBatch = new PIXI.WebGLFastSpriteBatch(renderSession.gl);
this.ready = true;
}
if (this.fastSpriteBatch.gl !== renderSession.gl)
{
this.fastSpriteBatch.setContext(renderSession.gl);
}
renderSession.spriteBatch.stop();
renderSession.shaderManager.setShader(renderSession.shaderManager.fastShader);
this.fastSpriteBatch.begin(this, renderSession);
this.fastSpriteBatch.render(this);
renderSession.spriteBatch.start();
};
/**
* Renders the Sprite Batch using the Canvas renderer.
*
* @private
* @method
* @memberof Phaser.SpriteBatch
* @param {RenderSession} renderSession
*/
Phaser.SpriteBatch.prototype._renderCanvas = function (renderSession) {
if (!this.visible || this.alpha <= 0 || !this.children.length)
{
return;
}
var context = renderSession.context;
context.globalAlpha = this.worldAlpha;
this.displayObjectUpdateTransform();
var transform = this.worldTransform;
var isRotated = true;
for (var i = 0; i < this.children.length; i++)
{
var child = this.children[i];
if (!child.visible)
{
continue;
}
var texture = child.texture;
var frame = texture.frame;
context.globalAlpha = this.worldAlpha * child.alpha;
if (child.rotation % (Math.PI * 2) === 0)
{
// If rotation === 0 we can avoid setTransform
if (isRotated)
{
context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty);
isRotated = false;
}
context.drawImage(
texture.baseTexture.source,
frame.x,
frame.y,
frame.width,
frame.height,
((child.anchor.x) * (-frame.width * child.scale.x) + child.position.x + 0.5 + renderSession.shakeX) | 0,
((child.anchor.y) * (-frame.height * child.scale.y) + child.position.y + 0.5 + renderSession.shakeY) | 0,
frame.width * child.scale.x,
frame.height * child.scale.y);
}
else
{
if (!isRotated)
{
isRotated = true;
}
child.displayObjectUpdateTransform();
var childTransform = child.worldTransform;
var tx = (childTransform.tx * renderSession.resolution) + renderSession.shakeX;
var ty = (childTransform.ty * renderSession.resolution) + renderSession.shakeY;
// allow for trimming
if (renderSession.roundPixels)
{
context.setTransform(childTransform.a, childTransform.b, childTransform.c, childTransform.d, tx | 0, ty | 0);
}
else
{
context.setTransform(childTransform.a, childTransform.b, childTransform.c, childTransform.d, tx, ty);
}
context.drawImage(
texture.baseTexture.source,
frame.x,
frame.y,
frame.width,
frame.height,
((child.anchor.x) * (-frame.width) + 0.5) | 0,
((child.anchor.y) * (-frame.height) + 0.5) | 0,
frame.width,
frame.height);
}
}
};