Added Full Screen support and tested it. Also added in the BitmapText game object and custom XML loader. Game now sends a pause and resume signal, which the TweenManager listens to and handles correctly.

This commit is contained in:
Richard Davey
2013-09-10 23:51:35 +01:00
parent e41e35fd09
commit e2eddc8b24
15 changed files with 2580 additions and 214 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<title>phaser.js - a new beginning</title>
<?php
require('js.php');
?>
</head>
<body>
<script type="text/javascript">
(function () {
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.bitmapFont('desyrel', 'assets/fonts/desyrel.png', 'assets/fonts/desyrel.xml');
}
function create() {
game.add.bitmapText(200, 100, 'Phaser\nis rocking!', { font: '64px Desyrel', align: 'center' });
}
function update() {
}
function render() {
}
})();
</script>
</body>
</html>
+52
View File
@@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<head>
<title>phaser.js - a new beginning</title>
<?php
require('js.php');
?>
<style type="text/css">
body {
margin: 0;
}
</style>
</head>
<body>
<script type="text/javascript">
(function () {
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.image('atari1', 'assets/sprites/atari130xe.png');
}
function create() {
var tempSprite = game.add.sprite(0, 0, 'atari1');
game.stage.backgroundColor = '#e3ed49';
game.input.onDown.add(gofull, this);
}
function gofull() {
game.stage.scale.startFullScreen();
}
function update() {
}
function render() {
}
})();
</script>
</body>
</html>
+2
View File
@@ -66,6 +66,7 @@
<script src="../src/gameobjects/Button.js"></script>
<script src="../src/gameobjects/Graphics.js"></script>
<script src="../src/gameobjects/RenderTexture.js"></script>
<script src="../src/gameobjects/BitmapText.js"></script>
<script src="../src/system/Canvas.js"></script>
<script src="../src/system/StageScaleMode.js"></script>
<script src="../src/system/Device.js"></script>
@@ -88,6 +89,7 @@
<script src="../src/animation/Parser.js"></script>
<script src="../src/loader/Cache.js"></script>
<script src="../src/loader/Loader.js"></script>
<script src="../src/loader/Parser.js"></script>
<script src="../src/sound/Sound.js"></script>
<script src="../src/sound/SoundManager.js"></script>
<script src="../src/utils/Debug.js"></script>
+221 -194
View File
@@ -34,18 +34,206 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
transparent = transparent || false;
antialias = antialias || true;
/**
* Phaser Game ID (for when Pixi supports multiple instances)
* @type {number}
*/
this.id = Phaser.GAMES.push(this) - 1;
/**
* The Games DOM parent.
* @type {HTMLElement}
*/
this.parent = parent;
// Do some more intelligent size parsing here, so they can set "100%" for example, maybe pass the scale mode in here too?
/**
* The Game width (in pixels).
* @type {number}
*/
this.width = width;
/**
* The Game height (in pixels).
* @type {number}
*/
this.height = height;
/**
* Use a transparent canvas background or not.
* @type {boolean}
*/
this.transparent = transparent;
/**
* Anti-alias graphics (in WebGL this helps with edges, in Canvas2D it retains pixel-art quality)
* @type {boolean}
*/
this.antialias = antialias;
/**
* The Pixi Renderer
* @type {number}
*/
this.renderType = renderer;
/**
* The StateManager.
* @type {Phaser.StateManager}
*/
this.state = new Phaser.StateManager(this, state);
/**
* Is game paused?
* @type {bool}
*/
this._paused = false;
/**
* The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL
* @type {number}
*/
this.renderType = 0;
/**
* Whether load complete loading or not.
* @type {bool}
*/
this._loadComplete = false;
/**
* Whether the game engine is booted, aka available.
* @type {bool}
*/
this.isBooted = false;
/**
* Is game running or paused?
* @type {bool}
*/
this.isRunning = false;
/**
* Automatically handles the core game loop via requestAnimationFrame or setTimeout
* @type {Phaser.RequestAnimationFrame}
*/
this.raf = null;
/**
* Reference to the GameObject Factory.
* @type {Phaser.GameObjectFactory}
*/
this.add = null;
/**
* Reference to the assets cache.
* @type {Phaser.Cache}
*/
this.cache = null;
/**
* Reference to the input manager
* @type {Phaser.Input}
*/
this.input = null;
/**
* Reference to the assets loader.
* @type {Phaser.Loader}
*/
this.load = null;
/**
* Reference to the math helper.
* @type {Phaser.GameMath}
*/
this.math = null;
/**
* Reference to the network class.
* @type {Phaser.Net}
*/
this.net = null;
/**
* Reference to the sound manager.
* @type {Phaser.SoundManager}
*/
this.sound = null;
/**
* Reference to the stage.
* @type {Phaser.Stage}
*/
this.stage = null;
/**
* Reference to game clock.
* @type {Phaser.TimeManager}
*/
this.time = null;
/**
* Reference to the tween manager.
* @type {Phaser.TweenManager}
*/
this.tweens = null;
/**
* Reference to the world.
* @type {Phaser.World}
*/
this.world = null;
/**
* Reference to the physics manager.
* @type {Phaser.Physics.PhysicsManager}
*/
this.physics = null;
/**
* Instance of repeatable random data generator helper.
* @type {Phaser.RandomDataGenerator}
*/
this.rnd = null;
/**
* Contains device information and capabilities.
* @type {Phaser.Device}
*/
this.device = null;
/**
* A handy reference to world.camera
* @type {Phaser.Camera}
*/
this.camera = null;
/**
* A handy reference to renderer.view
* @type {HTMLCanvasElement}
*/
this.canvas = null;
/**
* A handy reference to renderer.context (only set for CANVAS games)
* @type {Context}
*/
this.context = null;
/**
* A set of useful debug utilities
* @type {Phaser.Utils.Debug}
*/
this.debug = null;
/**
* The Particle Manager
* @type {Phaser.Particles}
*/
this.particles = null;
var _this = this;
this._onBoot = function () {
@@ -68,199 +256,6 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
Phaser.Game.prototype = {
// temps so we can clean-up the event listeneres
_tempState: null,
_onBoot: null,
/**
* Phaser Game ID.
* @type {number}
*/
id: 0,
/**
* The Game width (in pixels).
* @type {number}
*/
width: 0,
/**
* The Game height (in pixels).
* @type {number}
*/
height: 0,
transparent: false,
antialias: true,
/**
* The Games DOM parent.
* @type {HTMLElement}
*/
parent: '',
/**
* The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL
* @type {number}
*/
renderType: 0,
/**
* The Pixi Renderer
* @type {number}
*/
renderer: null,
/**
* Whether load complete loading or not.
* @type {bool}
*/
_loadComplete: false,
/**
* Is game paused?
* @type {bool}
*/
paused: false,
/**
* Whether the game engine is booted, aka available.
* @type {bool}
*/
isBooted: false,
/**
* Is game running or paused?
* @type {bool}
*/
isRunning: false,
/**
* Automatically handles the core game loop via requestAnimationFrame or setTimeout
* @type {Phaser.RequestAnimationFrame}
*/
raf: null,
/**
* The StateManager.
* @type {Phaser.StateManager}
*/
state: 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.Input}
*/
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,
/**
* A handy reference to world.camera
* @type {Phaser.Camera}
*/
camera: null,
/**
* A handy reference to renderer.view
* @type {HTMLCanvasElement}
*/
canvas: null,
/**
* A handy reference to renderer.context (only set for CANVAS games)
* @type {Context}
*/
context: null,
/**
* A set of useful debug utilities
* @type {Phaser.Utils.Debug}
*/
debug: null,
/**
* The Particle Manager
* @type {Phaser.Particles}
*/
particles: null,
/**
* Initialize engine sub modules and start the game.
* @param parent {string} ID of parent Dom element.
@@ -385,7 +380,7 @@ Phaser.Game.prototype = {
this.time.update(time);
if (!this.paused)
if (!this._paused)
{
this.plugins.preUpdate();
this.physics.preUpdate();
@@ -426,3 +421,35 @@ Phaser.Game.prototype = {
}
};
Object.defineProperty(Phaser.Game.prototype, "paused", {
get: function () {
return this._paused;
},
set: function (value) {
if (value === true)
{
if (this._paused == false)
{
this._paused = true;
this.onPause.dispatch(this);
}
}
else
{
if (this._paused)
{
this._paused = false;
this.onResume.dispatch(this);
}
}
},
enumerable: true,
configurable: true
});
+1
View File
@@ -23,6 +23,7 @@ Phaser.Stage = function (game, width, height) {
this.offset = new Phaser.Point;
this.canvas = Phaser.Canvas.create(width, height);
this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%';
// The Pixi Stage which is hooked to the renderer
this._stage = new PIXI.Stage(0x000000, false);
+117
View File
@@ -0,0 +1,117 @@
Phaser.BitmapText = function (game, x, y, text, style) {
x = x || 0;
y = y || 0;
text = text || '';
style = style || '';
// If exists = false then the Sprite isn't updated by the core game loop or physics subsystem at all
this.exists = true;
// This is a handy little var your game can use to determine if a sprite is alive or not, it doesn't effect rendering
this.alive = true;
this.group = null;
this.name = '';
this.game = game;
PIXI.BitmapText.call(this, text, style);
this.position.x = x;
this.position.y = y;
// Replaces the PIXI.Point with a slightly more flexible one
this.scale = new Phaser.Point(1, 1);
// Influence of camera movement upon the position
this.scrollFactor = new Phaser.Point(1, 1);
// A mini cache for storing all of the calculated values
this._cache = {
dirty: false,
// Transform cache
a00: 1, a01: 0, a02: x, a10: 0, a11: 1, a12: y, id: 1,
// The previous calculated position inc. camera x/y and scrollFactor
x: -1, y: -1,
// The actual scale values based on the worldTransform
scaleX: 1, scaleY: 1
};
this._cache.x = this.x - (this.game.world.camera.x * this.scrollFactor.x);
this._cache.y = this.y - (this.game.world.camera.y * this.scrollFactor.y);
this.renderable = true;
};
Phaser.BitmapText.prototype = Phaser.Utils.extend(true, PIXI.BitmapText.prototype);
Phaser.BitmapText.prototype.constructor = Phaser.BitmapText;
// Add our own custom methods
/**
* Automatically called by World.update
*/
Phaser.BitmapText.prototype.update = function() {
if (!this.exists)
{
return;
}
this._cache.dirty = false;
this._cache.x = this.x - (this.game.world.camera.x * this.scrollFactor.x);
this._cache.y = this.y - (this.game.world.camera.y * this.scrollFactor.y);
if (this.position.x != this._cache.x || this.position.y != this._cache.y)
{
this.position.x = this._cache.x;
this.position.y = this._cache.y;
this._cache.dirty = true;
}
}
Object.defineProperty(Phaser.BitmapText.prototype, 'angle', {
get: function() {
return Phaser.Math.radToDeg(this.rotation);
},
set: function(value) {
this.rotation = Phaser.Math.degToRad(value);
}
});
Object.defineProperty(Phaser.BitmapText.prototype, 'x', {
get: function() {
return this.position.x;
},
set: function(value) {
this.position.x = value;
}
});
Object.defineProperty(Phaser.BitmapText.prototype, 'y', {
get: function() {
return this.position.y;
},
set: function(value) {
this.position.y = value;
}
});
+6
View File
@@ -97,4 +97,10 @@ Phaser.GameObjectFactory.prototype = {
},
bitmapText: function (x, y, text, style) {
return this.world.add(new Phaser.BitmapText(this.game, x, y, text, style));
},
};
+19
View File
@@ -108,6 +108,25 @@ Phaser.Cache.prototype = {
},
/**
* Add a new Bitmap Font.
* @param key {string} Asset key for the font texture.
* @param url {string} URL of this font xml file.
* @param data {object} Extra font data.
* @param xmlData {object} Texture atlas frames data.
*/
addBitmapFont: function (key, url, data, xmlData) {
this._images[key] = { url: url, data: data, spriteSheet: true };
PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data);
PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]);
Phaser.Loader.Parser.bitmapFont(this.game, xmlData, key);
// this._images[key].frameData = Phaser.Animation.Parser.XMLData(this.game, xmlData, key);
},
/**
* Adds a default image to be used when a key is wrong / missing.
* Is mapped to the key __default
+119 -18
View File
@@ -217,6 +217,64 @@ Phaser.Loader.prototype = {
},
/**
* Add a new bitmap font loading request.
* @param key {string} Unique asset key of the bitmap font.
* @param textureURL {string} The url of the font image file.
* @param [xmlURL] {string} The url of the font data file (xml/fnt)
* @param [xmlData] {object} An optional XML data object.
*/
bitmapFont: function (key, textureURL, xmlURL, xmlData) {
if (typeof xmlURL === "undefined") { xmlURL = null; }
if (typeof xmlData === "undefined") { xmlData = null; }
if (this.checkKeyExists(key) === false)
{
// A URL to a json/xml file has been given
if (xmlURL)
{
this.addToFileList('bitmapfont', key, textureURL, { xmlURL: xmlURL });
}
else
{
// An xml string or object has been given
if (typeof xmlData === 'string')
{
var xml;
try {
if (window['DOMParser'])
{
var domparser = new DOMParser();
xml = domparser.parseFromString(xmlData, "text/xml");
}
else
{
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = 'false';
xml.loadXML(xmlData);
}
}
catch (e)
{
xml = undefined;
}
if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length)
{
throw new Error("Phaser.Loader. Invalid Bitmap Font XML given");
}
else
{
this.addToFileList('bitmapfont', key, textureURL, { xmlURL: null, xmlData: xml });
}
}
}
}
},
atlasJSONArray: function (key, textureURL, atlasURL, atlasData) {
this.atlas(key, textureURL, atlasURL, atlasData, Phaser.Loader.TEXTURE_ATLAS_JSON_ARRAY);
@@ -249,20 +307,22 @@ Phaser.Loader.prototype = {
if (typeof atlasData === "undefined") { atlasData = null; }
if (typeof format === "undefined") { format = Phaser.Loader.TEXTURE_ATLAS_JSON_ARRAY; }
if (this.checkKeyExists(key) === false) {
if (this.checkKeyExists(key) === false)
{
// A URL to a json/xml file has been given
if (atlasURL) {
if (atlasURL)
{
this.addToFileList('textureatlas', key, textureURL, { atlasURL: atlasURL, format: format });
}
else
{
switch (format) {
switch (format)
{
// A json string or object has been given
case Phaser.Loader.TEXTURE_ATLAS_JSON_ARRAY:
if (typeof atlasData === 'string') {
if (typeof atlasData === 'string')
{
atlasData = JSON.parse(atlasData);
}
break;
@@ -270,24 +330,34 @@ Phaser.Loader.prototype = {
// An xml string or object has been given
case Phaser.Loader.TEXTURE_ATLAS_XML_STARLING:
if (typeof atlasData === 'string') {
if (typeof atlasData === 'string')
{
var xml;
try {
if (window['DOMParser']) {
if (window['DOMParser'])
{
var domparser = new DOMParser();
xml = domparser.parseFromString(atlasData, "text/xml");
} else {
}
else
{
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = 'false';
xml.loadXML(atlasData);
}
} catch (e) {
}
catch (e)
{
xml = undefined;
}
if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) {
if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length)
{
throw new Error("Phaser.Loader. Invalid Texture Atlas XML given");
} else {
}
else
{
atlasData = xml;
}
}
@@ -298,7 +368,6 @@ Phaser.Loader.prototype = {
}
}
},
@@ -367,6 +436,7 @@ Phaser.Loader.prototype = {
case 'image':
case 'spritesheet':
case 'textureatlas':
case 'bitmapfont':
file.data = new Image();
file.data.name = file.key;
file.data.onload = function () {
@@ -537,6 +607,29 @@ Phaser.Loader.prototype = {
}
break;
case 'bitmapfont':
if (file.xmlURL == null)
{
this.game.cache.addBitmapFont(file.key, file.url, file.data, file.xmlData);
}
else
{
// Load the XML before carrying on with the next file
loadNext = false;
this._xhr.open("GET", this.baseURL + file.xmlURL, true);
this._xhr.responseType = "text";
this._xhr.onload = function () {
return _this.xmlLoadComplete(file.key);
};
this._xhr.onerror = function () {
return _this.dataLoadError(file.key);
};
this._xhr.send();
}
break;
case 'audio':
if (this.game.sound.usingWebAudio)
@@ -605,7 +698,7 @@ Phaser.Loader.prototype = {
file.error = true;
throw new Error("Phaser.Loader dataLoadError: " + key);
console.warn("Phaser.Loader dataLoadError: " + key);
this.nextFile(key, true);
@@ -613,7 +706,7 @@ Phaser.Loader.prototype = {
xmlLoadComplete: function (key) {
var atlasData = this._xhr.response;
var data = this._xhr.response;
var xml;
try
@@ -621,13 +714,13 @@ Phaser.Loader.prototype = {
if (window['DOMParser'])
{
var domparser = new DOMParser();
xml = domparser.parseFromString(atlasData, "text/xml");
xml = domparser.parseFromString(data, "text/xml");
}
else
{
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = 'false';
xml.loadXML(atlasData);
xml.loadXML(data);
}
}
catch (e)
@@ -641,7 +734,15 @@ Phaser.Loader.prototype = {
}
var file = this._fileList[key];
this.game.cache.addTextureAtlas(file.key, file.url, file.data, xml, file.format);
if (file.type == 'bitmapfont')
{
this.game.cache.addBitmapFont(file.key, file.url, file.data, xml);
}
else if (file.type == 'textureatlas')
{
this.game.cache.addTextureAtlas(file.key, file.url, file.data, xml, file.format);
}
this.nextFile(key, true);
+71
View File
@@ -0,0 +1,71 @@
Phaser.Loader.Parser = {
/**
* Parse frame data from an XML file.
* @param xml {object} XML data you want to parse.
* @return {FrameData} Generated FrameData object.
*/
bitmapFont: function (game, xml, cacheKey) {
// Malformed?
if (!xml.getElementsByTagName('font'))
{
console.warn("Phaser.Loader.Parser.bitmapFont: Invalid XML given, missing <font> tag");
return;
}
var texture = PIXI.TextureCache[cacheKey];
var data = {};
var info = xml.getElementsByTagName("info")[0];
var common = xml.getElementsByTagName("common")[0];
data.font = info.attributes.getNamedItem("face").nodeValue;
data.size = parseInt(info.attributes.getNamedItem("size").nodeValue, 10);
data.lineHeight = parseInt(common.attributes.getNamedItem("lineHeight").nodeValue, 10);
data.chars = {};
//parse letters
var letters = xml.getElementsByTagName("char");
for (var i = 0; i < letters.length; i++)
{
var charCode = parseInt(letters[i].attributes.getNamedItem("id").nodeValue, 10);
var textureRect = {
x: parseInt(letters[i].attributes.getNamedItem("x").nodeValue, 10),
y: parseInt(letters[i].attributes.getNamedItem("y").nodeValue, 10),
width: parseInt(letters[i].attributes.getNamedItem("width").nodeValue, 10),
height: parseInt(letters[i].attributes.getNamedItem("height").nodeValue, 10)
};
// Note: This means you can only have 1 BitmapFont loaded at once!
// Need to replace this with our own handler soon.
PIXI.TextureCache[charCode] = new PIXI.Texture(texture, textureRect);
data.chars[charCode] = {
xOffset: parseInt(letters[i].attributes.getNamedItem("xoffset").nodeValue, 10),
yOffset: parseInt(letters[i].attributes.getNamedItem("yoffset").nodeValue, 10),
xAdvance: parseInt(letters[i].attributes.getNamedItem("xadvance").nodeValue, 10),
kerning: {},
texture:new PIXI.Texture(texture, textureRect)
};
}
//parse kernings
var kernings = xml.getElementsByTagName("kerning");
for (i = 0; i < kernings.length; i++)
{
var first = parseInt(kernings[i].attributes.getNamedItem("first").nodeValue, 10);
var second = parseInt(kernings[i].attributes.getNamedItem("second").nodeValue, 10);
var amount = parseInt(kernings[i].attributes.getNamedItem("amount").nodeValue, 10);
data.chars[second].kerning[first] = amount;
}
PIXI.BitmapText.fonts[data.font] = data;
}
};
+4 -1
View File
@@ -144,9 +144,12 @@ Phaser.StageScaleMode.prototype = {
}
else if (element['webkitRequestFullScreen'])
{
element['webkitRequestFullScreen']();
element['webkitRequestFullScreen'](Element.ALLOW_KEYBOARD_INPUT);
}
this.game.stage.canvas.style['width'] = '100%';
this.game.stage.canvas.style['height'] = '100%';
},
stopFullScreen: function () {
+4 -1
View File
@@ -158,6 +158,10 @@ Phaser.Time = function (game) {
*/
this.lastTime = 0;
// Listen for game pause/resume events
this.game.onPause.add(this.gamePaused, this);
this.game.onResume.add(this.gameResumed, this);
};
Phaser.Time.prototype = {
@@ -229,7 +233,6 @@ Phaser.Time.prototype = {
// Level out the elapsed timer to avoid spikes
this.elapsed = 0;
this.physicsElapsed = 0;
this.time = Date.now();
this.pauseDuration = this.pausedTime;
},
+3
View File
@@ -14,6 +14,9 @@ Phaser.TweenManager = function (game) {
this.game = game;
this._tweens = [];
this.game.onPause.add(this.pauseAll, this);
this.game.onResume.add(this.resumeAll, this);
};
Phaser.TweenManager.prototype = {