diff --git a/README.md b/README.md index c75db05c..c50d708c 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Version 1.1.4 - "Kandor" - In development Significant API changes: -* Loader.tileset has a new method signature. Please use the new format: load.tileset(key, url, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total). +* Loader.tileset has been removed as it's no longer required, this was as part of the Tilemap system overhaul. * TilemapLayers are now created via the Tilemap object itself: map.createLayer(x, y, width, height, tileset, layer, group) and no longer via the GameObjectFactory. * Tilemap.createFromObjects can now turn a bunch of Tiled objects into Sprites in one single call, and copies across all properties as well. * Tween.onStartCallback and onCompleteCallback have been removed to avoid confusion. You should use the onStart, onLoop and onComplete events instead. @@ -54,8 +54,8 @@ Significant API changes: New features: -* Gamepad API support has been added with lots of new examples showing how to use it (thanks Karl Macklin) -* Phaser.Game constructor can now be passed a single object containing game settings + Stage settings, useful for advanced configurations. +* Gamepad API support has been added with lots of new examples (thanks Karl Macklin) +* Phaser.Game constructor can now be passed a single object containing all of your game settings + Stage settings. Useful for advanced configurations. * The width/height given to Phaser.Game can now be percentages, i.e. "100%" will set the width to the maximum window innerWidth. * Added a stage.fullScreenScaleMode property to determine scaling when fullscreen (thanks oysterCrusher) * Added support for margin and spacing around a frame in Loader.spritesheet. @@ -83,6 +83,9 @@ New Examples: * Tweens - Example showing how to use the tween events, onStart, onLoop and onComplete. * Display - Pixi Render Texture. A Phaser conversion of the Pixi.js Render Texture example. * Input - 5 new examples showing how to use the Gamepad API (thanks Karl Macklin) +* Animation - Group Creation, showing how to create animations across all Group children in one call. +* Particles - Rain by Jens Anders Bakke. +* Particles - Snow by Jens Anders Bakke. Updates: @@ -128,7 +131,8 @@ Bug Fixes: * Canvas.addToDOM is now more robust when applying the overflowHidden style. * Fixed Pixi.StripShader which should stop the weird TileSprite GPU issues some were reporting (thanks GoodboyDigital) * Patched desyrel.xml so it doesn't contain any zero width/height characters, as they broke Firefox 25. - +* Cache.addSound now implements a locked attribute (thanks haden) +* Sound now checks for CocoonJS during playback to avoid readyState clash (thanks haden) You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md diff --git a/bower.json b/bower.json index 74bd4116..70ab4e24 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "phaser", - "version": "1.1.3", + "version": "1.1.4", "homepage": "http://phaser.io", "authors": [ "photonstorm " diff --git a/examples/_site/examples.json b/examples/_site/examples.json index 2036beff..afbee69a 100644 --- a/examples/_site/examples.json +++ b/examples/_site/examples.json @@ -4,6 +4,10 @@ "file": "change+texture+on+click.js", "title": "change texture on click" }, + { + "file": "group+creation.js", + "title": "group creation" + }, { "file": "local+json+object.js", "title": "local json object" @@ -542,10 +546,18 @@ "file": "no+rotation.js", "title": "no rotation" }, + { + "file": "rain.js", + "title": "rain" + }, { "file": "random+sprite.js", "title": "random sprite" }, + { + "file": "snow.js", + "title": "snow" + }, { "file": "when+particles+collide.js", "title": "when particles collide" diff --git a/examples/animation/group creation.js b/examples/animation/group creation.js new file mode 100644 index 00000000..ee575536 --- /dev/null +++ b/examples/animation/group creation.js @@ -0,0 +1,40 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.atlas('seacreatures', 'assets/sprites/seacreatures_json.png', 'assets/sprites/seacreatures_json.json'); + game.load.image('undersea', 'assets/pics/undersea.jpg'); + game.load.image('coral', 'assets/pics/seabed.png'); + +} + +function create() { + + game.add.sprite(0, 0, 'undersea'); + + // Here we create our group and populate it with 6 sprites + var group = game.add.group(); + + for (var i = 0; i < 6; i++) + { + // They are evenly spaced out on the X coordinate, with a random Y coordinate + sprite = group.create(120 * i, game.rnd.integerInRange(100, 400), 'seacreatures', 'octopus0000'); + } + + // These are the frame names for the octopus animation. We use the generateFrames function to help create the array. + var frameNames = Phaser.Animation.generateFrameNames('octopus', 0, 24, '', 4); + + // Here is the important part. Group.callAll will call a method that exists on every child in the Group. + // In this case we're saying: child.animations.add('swim', frameNames, 30, true, false) + // The second parameter ('animations') is really important and is the context in which the method is called. + // For animations the context is the Phaser.AnimationManager, which is linked to the child.animations property. + // Everything after the 2nd parameter is just the usual values you'd pass to the animations.add method. + group.callAll('animations.add', 'animations', 'swim', frameNames, 30, true, false); + + // Here we just say 'play the swim animation', this time the 'play' method exists on the child itself, so we can set the context to null. + group.callAll('play', null, 'swim'); + + game.add.sprite(0, 466, 'coral'); + +} diff --git a/examples/assets/sprites/rain.png b/examples/assets/sprites/rain.png new file mode 100644 index 00000000..d9a944df Binary files /dev/null and b/examples/assets/sprites/rain.png differ diff --git a/examples/assets/sprites/snowflakes.png b/examples/assets/sprites/snowflakes.png new file mode 100644 index 00000000..caf98ae8 Binary files /dev/null and b/examples/assets/sprites/snowflakes.png differ diff --git a/examples/assets/sprites/snowflakes_large.png b/examples/assets/sprites/snowflakes_large.png new file mode 100644 index 00000000..b8811128 Binary files /dev/null and b/examples/assets/sprites/snowflakes_large.png differ diff --git a/examples/groups/for each.js b/examples/groups/for each.js index 705422d3..0e6e177b 100644 --- a/examples/groups/for each.js +++ b/examples/groups/for each.js @@ -1,7 +1,7 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); -var baseAlphaIncSpeed= 0.006; +var baseAlphaIncSpeed = 0.006; function preload() { game.load.spritesheet('item', 'assets/buttons/number-buttons-90x90.png', 90, 90); diff --git a/examples/particles/rain.js b/examples/particles/rain.js new file mode 100644 index 00000000..06aa3dae --- /dev/null +++ b/examples/particles/rain.js @@ -0,0 +1,27 @@ +// This example was created by Jens Anders Bakke + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.spritesheet('rain', 'assets/sprites/rain.png', 17, 17); + +} + +function create() { + + var emitter = game.add.emitter(game.world.centerX, 0, 400); + emitter.width = game.world.width; + // emitter.angle = 30; // uncomment to set an angle for the rain. + + emitter.makeParticles('rain'); + emitter.maxParticleScale = 0.5; + emitter.minParticleScale = 0.1; + emitter.setYSpeed(300, 500); + emitter.setXSpeed(-5, 5); + emitter.minRotation = 0; + emitter.maxRotation = 0; + + emitter.start(false, 1600, 5, 0); + +} diff --git a/examples/particles/snow.js b/examples/particles/snow.js new file mode 100644 index 00000000..5dafe04a --- /dev/null +++ b/examples/particles/snow.js @@ -0,0 +1,100 @@ +// This example was created by Jens Anders Bakke + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.spritesheet('snowflakes', 'assets/sprites/snowflakes.png', 17, 17); + game.load.spritesheet('snowflakes_large', 'assets/sprites/snowflakes_large.png', 64, 64); + +} + +var max = 0; +var front_emitter; +var mid_emitter; +var back_emitter; +var update_interval = 4 * 60; +var i = 0; + +function create() { + + back_emitter = game.add.emitter(game.world.centerX, -32, 600); + back_emitter.makeParticles('snowflakes', [0, 1, 2, 3, 4, 5]); + back_emitter.maxParticleScale = 0.6; + back_emitter.minParticleScale = 0.2; + back_emitter.setYSpeed(20, 100); + back_emitter.gravity = 0; + back_emitter.width = game.world.width * 1.5; + back_emitter.minRotation = 0; + back_emitter.maxRotation = 40; + + + mid_emitter = game.add.emitter(game.world.centerX, -32, 250); + mid_emitter.makeParticles('snowflakes', [0, 1, 2, 3, 4, 5]); + mid_emitter.maxParticleScale = 1.2; + mid_emitter.minParticleScale = 0.8; + mid_emitter.setYSpeed(50, 150); + mid_emitter.gravity = 0; + mid_emitter.width = game.world.width * 1.5; + mid_emitter.minRotation = 0; + mid_emitter.maxRotation = 40; + + + front_emitter = game.add.emitter(game.world.centerX, -32, 50); + front_emitter.makeParticles('snowflakes_large', [0, 1, 2, 3, 4, 5]); + front_emitter.maxParticleScale = 1; + front_emitter.minParticleScale = 0.5; + front_emitter.setYSpeed(100, 200); + front_emitter.gravity = 0; + front_emitter.width = game.world.width * 1.5; + front_emitter.minRotation = 0; + front_emitter.maxRotation = 40; + + changeWindDirection(); + + back_emitter.start(false, 14000, 20); + mid_emitter.start(false, 12000, 40); + front_emitter.start(false, 6000, 1000); + +} + +function update() { + + i++; + + if (i === update_interval) + { + changeWindDirection(); + update_interval = Math.floor(Math.random() * 20) * 60; // 0 - 20sec @ 60fps + i = 0; + } + +} + +function changeWindDirection() { + + var multi = Math.floor((max + 200) / 4), + frag = (Math.floor(Math.random() * 100) - multi); + max = max + frag; + + if (max > 200) max = 150; + if (max < -200) max = -150; + + setXSpeed(back_emitter, max); + setXSpeed(mid_emitter, max); + setXSpeed(front_emitter, max); + +} + +function setXSpeed(emitter, max) { + + emitter.setXSpeed(max - 20, max); + emitter.forEachAlive(setParticleXSpeed, this, max); + +} + +function setParticleXSpeed(particle, max) { + + particle.body.velocity.x = max - Math.floor(Math.random() * 30); + +} diff --git a/examples/wip/group call all.js b/examples/wip/group call all.js new file mode 100644 index 00000000..f06b22ef --- /dev/null +++ b/examples/wip/group call all.js @@ -0,0 +1,31 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.atlas('seacreatures', 'assets/sprites/seacreatures_json.png', 'assets/sprites/seacreatures_json.json'); + game.load.image('undersea', 'assets/pics/undersea.jpg'); + game.load.image('coral', 'assets/pics/seabed.png'); + +} + +function create() { + + game.add.sprite(0, 0, 'undersea'); + + var group = game.add.group(); + + for (var i = 0; i < 6; i++) + { + sprite = group.create(120 * i, game.rnd.integerInRange(100, 400), 'seacreatures', 'octopus0000'); + } + + var frameNames = Phaser.Animation.generateFrameNames('octopus', 0, 24, '', 4); + + group.callAll('animations.add', 'animations', 'swim', frameNames, 30, true, false); + + group.callAll('play', null, 'swim'); + + game.add.sprite(0, 466, 'coral'); + +} diff --git a/examples/wip/mod.js b/examples/wip/mod.js index d244e0e6..0fc25ae0 100644 --- a/examples/wip/mod.js +++ b/examples/wip/mod.js @@ -56,7 +56,8 @@ function create() { // vu4 = game.add.sprite(400, 250, 'vu3'); module = new Protracker(); - module.buffer = game.cache.getBinary('globaltrash'); +// module.buffer = game.cache.getBinary('globaltrash'); + module.buffer = game.cache.getBinary('macrocosm'); module.parse(); module.play(); diff --git a/src/core/Group.js b/src/core/Group.js index 8763afff..51b12c90 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -223,7 +223,7 @@ Phaser.Group.prototype = { */ create: function (x, y, key, frame, exists) { - if (typeof exists == 'undefined') { exists = true; } + if (typeof exists === 'undefined') { exists = true; } var child = new Phaser.Sprite(this.game, x, y, key, frame); @@ -263,7 +263,7 @@ Phaser.Group.prototype = { */ createMultiple: function (quantity, key, frame, exists) { - if (typeof exists == 'undefined') { exists = false; } + if (typeof exists === 'undefined') { exists = false; } for (var i = 0; i < quantity; i++) { @@ -805,7 +805,7 @@ Phaser.Group.prototype = { }, /** - * Calls a function on all of the children that have exists=true in this Group. + * Returns a reference to a function that exists on a child of the Group based on the given callback array. * * @method Phaser.Group#callbackFromArray * @param {object} child - The object to inspect. @@ -863,7 +863,7 @@ Phaser.Group.prototype = { * * @method Phaser.Group#callAll * @param {string} method - A string containing the name of the function that will be called. The function must exist on the child. - * @param {string} [context=''] - A string containing the context under which the method will be executed. Leave to '' to default to the child. + * @param {string} [context=null] - A string containing the context under which the method will be executed. Set to null to default to the child. * @param {...*} parameter - Additional parameters that will be passed to the method. */ callAll: function (method, context) { diff --git a/src/loader/Cache.js b/src/loader/Cache.js index 60553472..ad5a51bc 100644 --- a/src/loader/Cache.js +++ b/src/loader/Cache.js @@ -320,7 +320,7 @@ Phaser.Cache.prototype = { decoded = true; } - this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag }; + this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag, locked: this.game.sound.touchLocked }; }, diff --git a/src/sound/Sound.js b/src/sound/Sound.js index f3c79d74..9e8d7389 100644 --- a/src/sound/Sound.js +++ b/src/sound/Sound.js @@ -552,7 +552,7 @@ Phaser.Sound.prototype = { else { // console.log('sound not locked, state?', this._sound.readyState); - if (this._sound && this._sound.readyState == 4) + if (this._sound && (this.game.device.cocoonJS || this._sound.readyState === 4)) { this._sound.play(); // This doesn't become available until you call play(), wonderful ...