RequestAnimationFrame done and optimised massively. PluginManager added (but needs testing). Game now fleshed out with all the state changing and core loop, also optimised heavily. Also Pixi integration started and the basics are working well :)

This commit is contained in:
Richard Davey 2013-08-29 03:52:59 +01:00
parent b8d3a61c97
commit 3c8cd20b70
9 changed files with 1076 additions and 44 deletions

View file

@ -3,13 +3,18 @@
<head>
<title>phaser.js - a(nother) new beginning</title>
<script src="../src/Phaser.js"></script>
<script src="../src/system/RequestAnimationFrame.js"></script>
<script src="../src/system/Device.js"></script>
<script src="../src/core/SignalBinding.js"></script>
<script src="../src/core/Signal.js"></script>
<script src="../src/math/RandomDataGenerator.js"></script>
<script src="../src/math/Math.js"></script>
<script src="../src/geom/Point.js"></script>
<script src="../src/geom/Circle.js"></script>
<script src="../src/net/Net.js"></script>
<script src="../src/tween/TweenManager.js"></script>
<script src="../src/tween/Tween.js"></script>
<script src="../src/tween/Easing.js"></script>
<script src="../src/time/Time.js"></script>
<script src="../src/animation/Animation.js"></script>
<script src="../src/animation/Frame.js"></script>
@ -25,14 +30,15 @@
var game = new Phaser.Game(this, '', 800, 600);
var data = Phaser.Math.sinCosGenerator(10);
var data = game.math.sinCosGenerator(10);
console.log('Sin', data.sin);
console.log('Cos', data.cos);
console.log('Shift value 1', Phaser.Math.shift(data.sin));
console.log('Shift value 2', Phaser.Math.shift(data.sin));
console.log('Shift value 3', Phaser.Math.shift(data.sin));
console.log('Shift value 1', game.math.shift(data.sin));
console.log('Shift value 2', game.math.shift(data.sin));
console.log('Shift value 3', game.math.shift(data.sin));
console.log('Shift value 4', game.math.shift(data.sin));
console.log('Sin', data.sin);

139
examples/pixi 1.html Normal file
View file

@ -0,0 +1,139 @@
<!DOCTYPE HTML>
<html>
<head>
<title>phaser.js - a(nother) new beginning</title>
<script src="../src/Phaser.js"></script>
<script src="../src/pixi/Pixi.js"></script>
<script src="../src/pixi/InteractionManager.js"></script>
<script src="../src/pixi/core/Circle.js"></script>
<script src="../src/pixi/core/Ellipse.js"></script>
<script src="../src/pixi/core/Matrix.js"></script>
<script src="../src/pixi/core/Point.js"></script>
<script src="../src/pixi/core/Polygon.js"></script>
<script src="../src/pixi/core/Rectangle.js"></script>
<script src="../src/pixi/display/DisplayObject.js"></script>
<script src="../src/pixi/display/DisplayObjectContainer.js"></script>
<script src="../src/pixi/display/Sprite.js"></script>
<script src="../src/pixi/display/MovieClip.js"></script>
<script src="../src/pixi/display/Stage.js"></script>
<script src="../src/pixi/extras/CustomRenderable.js"></script>
<script src="../src/pixi/extras/Strip.js"></script>
<script src="../src/pixi/extras/Rope.js"></script>
<script src="../src/pixi/extras/Spine.js"></script>
<script src="../src/pixi/extras/TilingSprite.js"></script>
<script src="../src/pixi/filters/FilterBlock.js"></script>
<script src="../src/pixi/filters/MaskFilter.js"></script>
<script src="../src/pixi/primitives/Graphics.js"></script>
<script src="../src/pixi/renderers/canvas/CanvasGraphics.js"></script>
<script src="../src/pixi/renderers/canvas/CanvasRenderer.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLBatch.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLGraphics.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLRenderer.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLRenderGroup.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLShaders.js"></script>
<script src="../src/pixi/text/BitmapText.js"></script>
<script src="../src/pixi/text/Text.js"></script>
<script src="../src/pixi/textures/BaseTexture.js"></script>
<script src="../src/pixi/textures/Texture.js"></script>
<script src="../src/pixi/textures/RenderTexture.js"></script>
<script src="../src/pixi/utils/Detector.js"></script>
<script src="../src/pixi/utils/EventTarget.js"></script>
<script src="../src/pixi/utils/Polyk.js"></script>
<script src="../src/pixi/utils/Utils.js"></script>
<script src="../src/system/RequestAnimationFrame.js"></script>
<script src="../src/system/Device.js"></script>
<script src="../src/core/SignalBinding.js"></script>
<script src="../src/core/Signal.js"></script>
<script src="../src/math/RandomDataGenerator.js"></script>
<script src="../src/math/Math.js"></script>
<script src="../src/geom/Point.js"></script>
<script src="../src/geom/Circle.js"></script>
<script src="../src/net/Net.js"></script>
<script src="../src/tween/TweenManager.js"></script>
<script src="../src/tween/Tween.js"></script>
<script src="../src/tween/Easing.js"></script>
<script src="../src/time/Time.js"></script>
<script src="../src/animation/Animation.js"></script>
<script src="../src/animation/Frame.js"></script>
<script src="../src/animation/FrameData.js"></script>
<script src="../src/animation/Parser.js"></script>
<script src="../src/loader/Cache.js"></script>
<script src="../src/loader/Loader.js"></script>
<script src="../src/Game.js"></script>
</head>
<body>
<script type="text/javascript">
var game = new Phaser.Game(this, '', 800, 600);
// PIXI it
var stage = new PIXI.Stage(0x000044);
var renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);
game.load.image('cockpit', 'assets/pics/cockpit.png');
game.load.image('rememberMe', 'assets/pics/remember-me.jpg');
game.load.image('overdose', 'assets/pics/lance-overdose-loader_eye.png');
game.load.onLoadStart.add(loadStarted, this);
game.load.onFileComplete.add(fileLoaded, this);
game.load.onLoadComplete.add(loadCompleted, this);
game.load.start();
function loadStarted(size) {
console.log('Loader started, queue size:', size);
}
// this.progress, previousKey, success, this.queueSize - this._keys.length, this.queueSize
function fileLoaded(progress, key, success, remaining, total) {
console.log('File Loaded:', key);
console.log('Progress: ' + progress + '%');
console.log('File: ' + remaining + ' out of ' + total);
}
var bunny;
function loadCompleted() {
console.log('Loader finished, creating base textures');
// Create a basetexture
var base = new PIXI.BaseTexture(game.cache.getImage('overdose'));
var texture = new PIXI.Texture(base);
bunny = new PIXI.Sprite(texture);
// center the sprites anchor point
bunny.anchor.x = 0.5;
bunny.anchor.y = 0.5;
// move the sprite t the center of the screen
bunny.position.x = 200;
bunny.position.y = 150;
stage.addChild(bunny);
requestAnimFrame(animate);
}
function animate() {
requestAnimFrame( animate );
// just for fun, lets rotate mr rabbit a little
bunny.rotation += 0.1;
bunny.scale.x += 0.01;
bunny.scale.y += 0.01;
// render the stage
renderer.render(stage);
}
</script>
</body>
</html>

45
examples/raf.html Normal file
View file

@ -0,0 +1,45 @@
<!DOCTYPE HTML>
<html>
<head>
<title>phaser.js - a(nother) new beginning</title>
<script src="../src/Phaser.js"></script>
<script src="../src/system/RequestAnimationFrame.js"></script>
<script src="../src/system/Device.js"></script>
<script src="../src/core/SignalBinding.js"></script>
<script src="../src/core/Signal.js"></script>
<script src="../src/math/RandomDataGenerator.js"></script>
<script src="../src/math/Math.js"></script>
<script src="../src/geom/Point.js"></script>
<script src="../src/geom/Circle.js"></script>
<script src="../src/net/Net.js"></script>
<script src="../src/tween/TweenManager.js"></script>
<script src="../src/tween/Tween.js"></script>
<script src="../src/tween/Easing.js"></script>
<script src="../src/time/Time.js"></script>
<script src="../src/animation/Animation.js"></script>
<script src="../src/animation/Frame.js"></script>
<script src="../src/animation/FrameData.js"></script>
<script src="../src/animation/Parser.js"></script>
<script src="../src/loader/Cache.js"></script>
<script src="../src/loader/Loader.js"></script>
<script src="../src/Game.js"></script>
</head>
<body>
<pre id="raf">?</pre>
<pre id="time">Game Time: </pre>
<script type="text/javascript">
var game = new Phaser.Game(this, '', 800, 600, null, null, update);
document.getElementById('raf').innerHTML = 'Browser using requestAnimationFrame: ' + game.raf.isRAF();
function update() {
document.getElementById('time').innerHTML = 'Game Time: ' + game.time.now;
}
</script>
</body>
</html>

View file

@ -3,9 +3,51 @@
<head>
<title>phaser.js - a(nother) new beginning</title>
<script src="../src/Phaser.js"></script>
<script src="../src/pixi/Pixi.js"></script>
<script src="../src/pixi/InteractionManager.js"></script>
<script src="../src/pixi/core/Circle.js"></script>
<script src="../src/pixi/core/Ellipse.js"></script>
<script src="../src/pixi/core/Matrix.js"></script>
<script src="../src/pixi/core/Point.js"></script>
<script src="../src/pixi/core/Polygon.js"></script>
<script src="../src/pixi/core/Rectangle.js"></script>
<script src="../src/pixi/display/DisplayObject.js"></script>
<script src="../src/pixi/display/DisplayObjectContainer.js"></script>
<script src="../src/pixi/display/Sprite.js"></script>
<script src="../src/pixi/display/MovieClip.js"></script>
<script src="../src/pixi/display/Stage.js"></script>
<script src="../src/pixi/extras/CustomRenderable.js"></script>
<script src="../src/pixi/extras/Strip.js"></script>
<script src="../src/pixi/extras/Rope.js"></script>
<script src="../src/pixi/extras/Spine.js"></script>
<script src="../src/pixi/extras/TilingSprite.js"></script>
<script src="../src/pixi/filters/FilterBlock.js"></script>
<script src="../src/pixi/filters/MaskFilter.js"></script>
<script src="../src/pixi/primitives/Graphics.js"></script>
<script src="../src/pixi/renderers/canvas/CanvasGraphics.js"></script>
<script src="../src/pixi/renderers/canvas/CanvasRenderer.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLBatch.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLGraphics.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLRenderer.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLRenderGroup.js"></script>
<script src="../src/pixi/renderers/webgl/WebGLShaders.js"></script>
<script src="../src/pixi/text/BitmapText.js"></script>
<script src="../src/pixi/text/Text.js"></script>
<script src="../src/pixi/textures/BaseTexture.js"></script>
<script src="../src/pixi/textures/Texture.js"></script>
<script src="../src/pixi/textures/RenderTexture.js"></script>
<script src="../src/pixi/utils/Detector.js"></script>
<script src="../src/pixi/utils/EventTarget.js"></script>
<script src="../src/pixi/utils/Polyk.js"></script>
<script src="../src/pixi/utils/Utils.js"></script>
<script src="../src/system/RequestAnimationFrame.js"></script>
<script src="../src/system/Device.js"></script>
<script src="../src/core/SignalBinding.js"></script>
<script src="../src/core/Signal.js"></script>
<script src="../src/core/PluginManager.js"></script>
<script src="../src/core/Plugin.js"></script>
<script src="../src/math/RandomDataGenerator.js"></script>
<script src="../src/math/Math.js"></script>
<script src="../src/geom/Point.js"></script>
@ -29,17 +71,70 @@
var game = new Phaser.Game(this, '', 800, 600);
var test = { x: 0 };
// PIXI it
var stage = new PIXI.Stage(0x000044);
var renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);
var tween = game.tweens.create(test);
game.load.image('cockpit', 'assets/pics/cockpit.png');
game.load.image('rememberMe', 'assets/pics/remember-me.jpg');
game.load.image('overdose', 'assets/pics/lance-overdose-loader_eye.png');
tween.onComplete.add(onComplete, this);
tween.to({x: 100}, 1000, Phaser.Easing.Linear.None, true);
game.load.onLoadStart.add(loadStarted, this);
game.load.onFileComplete.add(fileLoaded, this);
game.load.onLoadComplete.add(loadCompleted, this);
function onComplete() {
console.log('tween finished, new data: ', test);
game.load.start();
function loadStarted(size) {
console.log('Loader started, queue size:', size);
}
// this.progress, previousKey, success, this.queueSize - this._keys.length, this.queueSize
function fileLoaded(progress, key, success, remaining, total) {
console.log('File Loaded:', key);
console.log('Progress: ' + progress + '%');
console.log('File: ' + remaining + ' out of ' + total);
}
var bunny;
function loadCompleted() {
console.log('Loader finished, creating base textures');
// Create a basetexture
var base = new PIXI.BaseTexture(game.cache.getImage('overdose'));
var texture = new PIXI.Texture(base);
bunny = new PIXI.Sprite(texture);
// center the sprites anchor point
bunny.anchor.x = 0.5;
bunny.anchor.y = 0.5;
// move the sprite t the center of the screen
bunny.position.x = 200;
bunny.position.y = 150;
stage.addChild(bunny);
requestAnimFrame(animate);
}
function animate() {
requestAnimFrame( animate );
// just for fun, lets rotate mr rabbit a little
bunny.rotation += 0.1;
bunny.scale.x += 0.01;
bunny.scale.y += 0.01;
// render the stage
renderer.render(stage);
}
</script>
</body>

View file

@ -33,18 +33,14 @@ Phaser.Game = function (callbackContext, parent, width, height, preloadCallback,
this.onRenderCallback = renderCallback;
this.onDestroyCallback = destroyCallback;
var _this = this;
if (document.readyState === 'complete' || document.readyState === 'interactive')
{
setTimeout(function () {
return Phaser.GAMES[_this.id].boot(parent, width, height);
});
setTimeout(Phaser.GAMES[this.id].boot(parent, width, height), 0);
}
else
{
document.addEventListener('DOMContentLoaded', Phaser.GAMES[_this.id].boot(parent, width, height), false);
window.addEventListener('load', Phaser.GAMES[_this.id].boot(parent, width, height), false);
document.addEventListener('DOMContentLoaded', Phaser.GAMES[this.id].boot(parent, width, height), false);
window.addEventListener('load', Phaser.GAMES[this.id].boot(parent, width, height), false);
}
};
@ -147,6 +143,95 @@ Phaser.Game.prototype = {
*/
isRunning: false,
/**
* Automatically handles the core game loop via requestAnimationFrame or setTimeout
*/
raf: null,
/**
* Reference to the GameObject Factory.
* @type {Phaser.GameObjectFactory}
*/
add: null,
/**
* Reference to the assets cache.
* @type {Phaser.Cache}
*/
cache: null,
/**
* Reference to the input manager
* @type {Phaser.InputManager}
*/
input: null,
/**
* Reference to the assets loader.
* @type {Phaser.Loader}
*/
load: null,
/**
* Reference to the math helper.
* @type {Phaser.GameMath}
*/
math: null,
/**
* Reference to the network class.
* @type {Phaser.Net}
*/
net: null,
/**
* Reference to the sound manager.
* @type {Phaser.SoundManager}
*/
sound: null,
/**
* Reference to the stage.
* @type {Phaser.Stage}
*/
stage: null,
/**
* Reference to game clock.
* @type {Phaser.TimeManager}
*/
time: null,
/**
* Reference to the tween manager.
* @type {Phaser.TweenManager}
*/
tweens: null,
/**
* Reference to the world.
* @type {Phaser.World}
*/
world: null,
/**
* Reference to the physics manager.
* @type {Phaser.Physics.PhysicsManager}
*/
physics: null,
/**
* Instance of repeatable random data generator helper.
* @type {Phaser.RandomDataGenerator}
*/
rnd: null,
/**
* Contains device information and capabilities.
* @type {Phaser.Device}
*/
device: null,
/**
* Initialize engine sub modules and start the game.
* @param parent {string} ID of parent Dom element.
@ -155,29 +240,24 @@ Phaser.Game.prototype = {
*/
boot: function (parent, width, height) {
var _this = this;
if (this.isBooted) {
return;
}
if (!document.body) {
setTimeout(function () {
return Phaser.GAMES[_this.id].boot(parent, width, height);
}, 13);
setTimeout(Phaser.GAMES[this.id].boot(parent, width, height), 13);
}
else
{
document.removeEventListener('DOMContentLoaded', Phaser.GAMES[_this.id].boot);
window.removeEventListener('load', Phaser.GAMES[_this.id].boot);
document.removeEventListener('DOMContentLoaded', Phaser.GAMES[this.id].boot);
window.removeEventListener('load', Phaser.GAMES[this.id].boot);
console.log('Phaser', Phaser.VERSION, 'alive');
this.onPause = new Phaser.Signal();
this.onResume = new Phaser.Signal();
// this.onPause = new Phaser.Signal();
// this.onResume = new Phaser.Signal();
this.device = new Phaser.Device();
this.net = new Phaser.Net(this);
// this.math = new Phaser.GameMath(this);
this.math = Phaser.Math;
// this.stage = new Phaser.Stage(this, parent, width, height);
// this.world = new Phaser.World(this, width, height);
// this.add = new Phaser.GameObjectFactory(this);
@ -189,16 +269,275 @@ Phaser.Game.prototype = {
// this.sound = new Phaser.SoundManager(this);
this.rnd = new Phaser.RandomDataGenerator([(Date.now() * Math.random()).toString()]);
// this.physics = new Phaser.Physics.PhysicsManager(this);
// this.plugins = new Phaser.PluginManager(this, this);
// this.load.onLoadComplete.add(this.loadComplete, this);
this.plugins = new Phaser.PluginManager(this, this);
this.load.onLoadComplete.add(this.loadComplete, this);
// this.setRenderer(Phaser.Types.RENDERER_CANVAS);
// this.world.boot();
// this.stage.boot();
// this.input.boot();
this.isBooted = true;
if (this.onPreloadCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null) {
console.warn("Phaser update loop cannot start: No preload, create, update or render functions given and no pending State found");
}
else
{
console.log('Phaser', Phaser.VERSION, 'alive');
this.isRunning = true;
this._loadComplete = false;
this.raf = new Phaser.RequestAnimationFrame(this);
this.raf.start();
if (this._pendingState)
{
this.switchState(this._pendingState, false, false);
}
else
{
this.startState();
}
}
}
},
/**
* Called when the load has finished after preload was run.
*/
loadComplete: function () {
this._loadComplete = true;
this.onCreateCallback.call(this.callbackContext);
},
/**
* Start the current state
*/
startState: function () {
if (this.onPreloadCallback !== null)
{
this.load.reset();
this.onPreloadCallback.call(this.callbackContext);
// Is the loader empty?
if (this.load.queueSize == 0)
{
if (this.onCreateCallback !== null)
{
this.onCreateCallback.call(this.callbackContext);
}
this._loadComplete = true;
}
else
{
// Start the loader going as we have something in the queue
this.load.onLoadComplete.add(this.loadComplete, this);
this.load.start();
}
}
else
{
// No init? Then there was nothing to load either
if (this.onCreateCallback !== null) {
this.onCreateCallback.call(this.callbackContext);
}
this._loadComplete = true;
}
},
/**
* Set the most common state callbacks (init, create, update, render).
* @param preloadCallback {function} Init callback invoked when init state.
* @param createCallback {function} Create callback invoked when create state.
* @param updateCallback {function} Update callback invoked when update state.
* @param renderCallback {function} Render callback invoked when render state.
* @param destroyCallback {function} Destroy callback invoked when state is destroyed.
*/
setCallbacks: function (preloadCallback, createCallback, updateCallback, renderCallback, destroyCallback) {
if (typeof preloadCallback === "undefined") { preloadCallback = null; }
if (typeof createCallback === "undefined") { createCallback = null; }
if (typeof updateCallback === "undefined") { updateCallback = null; }
if (typeof renderCallback === "undefined") { renderCallback = null; }
if (typeof destroyCallback === "undefined") { destroyCallback = null; }
this.onPreloadCallback = preloadCallback;
this.onCreateCallback = createCallback;
this.onUpdateCallback = updateCallback;
this.onRenderCallback = renderCallback;
this.onDestroyCallback = destroyCallback;
},
update: function (time) {
this.time.update(time);
this.plugins.preUpdate();
this.tweens.update();
this.input.update();
this.stage.update();
this.sound.update();
this.physics.update();
this.world.update();
this.plugins.update();
if (this._loadComplete)
{
if (this.onUpdateCallback)
{
this.onUpdateCallback.call(this.callbackContext);
}
this.world.postUpdate();
this.plugins.postUpdate();
this.plugins.preRender();
if (this.onPreRenderCallback)
{
this.onPreRenderCallback.call(this.callbackContext);
}
this.renderer.render();
this.plugins.render();
if (this.onRenderCallback)
{
this.onRenderCallback.call(this.callbackContext);
}
this.plugins.postRender();
}
else
{
// Still loading assets
if (this.onLoadUpdateCallback)
{
this.onLoadUpdateCallback.call(this.callbackContext);
}
this.world.postUpdate();
this.plugins.postUpdate();
this.plugins.preRender();
this.renderer.render();
this.plugins.render();
if (this.onLoadRenderCallback)
{
this.onLoadRenderCallback.call(this.callbackContext);
}
this.plugins.postRender();
}
},
/**
* Switch to a new State.
* @param state {State} The state you want to switch to.
* @param [clearWorld] {bool} clear everything in the world? (Default to true)
* @param [clearCache] {bool} clear asset cache? (Default to false and ONLY available when clearWorld=true)
*/
switchState: function (state, clearWorld, clearCache) {
if (typeof clearWorld === "undefined") { clearWorld = true; }
if (typeof clearCache === "undefined") { clearCache = false; }
if (this.isBooted == false) {
this._pendingState = state;
return;
}
// Destroy current state?
if (this.onDestroyCallback !== null) {
this.onDestroyCallback.call(this.callbackContext);
}
this.input.reset(true);
// Prototype?
if (typeof state === 'function')
{
this.state = new state(this);
}
else
{
this.state = state;
}
// Ok, have we got at least a create or update function?
if (this.state['create'] || this.state['update']) {
this.callbackContext = this.state;
// Bingo, let's set them up
this.onPreloadCallback = this.state['preload'] || null;
this.onLoadRenderCallback = this.state['loadRender'] || null;
this.onLoadUpdateCallback = this.state['loadUpdate'] || null;
this.onCreateCallback = this.state['create'] || null;
this.onUpdateCallback = this.state['update'] || null;
this.onPreRenderCallback = this.state['preRender'] || null;
this.onRenderCallback = this.state['render'] || null;
this.onPausedCallback = this.state['paused'] || null;
this.onDestroyCallback = this.state['destroy'] || null;
if (clearWorld) {
//this.world.destroy();
if (clearCache == true) {
this.cache.destroy();
}
}
this._loadComplete = false;
this.startState();
}
else
{
console.warn("Invalid Phaser State object given. Must contain at least a create or update function.");
}
},
/**
* Nuke the entire game from orbit
*/
destroy: function () {
this.callbackContext = null;
this.onPreloadCallback = null;
this.onLoadRenderCallback = null;
this.onLoadUpdateCallback = null;
this.onCreateCallback = null;
this.onUpdateCallback = null;
this.onRenderCallback = null;
this.onPausedCallback = null;
this.onDestroyCallback = null;
this.cache = null;
this.input = null;
this.load = null;
this.sound = null;
this.stage = null;
this.time = null;
this.world = null;
this.isBooted = false;
}
};

79
src/core/Plugin.js Normal file
View file

@ -0,0 +1,79 @@
/**
* Phaser - Plugin
*
* This is a base Plugin template to use for any Phaser plugin development
*/
Phaser.Plugin = function (game, parent) {
this.game = game;
this.parent = parent;
this.active = false;
this.visible = false;
this.hasPreUpdate = false;
this.hasUpdate = false;
this.hasPostUpdate = false;
this.hasPreRender = false;
this.hasRender = false;
this.hasPostRender = false;
};
Phaser.Plugin.prototype = {,
/**
* Pre-update is called at the start of the update cycle, before any other updates have taken place.
* It is only called if active is set to true.
*/
preUpdate: function () {
},
/**
* Pre-update is called at the start of the update cycle, before any other updates have taken place.
* It is only called if active is set to true.
*/
update: function () {
},
/**
* Post-update is called at the end of the objects update cycle, after other update logic has taken place.
* It is only called if active is set to true.
*/
postUpdate: function () {
},
/**
* Pre-render is called right before the Game Renderer starts and before any custom preRender callbacks have been run.
* It is only called if visible is set to true.
*/
preRender: function () {
},
/**
* Pre-render is called right before the Game Renderer starts and before any custom preRender callbacks have been run.
* It is only called if visible is set to true.
*/
render: function () {
},
/**
* Post-render is called after every camera and game object has been rendered, also after any custom postRender callbacks have been run.
* It is only called if visible is set to true.
*/
postRender: function () {
},
/**
* Clear down this Plugin and null out references
*/
destroy: function () {
this.game = null;
this.parent = null;
this.active = false;
this.visible = false;
}
};

199
src/core/PluginManager.js Normal file
View file

@ -0,0 +1,199 @@
/**
* Phaser - PluginManager
*
* TODO: We can optimise this a lot by using separate hashes per function (update, render, etc)
*/
Phaser.PluginManager = function(game, parent) {
this.game = game;
this._parent = parent;
this.plugins = [];
this._pluginsLength = 0;
};
Phaser.PluginManager.prototype = {,
/**
* Add a new Plugin to the PluginManager.
* The plugins game and parent reference are set to this game and pluginmanager parent.
* @type {Phaser.Plugin}
*/
add: function (plugin) {
var result = false;
// Prototype?
if (typeof plugin === 'function')
{
plugin = new plugin(this.game, this._parent);
}
else
{
plugin.game = this.game;
plugin.parent = this._parent;
}
// Check for methods now to avoid having to do this every loop
if (typeof plugin['preUpdate'] === 'function') {
plugin.hasPreUpdate = true;
result = true;
}
if (typeof plugin['update'] === 'function') {
plugin.hasUpdate = true;
result = true;
}
if (typeof plugin['postUpdate'] === 'function') {
plugin.hasPostUpdate = true;
result = true;
}
if (typeof plugin['preRender'] === 'function') {
plugin.hasPreRender = true;
result = true;
}
if (typeof plugin['render'] === 'function') {
plugin.hasRender = true;
result = true;
}
if (typeof plugin['postRender'] === 'function') {
plugin.hasPostRender = true;
result = true;
}
// The plugin must have at least one of the above functions to be added to the PluginManager.
if (result) {
if (plugin.hasPreUpdate || plugin.hasUpdate || plugin.hasPostUpdate)
{
plugin.active = true;
}
if (plugin.hasPreRender || plugin.hasRender || plugin.hasPostRender)
{
plugin.visible = true;
}
this._pluginsLength = this.plugins.push(plugin);
return plugin;
}
else
{
return null;
}
},
remove: function (plugin) {
// TODO
this._pluginsLength--;
},
preUpdate: function () {
if (this._pluginsLength == 0)
{
return;
}
for (this._p = 0; this._p < this._pluginsLength; this._p++) {
if (this.plugins[this._p].active && this.plugins[this._p].hasPreUpdate) {
this.plugins[this._p].preUpdate();
}
}
},
update: function () {
if (this._pluginsLength == 0)
{
return;
}
for (this._p = 0; this._p < this._pluginsLength; this._p++) {
if (this.plugins[this._p].active && this.plugins[this._p].hasUpdate) {
this.plugins[this._p].update();
}
}
},
postUpdate: function () {
if (this._pluginsLength == 0)
{
return;
}
for (this._p = 0; this._p < this._pluginsLength; this._p++) {
if (this.plugins[this._p].active && this.plugins[this._p].hasPostUpdate) {
this.plugins[this._p].postUpdate();
}
}
},
preRender: function () {
if (this._pluginsLength == 0)
{
return;
}
for (this._p = 0; this._p < this._pluginsLength; this._p++) {
if (this.plugins[this._p].visible && this.plugins[this._p].hasPreRender) {
this.plugins[this._p].preRender();
}
}
},
render: function () {
if (this._pluginsLength == 0)
{
return;
}
for (this._p = 0; this._p < this._pluginsLength; this._p++) {
if (this.plugins[this._p].visible && this.plugins[this._p].hasRender) {
this.plugins[this._p].render();
}
}
},
postRender: function () {
if (this._pluginsLength == 0)
{
return;
}
for (this._p = 0; this._p < this._pluginsLength; this._p++) {
if (this.plugins[this._p].visible && this.plugins[this._p].hasPostRender) {
this.plugins[this._p].postRender();
}
}
},
destroy: function () {
this.plugins.length = 0;
this._pluginsLength = 0;
this.game = null;
this._parent = null;
}
};

View file

@ -0,0 +1,111 @@
/**
* Phaser - RequestAnimationFrame
*
* Abstracts away the use of RAF or setTimeOut for the core game update loop.
*/
Phaser.RequestAnimationFrame = function(game) {
this.game = game;
this._isSetTimeOut = false;
this.isRunning = false;
var vendors = [
'ms',
'moz',
'webkit',
'o'
];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'];
}
};
Phaser.RequestAnimationFrame.prototype = {
/**
* Starts the requestAnimatioFrame running or setTimeout if unavailable in browser
* @method start
**/
start: function () {
this.isRunning = true;
if (!window.requestAnimationFrame)
{
this._isSetTimeOut = true;
this._timeOutID = window.setTimeout(Phaser.GAMES[this.game.id].raf.updateSetTimeout, 0);
}
else
{
this._isSetTimeOut = false;
window.requestAnimationFrame(Phaser.GAMES[this.game.id].raf.updateRAF);
}
},
/**
* The update method for the requestAnimationFrame
* @method RAFUpdate
**/
updateRAF: function (time) {
this.game.update(time);
window.requestAnimationFrame(Phaser.GAMES[this.game.id].raf.updateRAF);
},
/**
* The update method for the setTimeout
* @method SetTimeoutUpdate
**/
updateSetTimeout: function () {
this.game.update(Date.now());
this._timeOutID = window.setTimeout(Phaser.GAMES[this.game.id].raf.updateSetTimeout, this.game.time.timeToCall);
},
/**
* Stops the requestAnimationFrame from running
* @method stop
**/
stop: function () {
if (this._isSetTimeOut)
{
clearTimeout(this._timeOutID);
}
else
{
window.cancelAnimationFrame;
}
this.isRunning = false;
},
/**
* Is the browser using setTimeout?
* @method isSetTimeOut
* @return bool
**/
isSetTimeOut: function () {
return this._isSetTimeOut;
},
/**
* Is the browser using requestAnimationFrame?
* @method isRAF
* @return bool
**/
isRAF: function () {
return (this._isSetTimeOut === false);
}
};

View file

@ -6,7 +6,7 @@
*/
/**
* This is the core internal game clock. It manages the elapsed time and calculation of delta values,
* This is the core internal game clock. It manages the elapsed time and calculation of elapsed values,
* used for game object motion and tweens.
*
* @class Time
@ -89,11 +89,11 @@ Phaser.Time.prototype = {
/**
* Elapsed time since the last frame.
* @property delta
* @property elapsed
* @public
* @type {Number}
*/
delta: 0,
elapsed: 0,
/**
* Frames per second.
@ -151,6 +151,22 @@ Phaser.Time.prototype = {
*/
pauseDuration: 0,
/**
* The value that setTimeout needs to work out when to next update
* @property timeToCall
* @public
* @type {Number}
*/
timeToCall: 0,
/**
* Internal value used by timeToCall as part of the setTimeout loop
* @property lastTime
* @public
* @type {Number}
*/
lastTime: 0,
/**
* The number of seconds that have elapsed since the game was started.
* @method totalElapsedSeconds
@ -161,18 +177,20 @@ Phaser.Time.prototype = {
},
/**
* Update clock and calculate the fps.
* This is called automatically by Game._raf
* Updates the game clock and calculate the fps.
* This is called automatically by Phaser.Game
* @method update
* @param {Number} raf The current timestamp, either performance.now or Date.now
* @param {Number} time The current timestamp, either performance.now or Date.now depending on the browser
*/
update: function (raf) {
update: function (time) {
this.now = raf;
this.delta = this.now - this.time;
this.now = time;
this.timeToCall = Math.max(0, 16 - (time - this.lastTime));
this.msMin = Math.min(this.msMin, this.delta);
this.msMax = Math.max(this.msMax, this.delta);
this.elapsed = this.now - this.time;
this.msMin = Math.min(this.msMin, this.elapsed);
this.msMax = Math.max(this.msMax, this.elapsed);
this.frames++;
@ -186,7 +204,8 @@ Phaser.Time.prototype = {
}
this.time = this.now;
this.physicsElapsed = 1.0 * (this.delta / 1000);
this.lastTime = time + this.timeToCall;
this.physicsElapsed = 1.0 * (this.elapsed / 1000);
// Paused?
if (this.game.paused) {
@ -211,8 +230,8 @@ Phaser.Time.prototype = {
*/
gameResumed: function () {
// Level out the delta timer to avoid spikes
this.delta = 0;
// Level out the elapsed timer to avoid spikes
this.elapsed = 0;
this.physicsElapsed = 0;
this.time = Date.now();
this.pauseDuration = this.pausedTime;