phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.
521 lines (445 loc) • 15 kB
JavaScript
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
var Camera = require('./Camera');
var Class = require('../../utils/Class');
var GetFastValue = require('../../utils/object/GetFastValue');
var PluginManager = require('../../boot/PluginManager');
var RectangleContains = require('../../geom/rectangle/Contains');
/**
* @typedef {object} InputJSONCameraObject
*
* @property {string} [name=''] - [description]
* @property {integer} [x=0] - [description]
* @property {integer} [y=0] - [description]
* @property {integer} [width] - [description]
* @property {integer} [height] - [description]
* @property {float} [zoom=1] - [description]
* @property {float} [rotation=0] - [description]
* @property {boolean} [roundPixels=false] - [description]
* @property {float} [scrollX=0] - [description]
* @property {float} [scrollY=0] - [description]
* @property {(false|string)} [backgroundColor=false] - [description]
* @property {?object} [bounds] - [description]
* @property {number} [bounds.x=0] - [description]
* @property {number} [bounds.y=0] - [description]
* @property {number} [bounds.width] - [description]
* @property {number} [bounds.height] - [description]
*/
/**
* @classdesc
* [description]
*
* @class CameraManager
* @memberOf Phaser.Cameras.Scene2D
* @constructor
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene that owns the Camera Manager plugin.
*/
var CameraManager = new Class({
initialize:
function CameraManager (scene)
{
/**
* The Scene that owns the Camera Manager plugin.
*
* @name Phaser.Cameras.Scene2D.CameraManager#scene
* @type {Phaser.Scene}
* @since 3.0.0
*/
this.scene = scene;
/**
* A reference to the Scene.Systems handler for the Scene that owns the Camera Manager.
*
* @name Phaser.Cameras.Scene2D.CameraManager#systems
* @type {Phaser.Scenes.Systems}
* @since 3.0.0
*/
this.systems = scene.sys;
/**
* The current Camera ID.
*
* @name Phaser.Cameras.Scene2D.CameraManager#currentCameraId
* @type {number}
* @default 1
* @readOnly
* @since 3.0.0
*/
this.currentCameraId = 1;
/**
* An Array of the Camera objects being managed by this Camera Manager.
*
* @name Phaser.Cameras.Scene2D.CameraManager#cameras
* @type {Phaser.Cameras.Scene2D.Camera[]}
* @since 3.0.0
*/
this.cameras = [];
/**
* A pool of Camera objects available to be used by the Camera Manager.
*
* @name Phaser.Cameras.Scene2D.CameraManager#cameraPool
* @type {Phaser.Cameras.Scene2D.Camera[]}
* @since 3.0.0
*/
this.cameraPool = [];
/**
* The default Camera in the Camera Manager.
*
* @name Phaser.Cameras.Scene2D.CameraManager#main
* @type {Phaser.Cameras.Scene2D.Camera}
* @since 3.0.0
*/
this.main;
/**
* This scale affects all cameras. It's used by Scale Manager.
*
* @name Phaser.Cameras.Scene2D.CameraManager#baseScale
* @type {number}
* @since 3.0.0
*/
this.baseScale = 1;
scene.sys.events.once('boot', this.boot, this);
scene.sys.events.on('start', this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Cameras.Scene2D.CameraManager#boot
* @private
* @since 3.5.1
*/
boot: function ()
{
var sys = this.systems;
if (sys.settings.cameras)
{
// We have cameras to create
this.fromJSON(sys.settings.cameras);
}
else
{
// Make one
this.add();
}
this.main = this.cameras[0];
this.systems.events.once('destroy', this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Cameras.Scene2D.CameraManager#start
* @private
* @since 3.5.0
*/
start: function ()
{
if (!this.main)
{
this.boot();
}
var eventEmitter = this.systems.events;
eventEmitter.on('update', this.update, this);
eventEmitter.once('shutdown', this.shutdown, this);
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#add
* @since 3.0.0
*
* @param {number} [x=0] - [description]
* @param {number} [y=0] - [description]
* @param {number} [width] - [description]
* @param {number} [height] - [description]
* @param {boolean} [makeMain=false] - [description]
* @param {string} [name=''] - [description]
*
* @return {Phaser.Cameras.Scene2D.Camera} [description]
*/
add: function (x, y, width, height, makeMain, name)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (width === undefined) { width = this.scene.sys.game.config.width; }
if (height === undefined) { height = this.scene.sys.game.config.height; }
if (makeMain === undefined) { makeMain = false; }
if (name === undefined) { name = ''; }
var camera = null;
if (this.cameraPool.length > 0)
{
camera = this.cameraPool.pop();
camera.setViewport(x, y, width, height);
}
else
{
camera = new Camera(x, y, width, height);
}
camera.setName(name);
camera.setScene(this.scene);
this.cameras.push(camera);
if (makeMain)
{
this.main = camera;
}
camera._id = this.currentCameraId;
this.currentCameraId = this.currentCameraId << 1;
return camera;
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#addExisting
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - [description]
*
* @return {Phaser.Cameras.Scene2D.Camera} [description]
*/
addExisting: function (camera)
{
var index = this.cameras.indexOf(camera);
var poolIndex = this.cameraPool.indexOf(camera);
if (index < 0 && poolIndex >= 0)
{
this.cameras.push(camera);
this.cameraPool.slice(poolIndex, 1);
return camera;
}
return null;
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#fromJSON
* @since 3.0.0
*
* @param {(InputJSONCameraObject|InputJSONCameraObject[])} config - [description]
*
* @return {Phaser.Cameras.Scene2D.CameraManager} [description]
*/
fromJSON: function (config)
{
if (!Array.isArray(config))
{
config = [ config ];
}
var gameWidth = this.scene.sys.game.config.width;
var gameHeight = this.scene.sys.game.config.height;
for (var i = 0; i < config.length; i++)
{
var cameraConfig = config[i];
var x = GetFastValue(cameraConfig, 'x', 0);
var y = GetFastValue(cameraConfig, 'y', 0);
var width = GetFastValue(cameraConfig, 'width', gameWidth);
var height = GetFastValue(cameraConfig, 'height', gameHeight);
var camera = this.add(x, y, width, height);
// Direct properties
camera.name = GetFastValue(cameraConfig, 'name', '');
camera.zoom = GetFastValue(cameraConfig, 'zoom', 1);
camera.rotation = GetFastValue(cameraConfig, 'rotation', 0);
camera.scrollX = GetFastValue(cameraConfig, 'scrollX', 0);
camera.scrollY = GetFastValue(cameraConfig, 'scrollY', 0);
camera.roundPixels = GetFastValue(cameraConfig, 'roundPixels', false);
// Background Color
var backgroundColor = GetFastValue(cameraConfig, 'backgroundColor', false);
if (backgroundColor)
{
camera.setBackgroundColor(backgroundColor);
}
// Bounds
var boundsConfig = GetFastValue(cameraConfig, 'bounds', null);
if (boundsConfig)
{
var bx = GetFastValue(boundsConfig, 'x', 0);
var by = GetFastValue(boundsConfig, 'y', 0);
var bwidth = GetFastValue(boundsConfig, 'width', gameWidth);
var bheight = GetFastValue(boundsConfig, 'height', gameHeight);
camera.setBounds(bx, by, bwidth, bheight);
}
}
return this;
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#getCamera
* @since 3.0.0
*
* @param {string} name - [description]
*
* @return {Phaser.Cameras.Scene2D.Camera} [description]
*/
getCamera: function (name)
{
for (var i = 0; i < this.cameras.length; i++)
{
if (this.cameras[i].name === name)
{
return this.cameras[i];
}
}
return null;
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#getCameraBelowPointer
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - [description]
*
* @return {Phaser.Cameras.Scene2D.Camera} [description]
*/
getCameraBelowPointer: function (pointer)
{
var cameras = this.cameras;
// Start from the most recently added camera (the 'top' camera)
for (var i = cameras.length - 1; i >= 0; i--)
{
var camera = cameras[i];
if (camera.inputEnabled && RectangleContains(camera, pointer.x, pointer.y))
{
return camera;
}
}
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#remove
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - [description]
*/
remove: function (camera)
{
var cameraIndex = this.cameras.indexOf(camera);
if (cameraIndex >= 0 && this.cameras.length > 1)
{
this.cameraPool.push(this.cameras[cameraIndex]);
this.cameras.splice(cameraIndex, 1);
if (this.main === camera)
{
this.main = this.cameras[0];
}
}
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#render
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Renderer that will render the children to this camera.
* @param {Phaser.GameObjects.GameObject[]} children - An array of renderable Game Objects.
* @param {number} interpolation - Interpolation value. Reserved for future use.
*/
render: function (renderer, children, interpolation)
{
var cameras = this.cameras;
var baseScale = this.baseScale;
for (var i = 0, l = cameras.length; i < l; ++i)
{
var camera = cameras[i];
camera.preRender(baseScale, renderer.config.resolution);
renderer.render(this.scene, children, interpolation, camera);
}
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#resetAll
* @since 3.0.0
*
* @return {Phaser.Cameras.Scene2D.Camera} [description]
*/
resetAll: function ()
{
while (this.cameras.length > 0)
{
this.cameraPool.push(this.cameras.pop());
}
this.main = this.add();
return this.main;
},
/**
* [description]
*
* @method Phaser.Cameras.Scene2D.CameraManager#update
* @since 3.0.0
*
* @param {number} timestep - [description]
* @param {number} delta - [description]
*/
update: function (timestep, delta)
{
for (var i = 0, l = this.cameras.length; i < l; ++i)
{
this.cameras[i].update(timestep, delta);
}
},
/**
* Resizes all cameras to the given dimensions.
*
* @method Phaser.Cameras.Scene2D.CameraManager#resize
* @since 3.2.0
*
* @param {number} width - The new width of the camera.
* @param {number} height - The new height of the camera.
*/
resize: function (width, height)
{
for (var i = 0, l = this.cameras.length; i < l; ++i)
{
this.cameras[i].setSize(width, height);
}
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Cameras.Scene2D.CameraManager#shutdown
* @private
* @since 3.0.0
*/
shutdown: function ()
{
this.main = undefined;
for (var i = 0; i < this.cameras.length; i++)
{
this.cameras[i].destroy();
}
for (i = 0; i < this.cameraPool.length; i++)
{
this.cameraPool[i].destroy();
}
this.cameras = [];
this.cameraPool = [];
var eventEmitter = this.systems.events;
eventEmitter.off('update', this.update, this);
eventEmitter.off('shutdown', this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Cameras.Scene2D.CameraManager#destroy
* @private
* @since 3.0.0
*/
destroy: function ()
{
this.shutdown();
this.scene.sys.events.off('start', this.start, this);
this.scene = null;
this.systems = null;
}
});
PluginManager.register('CameraManager', CameraManager, 'cameras');
module.exports = CameraManager;