2013-04-18 13:16:18 +00:00
|
|
|
/// <reference path="Phaser.ts" />
|
2013-04-12 16:19:56 +00:00
|
|
|
/// <reference path="Game.ts" />
|
2013-04-14 01:31:00 +00:00
|
|
|
/// <reference path="system/StageScaleMode.ts" />
|
2013-04-29 01:41:19 +00:00
|
|
|
/// <reference path="system/screens/BootScreen.ts" />
|
|
|
|
/// <reference path="system/screens/PauseScreen.ts" />
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
/**
|
2013-04-18 15:49:08 +00:00
|
|
|
* Phaser - Stage
|
|
|
|
*
|
|
|
|
* The Stage is the canvas on which everything is displayed. This class handles display within the web browser, focus handling,
|
|
|
|
* resizing, scaling and pause/boot screens.
|
2013-04-18 13:16:18 +00:00
|
|
|
*/
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
module Phaser {
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
export class Stage {
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Stage constructor
|
|
|
|
*
|
|
|
|
* Create a new <code>Stage</code> with specific width and height.
|
|
|
|
*
|
2013-05-04 11:34:05 +00:00
|
|
|
* @param parent {number} ID of parent DOM element.
|
|
|
|
* @param width {number} Width of the stage.
|
|
|
|
* @param height {number} Height of the stage.
|
2013-05-03 11:12:12 +00:00
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
constructor(game: Game, parent: string, width: number, height: number) {
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
this._game = game;
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
this.canvas = <HTMLCanvasElement> document.createElement('canvas');
|
|
|
|
this.canvas.width = width;
|
|
|
|
this.canvas.height = height;
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
if (document.getElementById(parent))
|
|
|
|
{
|
|
|
|
document.getElementById(parent).appendChild(this.canvas);
|
|
|
|
document.getElementById(parent).style.overflow = 'hidden';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
document.body.appendChild(this.canvas);
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-19 08:23:36 +00:00
|
|
|
// Consume default actions on the canvas
|
|
|
|
this.canvas.style.msTouchAction = 'none';
|
2013-05-16 01:36:58 +00:00
|
|
|
this.canvas.style['ms-touch-action'] = 'none';
|
2013-04-19 08:23:36 +00:00
|
|
|
this.canvas.style['touch-action'] = 'none';
|
2013-05-14 02:37:38 +00:00
|
|
|
this.canvas.style.backgroundColor = 'rgb(0,0,0)';
|
2013-05-21 03:12:54 +00:00
|
|
|
this.canvas.oncontextmenu = function(event) { event.preventDefault(); };
|
2013-04-19 08:23:36 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
this.context = this.canvas.getContext('2d');
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
this.offset = this.getOffset(this.canvas);
|
2013-05-28 20:38:37 +00:00
|
|
|
this.bounds = new Rectangle(this.offset.x, this.offset.y, width, height);
|
2013-04-18 13:16:18 +00:00
|
|
|
this.aspectRatio = width / height;
|
|
|
|
this.scaleMode = StageScaleMode.NO_SCALE;
|
|
|
|
this.scale = new StageScaleMode(this._game);
|
|
|
|
|
2013-04-25 19:05:56 +00:00
|
|
|
document.addEventListener('visibilitychange', (event) => this.visibilityChange(event), false);
|
|
|
|
document.addEventListener('webkitvisibilitychange', (event) => this.visibilityChange(event), false);
|
2013-04-18 13:16:18 +00:00
|
|
|
window.onblur = (event) => this.visibilityChange(event);
|
|
|
|
window.onfocus = (event) => this.visibilityChange(event);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Local private reference to game.
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
private _game: Game;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
2013-05-14 02:37:38 +00:00
|
|
|
* Background color of the stage (defaults to black)
|
2013-05-03 11:12:12 +00:00
|
|
|
* @type {string}
|
|
|
|
*/
|
2013-05-14 02:37:38 +00:00
|
|
|
private _bgColor: string = 'rgb(0,0,0)';
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* This will be displayed when Phaser is started without any default functions or State
|
|
|
|
* @type {BootScreen}
|
|
|
|
*/
|
2013-04-29 01:41:19 +00:00
|
|
|
private _bootScreen;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* This will be displayed whenever the game loses focus or the player switches to another browser tab.
|
|
|
|
* @type {PauseScreen}
|
|
|
|
*/
|
2013-04-29 01:41:19 +00:00
|
|
|
private _pauseScreen;
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Bound of this stage.
|
2013-05-28 20:38:37 +00:00
|
|
|
* @type {Rectangle}
|
2013-05-03 11:12:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public bounds: Rectangle;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Asperct ratio, thus: width / height.
|
|
|
|
* @type {number}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public aspectRatio: number;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Clear the whole stage every frame? (Default to true)
|
|
|
|
* @type {boolean}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public clear: bool = true;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Canvas element used by engine.
|
|
|
|
* @type {HTMLCanvasElement}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public canvas: HTMLCanvasElement;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Render context of stage's canvas.
|
|
|
|
* @type {CanvasRenderingContext2D}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public context: CanvasRenderingContext2D;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Do not use pause screen when game is paused?
|
|
|
|
* (Default to false, aka always use PauseScreen)
|
|
|
|
* @type {boolean}
|
|
|
|
*/
|
2013-04-20 02:50:21 +00:00
|
|
|
public disablePauseScreen: bool = false;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Do not use boot screen when engine starts?
|
|
|
|
* (Default to false, aka always use BootScreen)
|
|
|
|
* @type {boolean}
|
|
|
|
*/
|
2013-04-29 01:41:19 +00:00
|
|
|
public disableBootScreen: bool = false;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Offset from this stage to the canvas element.
|
2013-05-16 01:36:58 +00:00
|
|
|
* @type {MicroPoint}
|
2013-05-03 11:12:12 +00:00
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
public offset: Point;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* This object manages scaling of the game, see(StageScaleMode).
|
|
|
|
* @type {StageScaleMode}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public scale: StageScaleMode;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Which mode will the game be scaled.
|
|
|
|
* Available: StageScaleMode.EXACT_FIT, StageScaleMode.NO_SCALE, StageScaleMode.SHOW_ALL.
|
|
|
|
* @type {number}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public scaleMode: number;
|
2013-04-13 03:25:03 +00:00
|
|
|
|
2013-06-02 02:47:54 +00:00
|
|
|
/**
|
|
|
|
* Stage boot
|
|
|
|
*/
|
|
|
|
public boot() {
|
|
|
|
|
|
|
|
this._bootScreen = new BootScreen(this._game);
|
|
|
|
this._pauseScreen = new PauseScreen(this._game, this.width, this.height);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Update stage for rendering. This will handle scaling, clearing
|
|
|
|
* and PauseScreen/BootScreen updating and rendering.
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public update() {
|
|
|
|
|
|
|
|
this.scale.update();
|
|
|
|
|
|
|
|
if (this.clear)
|
|
|
|
{
|
|
|
|
// implement dirty rect? could take up more cpu time than it saves. needs benching.
|
|
|
|
this.context.clearRect(0, 0, this.width, this.height);
|
|
|
|
}
|
2013-04-13 03:25:03 +00:00
|
|
|
|
2013-04-29 01:41:19 +00:00
|
|
|
if (this._game.isRunning == false && this.disableBootScreen == false)
|
|
|
|
{
|
|
|
|
this._bootScreen.update();
|
|
|
|
this._bootScreen.render();
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-29 01:41:19 +00:00
|
|
|
if (this._game.paused == true && this.disablePauseScreen == false)
|
|
|
|
{
|
|
|
|
this._pauseScreen.update();
|
|
|
|
this._pauseScreen.render();
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
2013-05-14 02:37:38 +00:00
|
|
|
* This method is called when the canvas elements visibility is changed.
|
2013-05-03 11:12:12 +00:00
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
private visibilityChange(event) {
|
|
|
|
|
2013-04-20 02:50:21 +00:00
|
|
|
if (this.disablePauseScreen)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-05-14 02:37:38 +00:00
|
|
|
if (event.type == 'blur' || document['hidden'] == true || document['webkitHidden'] == true)
|
2013-04-18 13:16:18 +00:00
|
|
|
{
|
2013-04-29 01:41:19 +00:00
|
|
|
if (this._game.paused == false)
|
|
|
|
{
|
2013-05-22 23:01:58 +00:00
|
|
|
this.pauseGame();
|
2013-04-29 01:41:19 +00:00
|
|
|
}
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
2013-05-14 02:37:38 +00:00
|
|
|
else
|
2013-04-18 13:16:18 +00:00
|
|
|
{
|
2013-04-29 01:41:19 +00:00
|
|
|
if (this._game.paused == true)
|
|
|
|
{
|
2013-05-22 23:01:58 +00:00
|
|
|
this.resumeGame();
|
2013-04-29 01:41:19 +00:00
|
|
|
}
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
|
|
|
}
|
2013-04-18 13:16:18 +00:00
|
|
|
|
2013-05-22 23:01:58 +00:00
|
|
|
public pauseGame() {
|
|
|
|
|
|
|
|
this._pauseScreen.onPaused();
|
|
|
|
this.saveCanvasValues();
|
|
|
|
this._game.paused = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public resumeGame() {
|
|
|
|
|
|
|
|
this._pauseScreen.onResume();
|
|
|
|
this.restoreCanvasValues();
|
|
|
|
this._game.paused = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-05-18 02:05:28 +00:00
|
|
|
/**
|
|
|
|
* Get the DOM offset values of the given element
|
|
|
|
*/
|
2013-05-28 20:38:37 +00:00
|
|
|
private getOffset(element): Point {
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
var box = element.getBoundingClientRect();
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
var clientTop = element.clientTop || document.body.clientTop || 0;
|
|
|
|
var clientLeft = element.clientLeft || document.body.clientLeft || 0;
|
|
|
|
var scrollTop = window.pageYOffset || element.scrollTop || document.body.scrollTop;
|
|
|
|
var scrollLeft = window.pageXOffset || element.scrollLeft || document.body.scrollLeft;
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-05-28 20:38:37 +00:00
|
|
|
return new Point(box.left + scrollLeft - clientLeft, box.top + scrollTop - clientTop);
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Canvas strokeStyle.
|
|
|
|
* @type {string}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public strokeStyle: string;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Canvas lineWidth.
|
|
|
|
* @type {number}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public lineWidth: number;
|
2013-05-11 22:51:50 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Canvas fillStyle.
|
|
|
|
* @type {string}
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public fillStyle: string;
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Save current canvas properties (strokeStyle, lineWidth and fillStyle) for later using.
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public saveCanvasValues() {
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
this.strokeStyle = this.context.strokeStyle;
|
|
|
|
this.lineWidth = this.context.lineWidth;
|
|
|
|
this.fillStyle = this.context.fillStyle;
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-05-03 11:12:12 +00:00
|
|
|
/**
|
|
|
|
* Restore current canvas values (strokeStyle, lineWidth and fillStyle) with saved values.
|
|
|
|
*/
|
2013-04-18 13:16:18 +00:00
|
|
|
public restoreCanvasValues() {
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
this.context.strokeStyle = this.strokeStyle;
|
|
|
|
this.context.lineWidth = this.lineWidth;
|
|
|
|
this.context.fillStyle = this.fillStyle;
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public set backgroundColor(color: string) {
|
|
|
|
this.canvas.style.backgroundColor = color;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get backgroundColor(): string {
|
|
|
|
return this._bgColor;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get x(): number {
|
|
|
|
return this.bounds.x;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get y(): number {
|
|
|
|
return this.bounds.y;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get width(): number {
|
|
|
|
return this.bounds.width;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get height(): number {
|
|
|
|
return this.bounds.height;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get centerX(): number {
|
|
|
|
return this.bounds.halfWidth;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get centerY(): number {
|
|
|
|
return this.bounds.halfHeight;
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get randomX(): number {
|
|
|
|
return Math.round(Math.random() * this.bounds.width);
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
public get randomY(): number {
|
|
|
|
return Math.round(Math.random() * this.bounds.height);
|
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
2013-04-18 13:16:18 +00:00
|
|
|
}
|
2013-04-12 16:19:56 +00:00
|
|
|
|
|
|
|
}
|