Updated IE11 check, forces IE11 to use Canvas renderer even in AUTO mode.

This commit is contained in:
photonstorm
2013-12-13 14:04:14 +00:00
parent 1b954066a6
commit a361a18616
38 changed files with 9447 additions and 102 deletions
+6 -2
View File
@@ -47,7 +47,10 @@ Version 1.1.4 - "Kandor" - In development
New features: New features:
* Added a stage.fullScreenScaleMode property to determine scaling when fullscreen (thanks oysterCrusher) * Added a stage.fullScreenScaleMode property to determine scaling when fullscreen (thanks oysterCrusher)
* Added touch joystick example showing how to use the clay.io virtual game controller (thanks gabehollombe)
* Added support for margin and spacing around a frame in Loader.spritesheet.
* Added Device.vibration to check if the Vibration API is available or not.
* Added Device.trident and Device.tridentVersion for testing IE11 and forced IE11 to Canvas renderer until pixi updates to support it.
Updates: Updates:
@@ -59,7 +62,8 @@ Updates:
* Removed 'null parent' check from Group constructor. Will parent to game.world only if parent value is undefined. * Removed 'null parent' check from Group constructor. Will parent to game.world only if parent value is undefined.
* The tutorials have now been translated into Spanish - thanks feiss :) * The tutorials have now been translated into Spanish - thanks feiss :)
* separateY updated to re-implement the 'riding platforms' special condition (thanks cocoademon) * separateY updated to re-implement the 'riding platforms' special condition (thanks cocoademon)
* SoundManager.onSoundDecode now dispatches the key followed by the sound object, also now dispatched by the Cache when doing an auto-decode on load.
* Switch method of using trimmed sprites to support scaling and rotation (thanks cocoademon)
Bug Fixes: Bug Fixes:
+8768
View File
File diff suppressed because it is too large Load Diff
+26
View File
File diff suppressed because one or more lines are too long
+101
View File
@@ -0,0 +1,101 @@
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.image('car', 'assets/sprites/car90.png');
game.load.image('baddie', 'assets/sprites/space-baddie.png');
}
var car;
var aliens;
function create() {
// aliens = game.add.group();
// for (var i = 0; i < 50; i++)
// {
// var s = aliens.create(game.world.randomX, game.world.randomY, 'baddie');
// s.name = 'alien' + s;
// s.body.collideWorldBounds = true;
// s.body.bounce.setTo(0.8, 0.8);
// s.body.velocity.setTo(10 + Math.random() * 40, 10 + Math.random() * 40);
// }
car = game.add.sprite(0, 300, 'car');
car.anchor.setTo(0.5, 0.5);
car.body.collideWorldBounds = true;
car.body.bounce.setTo(0.8, 0.8);
car.body.allowRotation = true;
// car.body.drag.x = 10;
// car.body.drag.y = 10;
// car.body.acceleration.x = 10;
game.input.onDown.add(start, this);
}
var s = 0;
function start() {
// car.body.velocity.x = 200;
car.body.acceleration.x = 100;
s = game.time.now;
}
function update() {
if (car.x >= 400 && car.body.velocity.x > 0)
{
car.body.velocity.x = 0;
car.body.acceleration.x = 0;
var total = game.time.now - s;
console.log(game.time.physicsElapsed);
console.log('total ms', total, 'px/sec', car.x/(total/1000));
}
// car.body.velocity.x = 0;
// car.body.velocity.y = 0;
// car.body.angularVelocity = 0;
// car.body.acceleration.x = 0;
// car.body.acceleration.y = 0;
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
car.body.angularVelocity = -200;
// car.body.acceleration.x = -10;
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
car.body.angularVelocity = 200;
// car.body.acceleration.x = 10;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
{
// game.physics.accelerationFromRotation(car.rotation, 10, car.body.acceleration);
// car.body.acceleration.x = 10;
// car.body.acceleration.copyFrom(game.physics.velocityFromAngle(car.angle, 30));
// car.body.velocity.copyFrom(game.physics.velocityFromAngle(car.angle, 300));
}
else
{
// game.physics.accelerationFromRotation(car.rotation, 10, car.body.acceleration);
}
// game.physics.collide(car, aliens);
}
function render() {
game.debug.renderSpriteInfo(car, 32, 32);
}
+32
View File
@@ -0,0 +1,32 @@
var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
}
var snake;
var bmd;
var cursors;
function create() {
bmd = game.add.bitmapData(32, 32);
bmd.context.fillStyle = 'rgb(0, 255, 0)';
bmd.context.fillRect(0, 0, 32, 32);
snake = game.add.group();
sprite = game.add.sprite(game.world.randomX - 32, game.world.randomY - 64, bmd);
}
function update() {
}
function render() {
}
+32 -32
View File
@@ -6,45 +6,45 @@ BasicGame.Boot = function (game) {
BasicGame.Boot.prototype = { BasicGame.Boot.prototype = {
preload: function () { preload: function () {
// Here we load the assets required for our preloader (in this case a background and a loading bar) // Here we load the assets required for our preloader (in this case a background and a loading bar)
this.load.image('preloaderBackground', 'images/preloader_background.jpg'); this.load.image('preloaderBackground', 'images/preloader_background.jpg');
this.load.image('preloaderBar', 'images/preloadr_bar.png'); this.load.image('preloaderBar', 'images/preloadr_bar.png');
}, },
create: function () { create: function () {
// Unless you specifically know your game needs to support multi-touch I would recommend setting this to 1 // Unless you specifically know your game needs to support multi-touch I would recommend setting this to 1
this.game.input.maxPointers = 1; this.game.input.maxPointers = 1;
// Phaser will automatically pause if the browser tab the game is in loses focus. You can disable that here: // Phaser will automatically pause if the browser tab the game is in loses focus. You can disable that here:
this.game.stage.disableVisibilityChange = true; this.game.stage.disableVisibilityChange = true;
if (this.game.device.desktop) if (this.game.device.desktop)
{ {
// If you have any desktop specific settings, they can go in here // If you have any desktop specific settings, they can go in here
this.game.stage.scale.pageAlignHorizontally = true; this.game.stage.scale.pageAlignHorizontally = true;
} }
else else
{ {
// Same goes for mobile settings. // Same goes for mobile settings.
// In this case we're saying "scale the game, no lower than 480x260 and no higher than 1024x768" // In this case we're saying "scale the game, no lower than 480x260 and no higher than 1024x768"
this.game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; this.game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL;
this.game.stage.scale.minWidth = 480; this.game.stage.scale.minWidth = 480;
this.game.stage.scale.minHeight = 260; this.game.stage.scale.minHeight = 260;
this.game.stage.scale.maxWidth = 1024; this.game.stage.scale.maxWidth = 1024;
this.game.stage.scale.maxHeight = 768; this.game.stage.scale.maxHeight = 768;
this.game.stage.scale.forceLandscape = true; this.game.stage.scale.forceLandscape = true;
this.game.stage.scale.pageAlignHorizontally = true; this.game.stage.scale.pageAlignHorizontally = true;
this.game.stage.scale.setScreenSize(true); this.game.stage.scale.setScreenSize(true);
} }
// By this point the preloader assets have loaded to the cache, we've set the game settings // By this point the preloader assets have loaded to the cache, we've set the game settings
// So now let's start the real preloader going // So now let's start the real preloader going
this.game.state.start('Preloader'); this.game.state.start('Preloader');
} }
}; };
+8 -6
View File
@@ -20,9 +20,11 @@ Phaser.AnimationParser = {
* @param {number} frameWidth - The fixed width of each frame of the animation. * @param {number} frameWidth - The fixed width of each frame of the animation.
* @param {number} frameHeight - The fixed height of each frame of the animation. * @param {number} frameHeight - The fixed height of each frame of the animation.
* @param {number} [frameMax=-1] - The total number of animation frames to extact from the Sprite Sheet. The default value of -1 means "extract all frames". * @param {number} [frameMax=-1] - The total number of animation frames to extact from the Sprite Sheet. The default value of -1 means "extract all frames".
* @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
* @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
* @return {Phaser.FrameData} A FrameData object containing the parsed frames. * @return {Phaser.FrameData} A FrameData object containing the parsed frames.
*/ */
spriteSheet: function (game, key, frameWidth, frameHeight, frameMax) { spriteSheet: function (game, key, frameWidth, frameHeight, frameMax, margin, spacing) {
// How big is our image? // How big is our image?
var img = game.cache.getImage(key); var img = game.cache.getImage(key);
@@ -63,8 +65,8 @@ Phaser.AnimationParser = {
// Let's create some frames then // Let's create some frames then
var data = new Phaser.FrameData(); var data = new Phaser.FrameData();
var x = 0; var x = margin;
var y = 0; var y = margin;
for (var i = 0; i < total; i++) for (var i = 0; i < total; i++)
{ {
@@ -79,12 +81,12 @@ Phaser.AnimationParser = {
height: frameHeight height: frameHeight
}); });
x += frameWidth; x += frameWidth + spacing;
if (x === width) if (x === width)
{ {
x = 0; x = margin;
y += frameHeight; y += frameHeight + spacing;
} }
} }
+6
View File
@@ -372,6 +372,12 @@ Phaser.Game.prototype = {
*/ */
setUpRenderer: function () { setUpRenderer: function () {
if (this.device.trident)
{
// Until Pixi works with IE11
this.renderType = Phaser.CANVAS;
}
if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && this.device.webGL === false)) if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && this.device.webGL === false))
{ {
if (this.device.canvas) if (this.device.canvas)
+1 -1
View File
@@ -358,7 +358,7 @@ Phaser.Keyboard.prototype = {
/** /**
* Returns the "just released" state of the Key. Just released is considered as being true if the key was released within the duration given (default 250ms) * Returns the "just released" state of the Key. Just released is considered as being true if the key was released within the duration given (default 250ms)
* @method Phaser.Keyboard#justPressed * @method Phaser.Keyboard#justReleased
* @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR
* @param {number} [duration=250] - The duration below which the key is considered as being just released. * @param {number} [duration=250] - The duration below which the key is considered as being just released.
* @return {boolean} True if the key is just released otherwise false. * @return {boolean} True if the key is just released otherwise false.
+11 -6
View File
@@ -132,16 +132,18 @@ Phaser.Cache.prototype = {
* @param {object} data - Extra sprite sheet data. * @param {object} data - Extra sprite sheet data.
* @param {number} frameWidth - Width of the sprite sheet. * @param {number} frameWidth - Width of the sprite sheet.
* @param {number} frameHeight - Height of the sprite sheet. * @param {number} frameHeight - Height of the sprite sheet.
* @param {number} frameMax - How many frames stored in the sprite sheet. * @param {number} [frameMax=-1] - How many frames stored in the sprite sheet. If -1 then it divides the whole sheet evenly.
* @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
* @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
*/ */
addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax) { addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax, margin, spacing) {
this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight }; this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight, margin: margin, spacing: spacing };
PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data); PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data);
PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]); PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]);
this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax); this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax, margin, spacing);
}, },
@@ -339,6 +341,7 @@ Phaser.Cache.prototype = {
/** /**
* Reload a sound. * Reload a sound.
*
* @method Phaser.Cache#reloadSound * @method Phaser.Cache#reloadSound
* @param {string} key - Asset key for the sound. * @param {string} key - Asset key for the sound.
*/ */
@@ -359,7 +362,8 @@ Phaser.Cache.prototype = {
}, },
/** /**
* Description. * Fires the onSoundUnlock event when the sound has completed reloading.
*
* @method Phaser.Cache#reloadSoundComplete * @method Phaser.Cache#reloadSoundComplete
* @param {string} key - Asset key for the sound. * @param {string} key - Asset key for the sound.
*/ */
@@ -374,7 +378,8 @@ Phaser.Cache.prototype = {
}, },
/** /**
* Description. * Updates the sound object in the cache.
*
* @method Phaser.Cache#updateSound * @method Phaser.Cache#updateSound
* @param {string} key - Asset key for the sound. * @param {string} key - Asset key for the sound.
*/ */
+8 -3
View File
@@ -372,13 +372,17 @@ Phaser.Loader.prototype = {
* @param {number} frameWidth - Width of each single frame. * @param {number} frameWidth - Width of each single frame.
* @param {number} frameHeight - Height of each single frame. * @param {number} frameHeight - Height of each single frame.
* @param {number} [frameMax=-1] - How many frames in this sprite sheet. If not specified it will divide the whole image into frames. * @param {number} [frameMax=-1] - How many frames in this sprite sheet. If not specified it will divide the whole image into frames.
* @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
* @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
* @return {Phaser.Loader} This Loader instance. * @return {Phaser.Loader} This Loader instance.
*/ */
spritesheet: function (key, url, frameWidth, frameHeight, frameMax) { spritesheet: function (key, url, frameWidth, frameHeight, frameMax, margin, spacing) {
if (typeof frameMax === "undefined") { frameMax = -1; } if (typeof frameMax === "undefined") { frameMax = -1; }
if (typeof margin === "undefined") { margin = 0; }
if (typeof spacing === "undefined") { spacing = 0; }
this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax }); this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax, margin: margin, spacing: spacing });
return this; return this;
@@ -950,7 +954,7 @@ Phaser.Loader.prototype = {
case 'spritesheet': case 'spritesheet':
this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax); this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax, file.margin, file.spacing);
break; break;
case 'tileset': case 'tileset':
@@ -1038,6 +1042,7 @@ Phaser.Loader.prototype = {
if (buffer) if (buffer)
{ {
that.game.cache.decodedSound(key, buffer); that.game.cache.decodedSound(key, buffer);
that.game.sound.onSoundDecode.dispatch(key, that.game.cache.getSound(key));
} }
}); });
} }
+2 -2
View File
@@ -223,7 +223,7 @@ PIXI.InteractionManager.prototype.update = function()
// loop through interactive objects! // loop through interactive objects!
var length = this.interactiveItems.length; var length = this.interactiveItems.length;
this.interactionDOMElement.style.cursor = "default"; this.interactionDOMElement.style.cursor = "inherit";
for (var i = 0; i < length; i++) for (var i = 0; i < length; i++)
{ {
@@ -352,7 +352,7 @@ PIXI.InteractionManager.prototype.onMouseOut = function(event)
{ {
var length = this.interactiveItems.length; var length = this.interactiveItems.length;
this.interactionDOMElement.style.cursor = "default"; this.interactionDOMElement.style.cursor = "inherit";
for (var i = 0; i < length; i++) for (var i = 0; i < length; i++)
{ {
+4 -5
View File
@@ -374,6 +374,7 @@ PIXI.DisplayObject.prototype.addFilter = function(data)
//this.filter = true; //this.filter = true;
// data[0].target = this; // data[0].target = this;
// insert a filter block.. // insert a filter block..
// TODO Onject pool thease bad boys.. // TODO Onject pool thease bad boys..
var start = new PIXI.FilterBlock(); var start = new PIXI.FilterBlock();
@@ -391,7 +392,7 @@ PIXI.DisplayObject.prototype.addFilter = function(data)
start.open = true; start.open = true;
start.target = this; start.target = this;
/* /*
* insert start * insert start
*/ */
@@ -460,7 +461,6 @@ PIXI.DisplayObject.prototype.addFilter = function(data)
// if webGL... // if webGL...
if(this.__renderGroup) if(this.__renderGroup)
{ {
console.log('__renderGroup');
this.__renderGroup.addFilterBlocks(start, end); this.__renderGroup.addFilterBlocks(start, end);
} }
@@ -478,12 +478,11 @@ PIXI.DisplayObject.prototype.removeFilter = function(data)
//this.filter = false; //this.filter = false;
// console.log("YUOIO") // console.log("YUOIO")
// modify the list.. // modify the list..
var startBlock = data.start; var startBlock = data.start;
var nextObject = startBlock._iNext; var nextObject = startBlock._iNext;
var previousObject = startBlock._iPrev; var previousObject = startBlock._iPrev;
if(nextObject)nextObject._iPrev = previousObject; if(nextObject)nextObject._iPrev = previousObject;
if(previousObject)previousObject._iNext = nextObject; if(previousObject)previousObject._iNext = nextObject;
+18 -31
View File
@@ -214,43 +214,30 @@ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index)
*/ */
PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
{ {
/* if(child === child2) {
* this funtion needs to be recoded.. return;
* can be done a lot faster.. }
*/
return; var index1 = this.children.indexOf(child);
var index2 = this.children.indexOf(child2);
// need to fix this function :/ if(index1 < 0 || index2 < 0) {
/* throw new Error("swapChildren: Both the supplied DisplayObjects must be a child of the caller.");
// TODO I already know this?? }
var index = this.children.indexOf( child );
var index2 = this.children.indexOf( child2 ); this.removeChild(child);
this.removeChild(child2);
if ( index !== -1 && index2 !== -1 ) if(index1 < index2)
{ {
// cool this.addChildAt(child2, index1);
this.addChildAt(child, index2);
/*
if(this.stage)
{
// this is to satisfy the webGL batching..
// TODO sure there is a nicer way to achieve this!
this.stage.__removeChild(child);
this.stage.__removeChild(child2);
this.stage.__addChild(child);
this.stage.__addChild(child2);
}
// swap the positions..
this.children[index] = child2;
this.children[index2] = child;
} }
else else
{ {
throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this); this.addChildAt(child, index2);
}*/ this.addChildAt(child2, index1);
}
} }
/** /**
+33 -1
View File
@@ -71,6 +71,33 @@ PIXI.AssetLoader = function(assetURLs, crossorigin)
// constructor // constructor
PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader; PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
PIXI.AssetLoader.prototype._getDataType = function(str)
{
var test = "data:";
//starts with 'data:'
var start = str.slice(0, test.length).toLowerCase();
if (start == test) {
var data = str.slice(test.length);
var sepIdx = data.indexOf(',');
if (sepIdx === -1) //malformed data URI scheme
return null;
//e.g. "image/gif;base64" => "image/gif"
var info = data.slice(0, sepIdx).split(';')[0];
//We might need to handle some special cases here...
//standardize text/plain to "txt" file extension
if (!info || info.toLowerCase() == "text/plain")
return "txt"
//User specified mime type, try splitting it by '/'
return info.split('/').pop().toLowerCase();
}
return null;
}
/** /**
* Starts loading the assets sequentially * Starts loading the assets sequentially
* *
@@ -85,7 +112,12 @@ PIXI.AssetLoader.prototype.load = function()
for (var i=0; i < this.assetURLs.length; i++) for (var i=0; i < this.assetURLs.length; i++)
{ {
var fileName = this.assetURLs[i]; var fileName = this.assetURLs[i];
var fileType = fileName.split("?").shift().split(".").pop().toLowerCase(); //first see if we have a data URI scheme..
var fileType = this._getDataType(fileName);
//if not, assume it's a file URI
if (!fileType)
fileType = fileName.split("?").shift().split(".").pop().toLowerCase();
var loaderClass = this.loadersByType[fileType]; var loaderClass = this.loadersByType[fileType];
if(!loaderClass) if(!loaderClass)
+5 -4
View File
@@ -163,10 +163,11 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
if(displayObject instanceof PIXI.Sprite) if(displayObject instanceof PIXI.Sprite)
{ {
var frame = displayObject.texture.frame; var frame = displayObject.texture.frame;
if(frame && frame.width && frame.height) //ignore null sources
if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source)
{ {
context.globalAlpha = displayObject.worldAlpha; context.globalAlpha = displayObject.worldAlpha;
+1 -1
View File
@@ -65,7 +65,7 @@ PIXI.Text.prototype.setStyle = function(style)
/** /**
* Set the copy for the text object. To split a line you can use "\n" * Set the copy for the text object. To split a line you can use "\n"
* *
* @methos setText * @method setText
* @param {String} text The copy that you would like the text to display * @param {String} text The copy that you would like the text to display
*/ */
PIXI.Text.prototype.setText = function(text) PIXI.Text.prototype.setText = function(text)
+5
View File
@@ -91,6 +91,7 @@ PIXI.BaseTexture = function(source)
PIXI.texturesToUpdate.push(this); PIXI.texturesToUpdate.push(this);
} }
this.imageUrl = null;
this._powerOf2 = false; this._powerOf2 = false;
} }
@@ -105,6 +106,9 @@ PIXI.BaseTexture.prototype.destroy = function()
{ {
if(this.source instanceof Image) if(this.source instanceof Image)
{ {
if (this.imageUrl in PIXI.BaseTextureCache)
delete PIXI.BaseTextureCache[this.imageUrl];
this.imageUrl = null;
this.source.src = null; this.source.src = null;
} }
this.source = null; this.source = null;
@@ -147,6 +151,7 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
} }
image.src = imageUrl; image.src = imageUrl;
baseTexture = new PIXI.BaseTexture(image); baseTexture = new PIXI.BaseTexture(image);
baseTexture.imageUrl = imageUrl;
PIXI.BaseTextureCache[imageUrl] = baseTexture; PIXI.BaseTextureCache[imageUrl] = baseTexture;
} }
+1 -1
View File
@@ -27,7 +27,7 @@ PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
if(webgl) if(webgl)
{ {
var ie = (navigator.userAgent.toLowerCase().indexOf('msie') != -1); var ie = (navigator.userAgent.toLowerCase().indexOf('trident') != -1);
webgl = !ie; webgl = !ie;
} }
+5
View File
@@ -63,4 +63,9 @@ PIXI.EventTarget = function () {
}; };
this.removeAllEventListeners = function( type ) {
var a = listeners[type];
if (a)
a.length = 0;
};
}; };
+1 -1
View File
@@ -288,7 +288,7 @@ Phaser.SoundManager.prototype = {
that.game.cache.decodedSound(key, buffer); that.game.cache.decodedSound(key, buffer);
if (sound) if (sound)
{ {
that.onSoundDecode.dispatch(sound); that.onSoundDecode.dispatch(key, sound);
} }
}); });
} }
+29
View File
@@ -138,6 +138,12 @@ Phaser.Device = function () {
*/ */
this.typedArray = false; this.typedArray = false;
/**
* @property {boolean} vibration - Does the device support the Vibration API?
* @default
*/
this.vibration = false;
// Browser // Browser
/** /**
@@ -176,6 +182,18 @@ Phaser.Device = function () {
*/ */
this.ieVersion = 0; this.ieVersion = 0;
/**
* @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+)
* @default
*/
this.trident = false;
/**
* @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx
* @default
*/
this.tridentVersion = 0;
/** /**
* @property {boolean} mobileSafari - Set to true if running in Mobile Safari. * @property {boolean} mobileSafari - Set to true if running in Mobile Safari.
* @default * @default
@@ -400,6 +418,10 @@ Phaser.Device.prototype = {
this.opera = true; this.opera = true;
} else if (/Safari/.test(ua)) { } else if (/Safari/.test(ua)) {
this.safari = true; this.safari = true;
} else if (/Trident\/(\d+\.\d+);/.test(ua)) {
this.ie = true;
this.trident = true;
this.tridentVersion = parseInt(RegExp.$1, 10);
} }
// WebApp mode in iOS // WebApp mode in iOS
@@ -483,6 +505,13 @@ Phaser.Device.prototype = {
this.typedArray = false; this.typedArray = false;
} }
navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
if (navigator.vibrate)
{
this.vibration = true;
}
}, },
/** /**
+6 -6
View File
@@ -15,12 +15,12 @@ Phaser.TilemapParser = {
* Creates a Tileset object. * Creates a Tileset object.
* @method Phaser.TilemapParser.tileset * @method Phaser.TilemapParser.tileset
* @param {Phaser.Game} game - Game reference to the currently running game. * @param {Phaser.Game} game - Game reference to the currently running game.
* @param {string} key * @param {string} key - The Cache key of this tileset.
* @param {number} tileWidth * @param {number} tileWidth - Width of the sprite sheet.
* @param {number} tileHeight * @param {number} tileHeight - Height of the sprite sheet.
* @param {number} tileMax * @param {number} tileMax - How many tiles stored in the sprite sheet.
* @param {number} tileMargin * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here.
* @param {number} tileSpacing * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here.
* @return {Phaser.Tileset} Generated Tileset object. * @return {Phaser.Tileset} Generated Tileset object.
*/ */
tileset: function (game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) { tileset: function (game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) {
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

@@ -0,0 +1,338 @@
This tutorial is a follow-up to the TypeScript with Phaser <a href="http://www.photonstorm.com/phaser/how-to-use-phaser-with-typescript">beginners guide</a>. I will assume you have worked through that tutorial already and have a working set-up in which you can compile Phaser projects. From this base we will expand on the simple approach taken in the beginners guide and show how to structure a more advanced project that benefits from the power of TypeScript.
<h3>Create a new Project</h3>
In the first tutorial everything was hanging off a single <code>app.ts</code> file with one bundled class. This time around we're going to break it up into more individual classes. In Visual Studio create a new empty TypeScript project, then add the phaser TypeScript definition and JS library files to it as outlined in Step 2 in the first tutorial.
<a href="http://gametest.mobi/phaser/tutorials/04%20Advanced%20TypeScript%20Projects/assets.zip">Download this asset pack</a> and unzip it into the project folder. We'll reference these files in our code.
Create a new TypeScript file called <code>Game.ts</code> and add this code to it:
<pre class="lang:js decode:true " >
module Castlevania {
export class Game extends Phaser.Game {
constructor() {
super(800, 600, Phaser.AUTO, 'content', null);
this.state.add('Boot', Boot, false);
this.state.add('Preloader', Preloader, false);
this.state.add('MainMenu', MainMenu, false);
this.state.add('Level1', Level1, false);
this.state.start('Boot');
}
}
}
</pre>
Here we have created a new Module called <code>Castlevania</code> under which all of our game classes will live. Obviously you'd change this to whatever your game is actually called, unless you're genuinely working on a Castlevania game, in which case I'm eternally jealous :)
The <code>Game</code> class is extending <code>Phaser.Game</code>. As a result we need to call super in the constructor and pass in our game settings. Once done we add 4 States to the game: Boot, Preloader, MainMenu and Level1, and then start the Boot state. You don't have to add ALL of the States at this point, but there is no harm in doing so.
<!--more-->
When adding this code in Visual Studio you may notice that Boot, Preload, MainMenu, and Level1 are underlined in red. This is because they don't yet exist within the Project.
<a href="http://www.photonstorm.com/wp-content/uploads/2013/12/part11.png"><img src="http://www.photonstorm.com/wp-content/uploads/2013/12/part11.png" alt="part1" width="1327" height="971" class="alignnone size-full wp-image-13669" /></a>
<h3>Let's Boot</h3>
Create a new TypeScript file called <code>Boot.ts</code> and paste this code in:
<pre class="lang:js decode:true " >
module Castlevania {
export class Boot extends Phaser.State {
preload() {
this.load.image('preloadBar', 'assets/loader.png');
}
create() {
// Unless you specifically need to support multitouch I would recommend setting this to 1
this.input.maxPointers = 1;
// Phaser will automatically pause if the browser tab the game is in loses focus. You can disable that here:
this.stage.disableVisibilityChange = true;
if (this.game.device.desktop) {
// If you have any desktop specific settings, they can go in here
this.stage.scale.pageAlignHorizontally = true;
}
else {
// Same goes for mobile settings.
}
this.game.state.start('Preloader', true, false);
}
}
}
</pre>
Our <code>Boot</code> class is where we define global settings for the game. It's also were we preload the graphics that will be used by the actual Preloader, in this case a simple loading bar image.
The <code>create</code> function is called after the image has loaded. In the code above you can see that we're setting the maximum number of pointers to 1 and disabling the 'pause' checks. This isn't a require of Phaser, it's just a good example of the sort of things that go into a common Boot script. This is also where you would define how the game handles scaling. For example if this was aimed at mobile and needed to run at iPad resolution (1024x672) then we would usually add the following code into the 'mobile settings' part of the class:
<pre class="lang:js decode:true " >// In this case we're saying "scale the game, no lower than 480x260 and no higher than 1024x768"
this.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL;
this.stage.scale.minWidth = 480;
this.stage.scale.minHeight = 260;
this.stage.scale.maxWidth = 1024;
this.stage.scale.maxHeight = 768;
this.stage.scale.forceLandscape = true;
this.stage.scale.pageAlignHorizontally = true;
this.stage.scale.setScreenSize(true);
</pre>
The code above isn't needed for this tutorial however.
When all of this has finished Phaser swaps to the <code>Preloader</code> state.
<h3>Creating our Preloader, extending a Phaser.State</h3>
Create a new TypeScript file called <code>Preloader.ts</code> and paste the following code in:
<pre class="lang:js decode:true " >module Castlevania {
export class Preloader extends Phaser.State {
preloadBar: Phaser.Sprite;
preload() {
// Set-up our preloader sprite
this.preloadBar = this.add.sprite(200, 250, 'preloadBar');
this.load.setPreloadSprite(this.preloadBar);
// Load our actual games assets
this.load.image('titlepage', 'assets/titlepage.jpg');
this.load.image('logo', 'assets/logo.png');
this.load.audio('music', 'assets/title.mp3', true);
this.load.spritesheet('simon', 'assets/simon.png', 58, 96, 5);
this.load.image('level1', 'assets/level1.png');
}
create() {
var tween = this.add.tween(this.preloadBar).to({ alpha: 0 }, 1000, Phaser.Easing.Linear.None, true);
tween.onComplete.add(this.startMainMenu, this);
}
startMainMenu() {
this.game.state.start('MainMenu', true, false);
}
}
}
</pre>
This class is extending <a href="http://gametest.mobi/phaser/docs/Phaser.State.html">Phaser.State</a>. This means you've got instant access to all the properties of the State object. Phaser uses a set of specially named functions to perform tasks, one of which is <code>preload</code>. Inside here we can queue calls to Phasers asset loader. As you can see in the code above we're loading a variety of assets: some images, a sprite sheet and an mp3.
We also create a sprite called <code>preloadBar</code> and link it to the asset loader. It will be automatically cropped as the files load in, making the effect of a preloader bar increasing over time as each file completes:
<a href="http://www.photonstorm.com/wp-content/uploads/2013/12/part21.png"><img src="http://www.photonstorm.com/wp-content/uploads/2013/12/part21.png" alt="part2" width="800" height="600" class="alignnone size-full wp-image-13674" /></a>
When the load is finished the <code>create</code> function is called, which is when we fade the preload bar away. On completion of that tween we start the main menu. If you run the game locally you probably won't even see the preload bar fill-up as the assets will load from the local filesystem too fast to be noticed, but once out in the wild this won't be an issue and it'll be important to offer a decent looking preloader screen.
Once everything has finished we start the <code>MainMenu</code>.
<h3>The Main Menu</h3>
For this tutorial our menu is a picture and a game logo with a couple of simple tweens. Obviously you'll want to enhance this for your own games, but it serves our purpose here. Create a new file called <code>MainMenu.ts</code> and paste this code in:
<pre class="lang:js decode:true " >module Castlevania {
export class MainMenu extends Phaser.State {
background: Phaser.Sprite;
logo: Phaser.Sprite;
create() {
this.background = this.add.sprite(0, 0, 'titlepage');
this.background.alpha = 0;
this.logo = this.add.sprite(this.world.centerX, -300, 'logo');
this.logo.anchor.setTo(0.5, 0.5);
this.add.tween(this.background).to({ alpha: 1}, 2000, Phaser.Easing.Bounce.InOut, true);
this.add.tween(this.logo).to({ y: 220 }, 2000, Phaser.Easing.Elastic.Out, true, 2000);
this.input.onDown.addOnce(this.fadeOut, this);
}
fadeOut() {
this.add.tween(this.background).to({ alpha: 0 }, 2000, Phaser.Easing.Linear.None, true);
var tween = this.add.tween(this.logo).to({ y: 800 }, 2000, Phaser.Easing.Linear.None, true);
tween.onComplete.add(this.startGame, this);
}
startGame() {
this.game.state.start('Level1', true, false);
}
}
}</pre>
I won't explain all of it because it should start becoming quite familiar by now. A couple of Sprites, tweens to make them appear. Then the game waits for an input event before fading out and starting the Level1 class. When you run it the menu will look like this:
<a href="http://www.photonstorm.com/wp-content/uploads/2013/12/part3.jpg"><img src="http://www.photonstorm.com/wp-content/uploads/2013/12/part3.jpg" alt="part3" width="800" height="600" class="alignnone size-full wp-image-13675" /></a>
Not too bad :)
<h3>Extending Phaser.Sprite</h3>
Create a new TypeScript file called <code>Level1.ts</code> and add this code to it:
<pre class="lang:js decode:true " >module Castlevania {
export class Level1 extends Phaser.State {
background: Phaser.Sprite;
music: Phaser.Sound;
player: Castlevania.Player;
create() {
this.background = this.add.sprite(0, 0, 'level1');
this.music = this.add.audio('music', 1, false);
this.music.play();
this.player = new Player(this.game, 130, 284);
}
}
} </pre>
We aren't going to cover creating a fully working game here, but I do want to use this file to highlight extending Phaser Sprites. In the code above you'll see a local variable called <code>player</code> that is an instance of Castlevania.Player. Create a new TypeScript file called Player.ts and paste this code in:
<pre class="lang:js decode:true " >module Castlevania {
export class Player extends Phaser.Sprite {
constructor(game: Phaser.Game, x: number, y: number) {
super(game, x, y, 'simon', 0);
this.anchor.setTo(0.5, 0);
this.animations.add('walk', [0, 1, 2, 3, 4], 10, true);
game.add.existing(this);
}
update() {
this.body.velocity.x = 0;
if (this.game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
this.body.velocity.x = -150;
this.animations.play('walk');
if (this.scale.x == 1) {
this.scale.x = -1;
}
}
else if (this.game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
this.body.velocity.x = 150;
this.animations.play('walk');
if (this.scale.x == -1) {
this.scale.x = 1;
}
}
else {
this.animations.frame = 0;
}
}
}
}</pre>
Here our Player object is extending <a href="http://gametest.mobi/phaser/docs/Phaser.Sprite.html">Phaser.Sprite</a>. As a result we have direct access to all Sprite properties from within it, which is why we can set the velocity directly on the body for example. Upon instantiation a few visual properties are set and an animation walk cycle added. Finally the sprite is added to the game world via <code>game.add.existing(this)</code>.
Once the sprite is added to the game world its update function will be called every frame. So to take advantage of this we set the players velocity if the left or right arrow keys are held down. As you'd expect this allows you to make the player walk left or right and animate accordingly. The end result looks like this:
<a href="http://www.photonstorm.com/wp-content/uploads/2013/12/part42.png"><img src="http://www.photonstorm.com/wp-content/uploads/2013/12/part42.png" alt="part4" width="800" height="600" class="alignnone size-full wp-image-13677" /></a>
We didn't have to check for input within the Player class. We could have added an update function to the Level1 class instead and then told the Player to move as a result of that, but it highlighted an important choice: it's up to you how your code is structured. So long as you adhere to a few basic rules and remember the names of the special Phaser functions, you can achieve pretty much any set-up you require or are familiar with.
<h3>Compiling to a single JS file</h3>
I'm sure you are keen to try out the project, but first let's make a couple of small but vital tweaks so we can build it. Enter the Project properties by selecting <code>Properties</code> from the Project menu. Then click the <strong>TypeScript Build</strong> category on the left and change the settings to match this:
<a href="http://www.photonstorm.com/wp-content/uploads/2013/12/part52.png"><img src="http://www.photonstorm.com/wp-content/uploads/2013/12/part52.png" alt="part5" width="831" height="731" class="alignnone size-full wp-image-13678" /></a>
The important things to do are:
<ul>
<li>Make sure the ECMAScript version is set to ECMAScript 5.</li>
<li>Set the Module system to None</li>
<li>Check 'Combine JavaScript output into file' and enter 'game.js' as the filename</li>
</ul>
Save the changes to the Project Properties. What we've done is make sure that the whole project will be compiled into a single JavaScript file called <code>game.js</code>. This won't include Phaser but it will include all of your game code. The last couple of changes we need to make are to the <code>default.htm</code> and <code>app.ts</code> files:
<pre class="lang:xhtml decode:true " >&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="utf-8" /&gt;
&lt;title&gt;TypeScript HTML App&lt;/title&gt;
&lt;link rel="stylesheet" href="app.css" type="text/css" /&gt;
&lt;script src="phaser.js"&gt;&lt;/script&gt;
&lt;script src="game.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;TypeScript HTML App&lt;/h1&gt;
&lt;div id="content"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
Here we've included the single output file <code>game.js</code>. And <code>app.ts</code> is reduced to simply this:
<pre class="lang:js decode:true " >
window.onload = () =&gt; {
var game = new Castlevania.Game();
};</pre>
With all of these files in place you should be able to compile and build the project. And with it you should have a pretty good base from which to build out a complete future game. You can also download all of the <a href="http://gametest.mobi/phaser/tutorials/04%20Advanced%20TypeScript%20Projects/visualstudio_project.zip">Visual Studio project files</a>. We've more Phaser tutorials coming, so keep an eye out for them and subscribe to our <a href="https://confirmsubscription.com/h/r/369DE48E3E86AF1E">Phaser newsletter</a> for details.
Castlevania is &copy; Copyright Konami 1988. All rights reserved and is used for illustration purposes only.
Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB