mirror of
https://github.com/photonstorm/phaser
synced 2025-02-17 14:38:30 +00:00
Updating the StateManager so it supports renderToTexture and advanced State configs.
This commit is contained in:
parent
8a1dc20211
commit
2510bee27c
6 changed files with 193 additions and 153 deletions
|
@ -79,7 +79,7 @@ var CreateRenderer = function (game)
|
|||
else
|
||||
{
|
||||
game.renderer = new CanvasRenderer(game);
|
||||
game.context = game.renderer.context;
|
||||
game.context = game.renderer.gameContext;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ BaseLoader.prototype = {
|
|||
|
||||
start: function ()
|
||||
{
|
||||
console.log('BaseLoader start. Files to load:', this.list.size);
|
||||
console.log(this.state.settings.key, 'BaseLoader start. Files to load:', this.list.size);
|
||||
|
||||
if (!this.isReady())
|
||||
{
|
||||
|
@ -247,7 +247,7 @@ BaseLoader.prototype = {
|
|||
|
||||
processComplete: function ()
|
||||
{
|
||||
console.log('Loader Complete. Loaded:', this.storage.size, 'Failed:', this.failed.size);
|
||||
console.log(this.state.settings.key, 'Loader Complete. Loaded:', this.storage.size, 'Failed:', this.failed.size);
|
||||
|
||||
this.list.clear();
|
||||
this.inflight.clear();
|
||||
|
|
|
@ -2,45 +2,43 @@ var CONST = require('../../const');
|
|||
var DrawImage = require('./utils/DrawImage');
|
||||
var BlitImage = require('./utils/BlitImage');
|
||||
var GetBlendModes = require('./utils/GetBlendModes');
|
||||
var GetContext = require('../../canvas/GetContext');
|
||||
|
||||
var CanvasRenderer = function (game)
|
||||
{
|
||||
/**
|
||||
* @property {Phaser.Game} game - A reference to the currently running Game.
|
||||
*/
|
||||
// Needed?
|
||||
this.game = game;
|
||||
|
||||
// Needed?
|
||||
this.type = CONST.CANVAS;
|
||||
|
||||
// Read all the following from game config (or State config?)
|
||||
this.clearBeforeRender = true;
|
||||
|
||||
this.transparent = false;
|
||||
|
||||
this.autoResize = false;
|
||||
|
||||
this.drawCount = 0;
|
||||
|
||||
// Read all the following from game config (or State config?)
|
||||
// this.clearBeforeRender = true;
|
||||
// this.transparent = false;
|
||||
// this.autoResize = false;
|
||||
// this.smoothProperty = Phaser.Canvas.getSmoothingPrefix(this.context);
|
||||
|
||||
this.roundPixels = false;
|
||||
// this.roundPixels = false;
|
||||
|
||||
this.width = game.config.width * game.config.resolution;
|
||||
|
||||
this.height = game.config.height * game.config.resolution;
|
||||
|
||||
this.resolution = game.config.resolution;
|
||||
|
||||
this.view = game.canvas;
|
||||
this.gameCanvas = game.canvas;
|
||||
|
||||
/**
|
||||
* The canvas 2d context that everything is drawn with
|
||||
* @property context
|
||||
* @type CanvasRenderingContext2D
|
||||
*/
|
||||
this.context = this.view.getContext('2d', { alpha: true });
|
||||
this.gameContext = GetContext(this.gameCanvas);
|
||||
|
||||
this.gameConfig = game.config;
|
||||
|
||||
this.currentContext = this.gameContext;
|
||||
|
||||
// Map to the required function
|
||||
this.drawImage = DrawImage;
|
||||
|
@ -73,31 +71,85 @@ CanvasRenderer.prototype = {
|
|||
this.width = width * res;
|
||||
this.height = height * res;
|
||||
|
||||
this.view.width = this.width;
|
||||
this.view.height = this.height;
|
||||
this.gameCanvas.width = this.width;
|
||||
this.gameCanvas.height = this.height;
|
||||
|
||||
if (this.autoResize)
|
||||
{
|
||||
this.view.style.width = (this.width / res) + 'px';
|
||||
this.view.style.height = (this.height / res) + 'px';
|
||||
this.gameCanvas.style.width = (this.width / res) + 'px';
|
||||
this.gameCanvas.style.height = (this.height / res) + 'px';
|
||||
}
|
||||
|
||||
// if (this.smoothProperty)
|
||||
// {
|
||||
// this.context[this.smoothProperty] = (this.scaleMode === ScaleModes.LINEAR);
|
||||
// this.gameContext[this.smoothProperty] = (this.scaleMode === ScaleModes.LINEAR);
|
||||
// }
|
||||
},
|
||||
|
||||
resetTransform: function ()
|
||||
{
|
||||
this.currentContext.setTransform(1, 0, 0, 1, 0, 0);
|
||||
},
|
||||
|
||||
setBlendMode: function (blendMode)
|
||||
{
|
||||
if (this.currentBlendMode !== blendMode)
|
||||
{
|
||||
this.currentContext.globalCompositeOperation = blendMode;
|
||||
this.currentBlendMode = blendMode;
|
||||
}
|
||||
},
|
||||
|
||||
setAlpha: function (alpha)
|
||||
{
|
||||
if (this.currentAlpha !== alpha)
|
||||
{
|
||||
this.currentContext.globalAlpha = alpha;
|
||||
this.currentAlpha = alpha;
|
||||
}
|
||||
},
|
||||
|
||||
// Call at the start of the render loop
|
||||
preRender: function ()
|
||||
{
|
||||
// console.log('%c render start ', 'color: #ffffff; background: #00ff00;');
|
||||
|
||||
var ctx = this.gameContext;
|
||||
var config = this.gameConfig;
|
||||
|
||||
if (config.clearBeforeRender)
|
||||
{
|
||||
ctx.clearRect(0, 0, this.width, this.height);
|
||||
}
|
||||
|
||||
if (!config.transparent)
|
||||
{
|
||||
ctx.fillStyle = config.backgroundColor;
|
||||
ctx.fillRect(0, 0, this.width, this.height);
|
||||
}
|
||||
|
||||
// Add Pre-render hook
|
||||
|
||||
this.drawCount = 0;
|
||||
},
|
||||
|
||||
var ctx = this.context;
|
||||
/**
|
||||
* Renders the State.
|
||||
*
|
||||
* @method render
|
||||
* @param {Phaser.State} state - The State to be rendered.
|
||||
* @param {number} interpolationPercentage - The cumulative amount of time that hasn't been simulated yet, divided
|
||||
* by the amount of time that will be simulated the next time update()
|
||||
* runs. Useful for interpolating frames.
|
||||
*/
|
||||
render: function (state, list, interpolationPercentage)
|
||||
{
|
||||
var w = state.sys.width;
|
||||
var h = state.sys.height;
|
||||
var ctx = state.sys.context;
|
||||
var settings = state.sys.settings;
|
||||
|
||||
this.currentContext = ctx;
|
||||
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
|
||||
|
@ -117,53 +169,21 @@ CanvasRenderer.prototype = {
|
|||
|
||||
this.currentScaleMode = 0;
|
||||
|
||||
if (this.clearBeforeRender)
|
||||
if (settings.renderToTexture)
|
||||
{
|
||||
ctx.clearRect(0, 0, this.width, this.height);
|
||||
if (settings.clearBeforeRender)
|
||||
{
|
||||
ctx.clearRect(0, 0, w, h);
|
||||
}
|
||||
|
||||
if (settings.backgroundColor)
|
||||
{
|
||||
ctx.fillStyle = settings.backgroundColor;
|
||||
ctx.fillRect(0, 0, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
// TEMP
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.fillRect(0, 0, this.width, this.height);
|
||||
},
|
||||
|
||||
resetTransform: function ()
|
||||
{
|
||||
this.context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
},
|
||||
|
||||
setBlendMode: function (blendMode)
|
||||
{
|
||||
if (this.currentBlendMode !== blendMode)
|
||||
{
|
||||
this.context.globalCompositeOperation = blendMode;
|
||||
this.currentBlendMode = blendMode;
|
||||
}
|
||||
},
|
||||
|
||||
setAlpha: function (alpha)
|
||||
{
|
||||
if (this.currentAlpha !== alpha)
|
||||
{
|
||||
this.context.globalAlpha = alpha;
|
||||
this.currentAlpha = alpha;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders the State.
|
||||
*
|
||||
* @method render
|
||||
* @param {Phaser.State} state - The State to be rendered.
|
||||
* @param {number} interpolationPercentage - The cumulative amount of time that hasn't been simulated yet, divided
|
||||
* by the amount of time that will be simulated the next time update()
|
||||
* runs. Useful for interpolating frames.
|
||||
*/
|
||||
render: function (state, list, interpolationPercentage)
|
||||
{
|
||||
this.drawCount = list.length;
|
||||
|
||||
// console.log(this.drawCount);
|
||||
this.drawCount += list.length;
|
||||
|
||||
for (var c = 0; c < list.length; c++)
|
||||
{
|
||||
|
@ -173,7 +193,16 @@ CanvasRenderer.prototype = {
|
|||
}
|
||||
|
||||
// Reset the transform so going into the devs render function the context is ready for use
|
||||
this.context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
|
||||
// Call the State.render function
|
||||
state.render(ctx, interpolationPercentage);
|
||||
|
||||
// Blast it to the Game Canvas (if needed)
|
||||
if (settings.renderToTexture)
|
||||
{
|
||||
this.gameContext.drawImage(state.sys.canvas, 0, 0, w, h, settings.x, settings.y, w, h);
|
||||
}
|
||||
},
|
||||
|
||||
postRender: function ()
|
||||
|
@ -187,14 +216,14 @@ CanvasRenderer.prototype = {
|
|||
* Removes everything from the renderer and optionally removes the Canvas DOM element.
|
||||
*
|
||||
* @method destroy
|
||||
* @param [removeView=true] {boolean} Removes the Canvas element from the DOM.
|
||||
* @param [removegameCanvas=true] {boolean} Removes the Canvas element from the DOM.
|
||||
*/
|
||||
destroy: function ()
|
||||
{
|
||||
// CanvasPool
|
||||
|
||||
this.view = null;
|
||||
this.context = null;
|
||||
this.gameCanvas = null;
|
||||
this.gameContext = null;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -25,26 +25,33 @@ var Settings = {
|
|||
key: GetObjectValue(config, 'key', ''),
|
||||
active: GetObjectValue(config, 'active', false),
|
||||
visible: GetObjectValue(config, 'visible', true),
|
||||
scaleMode: GetObjectValue(config, 'scaleMode', ScaleModes.DEFAULT),
|
||||
|
||||
// Loader payload array
|
||||
|
||||
files: GetObjectValue(config, 'files', false),
|
||||
|
||||
// -1 means the State Manager will set it to be the Game dimensions
|
||||
|
||||
x: GetObjectValue(config, 'x', 0),
|
||||
y: GetObjectValue(config, 'y', 0),
|
||||
rotation: GetObjectValue(config, 'rotation', 0),
|
||||
width: GetObjectValue(config, 'width', -1),
|
||||
height: GetObjectValue(config, 'height', -1),
|
||||
|
||||
// Renderer Settings
|
||||
// State Render Settings (applies only to this State)
|
||||
|
||||
clearBeforeRender: GetObjectValue(config, 'clearBeforeRender', true),
|
||||
transparent: GetObjectValue(config, 'transparent', false),
|
||||
autoResize: GetObjectValue(config, 'autoResize', false),
|
||||
scaleMode: GetObjectValue(config, 'scaleMode', ScaleModes.DEFAULT),
|
||||
roundPixels: GetObjectValue(config, 'roundPixels', false),
|
||||
drawToPrimaryCanvas: GetObjectValue(config, 'drawToPrimaryCanvas', false),
|
||||
|
||||
// Loader payload array
|
||||
dirtyRender: GetObjectValue(config, 'dirtyRender', false),
|
||||
renderToTexture: GetObjectValue(config, 'renderToTexture', false),
|
||||
|
||||
files: GetObjectValue(config, 'files', false)
|
||||
// The following only apply if renderToTexture is true
|
||||
|
||||
autoResize: GetObjectValue(config, 'autoResize', false),
|
||||
transparent: GetObjectValue(config, 'transparent', false),
|
||||
clearBeforeRender: GetObjectValue(config, 'clearBeforeRender', true),
|
||||
backgroundColor: GetObjectValue(config, 'backgroundColor', false)
|
||||
|
||||
};
|
||||
},
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
var CONST = require('../const');
|
||||
var NOOP = require('../utils/NOOP');
|
||||
var State = require('./State');
|
||||
var Settings = require('./Settings');
|
||||
var Systems = require('./Systems');
|
||||
var GetObjectValue = require('../utils/object/GetObjectValue');
|
||||
var EventDispatcher = require('../events/EventDispatcher');
|
||||
var Rectangle = require('../geom/rectangle/Rectangle');
|
||||
var CanvasPool = require('../dom/CanvasPool');
|
||||
var CanvasInterpolation = require('../dom/CanvasInterpolation');
|
||||
var GetContext = require('../canvas/GetContext');
|
||||
|
||||
/**
|
||||
* The State Manager is responsible for loading, setting up and switching game states.
|
||||
|
@ -132,25 +135,25 @@ StateManager.prototype = {
|
|||
autoStart: autoStart
|
||||
});
|
||||
|
||||
// console.log('StateManager not yet booted, adding to list', this._pending.length);
|
||||
console.log('StateManager not yet booted, adding to list', this._pending.length);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// console.log('StateManager.add', key, stateConfig, autoStart);
|
||||
|
||||
key = this.getKey(key, stateConfig);
|
||||
|
||||
console.log('StateManager.add', key, stateConfig, autoStart);
|
||||
|
||||
var newState;
|
||||
|
||||
if (stateConfig instanceof State)
|
||||
{
|
||||
// console.log('StateManager.add from instance', key);
|
||||
console.log('StateManager.add from instance:', key);
|
||||
newState = this.createStateFromInstance(key, stateConfig);
|
||||
}
|
||||
else if (typeof stateConfig === 'object')
|
||||
{
|
||||
// console.log('StateManager.add from object', key);
|
||||
console.log('StateManager.add from object:', key);
|
||||
|
||||
stateConfig.key = key;
|
||||
|
||||
|
@ -158,7 +161,7 @@ StateManager.prototype = {
|
|||
}
|
||||
else if (typeof stateConfig === 'function')
|
||||
{
|
||||
// console.log('StateManager.add from function', key);
|
||||
console.log('StateManager.add from function:', key);
|
||||
|
||||
newState = this.createStateFromFunction(key, stateConfig);
|
||||
}
|
||||
|
@ -256,55 +259,65 @@ StateManager.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
setupCallbacks: function (newState, stateConfig)
|
||||
setupCallbacks: function (state, stateConfig)
|
||||
{
|
||||
if (stateConfig === undefined) { stateConfig = newState; }
|
||||
if (stateConfig === undefined) { stateConfig = state; }
|
||||
|
||||
// Extract callbacks or set NOOP
|
||||
|
||||
newState.init = GetObjectValue(stateConfig, 'init', NOOP);
|
||||
newState.preload = GetObjectValue(stateConfig, 'preload', NOOP);
|
||||
newState.create = GetObjectValue(stateConfig, 'create', NOOP);
|
||||
newState.shutdown = GetObjectValue(stateConfig, 'shutdown', NOOP);
|
||||
state.init = GetObjectValue(stateConfig, 'init', NOOP);
|
||||
state.preload = GetObjectValue(stateConfig, 'preload', NOOP);
|
||||
state.create = GetObjectValue(stateConfig, 'create', NOOP);
|
||||
state.shutdown = GetObjectValue(stateConfig, 'shutdown', NOOP);
|
||||
|
||||
// Game Loop level callbacks
|
||||
|
||||
newState.update = GetObjectValue(stateConfig, 'update', NOOP);
|
||||
newState.render = GetObjectValue(stateConfig, 'render', NOOP);
|
||||
state.update = GetObjectValue(stateConfig, 'update', NOOP);
|
||||
state.render = GetObjectValue(stateConfig, 'render', NOOP);
|
||||
|
||||
return newState;
|
||||
return state;
|
||||
},
|
||||
|
||||
createStateDisplay: function (newState)
|
||||
createStateDisplay: function (state)
|
||||
{
|
||||
return;
|
||||
console.log('createStateDisplay', state.settings.key);
|
||||
|
||||
/*
|
||||
var settings = newState.sys.settings;
|
||||
var settings = state.sys.settings;
|
||||
|
||||
var x = settings.x;
|
||||
var y = settings.y;
|
||||
// var x = settings.x;
|
||||
// var y = settings.y;
|
||||
var width = settings.width;
|
||||
var height = settings.height;
|
||||
|
||||
// Too late to do all this?
|
||||
var config = this.game.config;
|
||||
|
||||
if (settings.width === -1)
|
||||
if (config.renderType === CONST.CANVAS)
|
||||
{
|
||||
settings.width = this.game.config.width;
|
||||
if (settings.renderToTexture)
|
||||
{
|
||||
console.log('renderToTexture');
|
||||
state.sys.canvas = CanvasPool.create(state, width, height);
|
||||
state.sys.context = GetContext(state.sys.canvas);
|
||||
|
||||
// Pixel Art mode?
|
||||
if (config.pixelArt)
|
||||
{
|
||||
CanvasInterpolation.setCrisp(state.sys.canvas);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('using game canvas');
|
||||
state.sys.mask = new Rectangle(0, 0, width, height);
|
||||
state.sys.canvas = this.game.canvas;
|
||||
state.sys.context = this.game.context;
|
||||
}
|
||||
}
|
||||
else if (config.renderType === CONST.WEBGL)
|
||||
{
|
||||
// state.sys.fbo = this.game.renderer.createFBO(state, x, y, width, height);
|
||||
}
|
||||
|
||||
if (settings.height === -1)
|
||||
{
|
||||
settings.height = this.game.config.height;
|
||||
}
|
||||
|
||||
if (this.game.config.renderType === CONST.WEBGL)
|
||||
{
|
||||
var width = settings.width;
|
||||
var height = settings.height;
|
||||
|
||||
newState.sys.fbo = this.game.renderer.createFBO(newState, x, y, width, height);
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
getState: function (key)
|
||||
|
@ -339,10 +352,12 @@ StateManager.prototype = {
|
|||
|
||||
start: function (key)
|
||||
{
|
||||
console.log('start:', key);
|
||||
|
||||
// if not booted, then put state into a holding pattern
|
||||
if (!this.game.isBooted)
|
||||
{
|
||||
// console.log('StateManager not yet booted, setting autoStart on pending list');
|
||||
console.log('StateManager not yet booted, setting autoStart on pending list');
|
||||
|
||||
for (var i = 0; i < this._pending.length; i++)
|
||||
{
|
||||
|
@ -396,16 +411,16 @@ StateManager.prototype = {
|
|||
|
||||
payloadComplete: function (event)
|
||||
{
|
||||
console.log('payloadComplete');
|
||||
|
||||
var state = event.loader.state;
|
||||
|
||||
console.log('payloadComplete', state.sys.settings.key);
|
||||
|
||||
this.bootState(state);
|
||||
},
|
||||
|
||||
bootState: function (state)
|
||||
{
|
||||
console.log('bootState', state);
|
||||
console.log('bootState', state.sys.settings.key);
|
||||
|
||||
// + arguments
|
||||
if (state.init)
|
||||
|
@ -414,11 +429,11 @@ StateManager.prototype = {
|
|||
}
|
||||
|
||||
var loader = state.sys.load;
|
||||
|
||||
loader.reset();
|
||||
|
||||
if (state.preload && loader)
|
||||
if (state.preload)
|
||||
{
|
||||
loader.reset();
|
||||
|
||||
state.preload.call(state, this.game);
|
||||
|
||||
// Is the loader empty?
|
||||
|
@ -444,10 +459,10 @@ StateManager.prototype = {
|
|||
|
||||
loadComplete: function (event)
|
||||
{
|
||||
console.log('loadComplete');
|
||||
|
||||
var state = event.loader.state;
|
||||
|
||||
console.log('loadComplete', state.sys.settings.key);
|
||||
|
||||
// Make sure to do load-update one last time before state is set to _created
|
||||
|
||||
// Stop doing this ...
|
||||
|
@ -461,8 +476,11 @@ StateManager.prototype = {
|
|||
|
||||
startCreate: function (state)
|
||||
{
|
||||
console.log('startCreate', state.sys.settings.key);
|
||||
|
||||
if (state.create)
|
||||
{
|
||||
console.log('startCreate.call', state.sys.settings.key);
|
||||
state.create.call(state);
|
||||
}
|
||||
|
||||
|
@ -470,6 +488,8 @@ StateManager.prototype = {
|
|||
|
||||
var i = this.getStateIndex(state);
|
||||
|
||||
console.log('startCreate.index', state.sys.settings.key, i);
|
||||
|
||||
this.active.push({ index: i, state: state });
|
||||
|
||||
// Sort the 'active' array based on the index property
|
||||
|
|
|
@ -25,6 +25,13 @@ var Systems = function (state, config)
|
|||
|
||||
this.settings = Settings.create(config);
|
||||
|
||||
this.x = this.settings.x;
|
||||
this.y = this.settings.y;
|
||||
|
||||
this.mask = null;
|
||||
this.canvas;
|
||||
this.context;
|
||||
|
||||
// CORE SYSTEMS / PROPERTIES
|
||||
|
||||
this.cache;
|
||||
|
@ -39,7 +46,7 @@ var Systems = function (state, config)
|
|||
this.tree;
|
||||
|
||||
// State properties
|
||||
this.camera;
|
||||
this.cameras;
|
||||
this.children;
|
||||
this.color;
|
||||
this.data;
|
||||
|
@ -143,35 +150,12 @@ Systems.prototype = {
|
|||
camera.preRender();
|
||||
state.camera = camera;
|
||||
renderer.render(state, transform.flatRenderArray, interpolation, camera);
|
||||
state.render(interpolation);
|
||||
//state.render(interpolation);
|
||||
camera.postRender();
|
||||
}
|
||||
},
|
||||
|
||||
// Called just once per frame, regardless of speed
|
||||
|
||||
/*
|
||||
OLDrender: function (interpolation, renderer)
|
||||
{
|
||||
this.updates.start();
|
||||
|
||||
if (this.settings.visible && this.color.alpha !== 0)
|
||||
{
|
||||
var list = this.tree.search({
|
||||
minX: this.camera.x,
|
||||
minY: this.camera.y,
|
||||
maxX: this.camera.right,
|
||||
maxY: this.camera.bottom
|
||||
});
|
||||
|
||||
renderer.render(this.state, list, interpolation);
|
||||
}
|
||||
|
||||
this.updates.stop();
|
||||
|
||||
this.state.render(interpolation);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
};
|
||||
|
||||
module.exports = Systems;
|
||||
|
|
Loading…
Add table
Reference in a new issue