From c00bf9660391ac8a68aa206d7d11bd9f84e0c240 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Fri, 4 Oct 2013 16:51:24 +0100 Subject: [PATCH] World and Camera updates nearly complete. --- README.md | 6 +- examples/world/move around world.php | 24 ++-- src/core/Camera.js | 6 +- src/core/Game.js | 4 +- src/core/Group.js | 7 +- src/core/World.js | 191 +++++++++++++-------------- src/gameobjects/GameObjectFactory.js | 27 ++-- 7 files changed, 135 insertions(+), 130 deletions(-) diff --git a/README.md b/README.md index d317a9ae..dd6d0c26 100644 --- a/README.md +++ b/README.md @@ -81,12 +81,14 @@ Version 1.0.7 (in progress in the dev branch) * Fixed Cache.addDefaultImage so the default image works in Canvas as well as WebGL. Updated to a new image (32x32 black square with green outline) * Extended the Loader 404 error to display the url of the file that didn't load as well as the key. * Change: We've removed the scrollFactor property from all Game Objects. Sorry, but the new Camera system doesn't work with it and it caused all kinds of issues anyway. We will sort out a replacement for it at a later date. -* Change: The Camera has been completely revamped. +* Change: World now extends Phaser.Group. As a result we've updated GameObjectFactory and other classes that linked to it. If you have anywhere in your code that used to reference world.group you can just remove 'group' from that. So before, world.group.add() is now just world.add(). +* Change: The Camera has been completely revamped. Rather than adjusting the position of all display objects (bad) it now just shifts the position of the single world container (good!), this is much quicker and also stops the game objects positions from self-adjusting all the time, allowing for them to be properly nested with other containers. +* New: Direction constants have been added to Sprites and adjust based on body motion. Access them via +* World.randomX/Y now returns values anywhere in the world.bounds range (if set, otherwise 0), including negative values. * TODO: addMarker hh:mm:ss:ms * TODO: Direction constants -* TODO: Camera will adjust core DO. Means scrollFactor will need to be dropped sadly, but there are other ways to emulate its effect. Version 1.0.6 (September 24th 2013) diff --git a/examples/world/move around world.php b/examples/world/move around world.php index adc02a99..18aab068 100644 --- a/examples/world/move around world.php +++ b/examples/world/move around world.php @@ -13,9 +13,8 @@ window.onload = function () { function preload() { - // game.world.setSize(1920, 1200); + game.stage.backgroundColor = '#007236'; - game.load.image('backdrop', 'assets/pics/remember-me.jpg'); game.load.image('mushroom', 'assets/sprites/mushroom.png'); game.load.image('phaser', 'assets/sprites/sonic_havok_sanity.png'); @@ -26,21 +25,20 @@ window.onload = function () { function create() { - game.add.sprite(0, 0, 'backdrop'); - + // Modify the world and camera bounds + game.world.setBounds(-1000, -1000, 2000, 2000); + for (var i = 0; i < 100; i++) { - game.add.sprite(game.world.randomX, game.world.randomY, 'mushroom'); + var s = game.add.sprite(game.world.randomX, game.world.randomY, 'mushroom'); + console.log(s.x, s.y); } - d = game.add.sprite(200, 200, 'phaser'); + d = game.add.sprite(0, 0, 'phaser'); d.anchor.setTo(0.5, 0.5); cursors = game.input.keyboard.createCursorKeys(); - console.log(game.camera.displayObject.length); - // console.log(game.camera.displayObject.children[0].name); - } function update() { @@ -72,7 +70,7 @@ window.onload = function () { { if (cursors.left.shiftKey) { - game.camera.displayObject.rotation -= 0.05; + game.world.rotation -= 0.05; } else { @@ -83,7 +81,7 @@ window.onload = function () { { if (cursors.right.shiftKey) { - game.camera.displayObject.rotation += 0.05; + game.world.rotation += 0.05; } else { @@ -96,8 +94,8 @@ window.onload = function () { function render() { game.debug.renderCameraInfo(game.camera, 32, 32); - game.debug.renderWorldTransformInfo(d, 32, 200); - game.debug.renderLocalTransformInfo(d, 32, 400); + // game.debug.renderWorldTransformInfo(d, 32, 200); + // game.debug.renderLocalTransformInfo(d, 32, 400); game.debug.renderSpriteCorners(d, false, true); } diff --git a/src/core/Camera.js b/src/core/Camera.js index d0aff3c3..7eda4317 100644 --- a/src/core/Camera.js +++ b/src/core/Camera.js @@ -180,8 +180,6 @@ Phaser.Camera.prototype = { this.updateTarget(); } - this.updateTarget(); - if (this.bounds) { this.checkBounds(); @@ -325,7 +323,7 @@ Object.defineProperty(Phaser.Camera.prototype, "x", { set: function (value) { this.view.x = value; - this.displayObject.x = -value; + this.displayObject.position.x = -value; if (this.bounds) { @@ -349,7 +347,7 @@ Object.defineProperty(Phaser.Camera.prototype, "y", { set: function (value) { this.view.y = value; - this.displayObject.y = -value; + this.displayObject.position.y = -value; if (this.bounds) { diff --git a/src/core/Game.js b/src/core/Game.js index 14abf519..2aa26f8f 100644 --- a/src/core/Game.js +++ b/src/core/Game.js @@ -297,14 +297,14 @@ Phaser.Game.prototype = { this.net = new Phaser.Net(this); this.debug = new Phaser.Utils.Debug(this); - this.load.onLoadComplete.add(this.loadComplete, this); - this.stage.boot(); this.world.boot(); this.input.boot(); this.sound.boot(); this.state.boot(); + this.load.onLoadComplete.add(this.loadComplete, this); + if (this.renderType == Phaser.CANVAS) { console.log('%cPhaser ' + Phaser.VERSION + ' initialized. Rendering to Canvas', 'color: #ffff33; background: #000000'); diff --git a/src/core/Group.js b/src/core/Group.js index a27216f3..014f9296 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -70,7 +70,12 @@ Phaser.Group = function (game, parent, name, useStage) { * @default */ this.exists = true; - + + /** + * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. + */ + this.scale = new Phaser.Point(1, 1); + }; Phaser.Group.prototype = { diff --git a/src/core/World.js b/src/core/World.js index 5a424a6a..354a3fb9 100644 --- a/src/core/World.js +++ b/src/core/World.js @@ -17,10 +17,12 @@ */ Phaser.World = function (game) { + Phaser.Group.call(this, game, null, '__world', false); + /** - * @property {Phaser.Game} game - A reference to the currently running Game. - */ - this.game = game; + * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. + */ + this.scale = new Phaser.Point(1, 1); /** * The World has no fixed size, but it does have a bounds outside of which objects are no longer considered as being "in world" and you should use this to clean-up the display list and purge dead objects. @@ -41,120 +43,117 @@ Phaser.World = function (game) { */ this.currentRenderOrderID = 0; - /** - * @property {Phaser.Group} group - Object container stores every object created with `create*` methods. - */ - this.group = null; - }; -Phaser.World.prototype = { +Phaser.World.prototype = Object.create(Phaser.Group.prototype); +Phaser.World.prototype.constructor = Phaser.World; - /** - * Initialises the game world. - * - * @method Phaser.World#boot - * @protected - */ - boot: function () { +/** +* Initialises the game world. +* +* @method Phaser.World#boot +* @protected +*/ +Phaser.World.prototype.boot = function () { - this.group = new Phaser.Group(this.game, null, '__world'); + this.camera = new Phaser.Camera(this.game, 0, 0, 0, this.game.width, this.game.height); - this.camera = new Phaser.Camera(this.game, 0, 0, 0, this.game.width, this.game.height); - this.camera.displayObject = this.group; + this.camera.displayObject = this._container; - this.game.camera = this.camera; + this.game.camera = this.camera; - }, +} - /** - * This is called automatically every frame, and is where main logic happens. - * - * @method Phaser.World#update - */ - update: function () { +/** +* This is called automatically every frame, and is where main logic happens. +* +* @method Phaser.World#update +*/ +Phaser.World.prototype.update = function () { - this.camera.update(); + this.camera.update(); - this.currentRenderOrderID = 0; + this.currentRenderOrderID = 0; - if (this.game.stage._stage.first._iNext) + if (this.game.stage._stage.first._iNext) + { + var currentNode = this.game.stage._stage.first._iNext; + + do { - var currentNode = this.game.stage._stage.first._iNext; - - do + if (currentNode['preUpdate']) { - if (currentNode['preUpdate']) - { - currentNode.preUpdate(); - } - - if (currentNode['update']) - { - currentNode.update(); - } - - currentNode = currentNode._iNext; + currentNode.preUpdate(); } - while (currentNode != this.game.stage._stage.last._iNext) + + if (currentNode['update']) + { + currentNode.update(); + } + + currentNode = currentNode._iNext; } + while (currentNode != this.game.stage._stage.last._iNext) + } - }, +} - /** - * This is called automatically every frame, and is where main logic happens. - * @method Phaser.World#postUpdate - */ - postUpdate: function () { +/** +* This is called automatically every frame, and is where main logic happens. +* @method Phaser.World#postUpdate +*/ +Phaser.World.prototype.postUpdate = function () { - if (this.game.stage._stage.first._iNext) + if (this.game.stage._stage.first._iNext) + { + var currentNode = this.game.stage._stage.first._iNext; + + do { - var currentNode = this.game.stage._stage.first._iNext; - - do + if (currentNode['postUpdate']) { - if (currentNode['postUpdate']) - { - currentNode.postUpdate(); - } - - currentNode = currentNode._iNext; + currentNode.postUpdate(); } - while (currentNode != this.game.stage._stage.last._iNext) + + currentNode = currentNode._iNext; } - - }, - - /** - * Updates the size of this world. Note that this doesn't modify the world x/y coordinates, just the width and height. - * If you need to adjust the bounds of the world - * @method Phaser.World#setSize - * @param {number} width - New width of the world. - * @param {number} height - New height of the world. - */ - setSize: function (width, height) { - - this.bounds.width = width; - this.bounds.height = height; - - }, - - /** - * Destroyer of worlds. - * @method Phaser.World#destroy - */ - destroy: function () { - - this.camera.x = 0; - this.camera.y = 0; - - this.game.input.reset(true); - - this.group.removeAll(); - + while (currentNode != this.game.stage._stage.last._iNext) } - -}; + +} + +/** +* Updates the size of this world. Note that this doesn't modify the world x/y coordinates, just the width and height. +* If you need to adjust the bounds of the world +* @method Phaser.World#setSize +* @param {number} width - New width of the world. +* @param {number} height - New height of the world. +*/ +Phaser.World.prototype.setBounds = function (x, y, width, height) { + + this.bounds.setTo(x, y, width, height); + + if (this.camera.bounds) + { + this.camera.bounds.setTo(x, y, width, height); + } + +} + +/** +* Destroyer of worlds. +* @method Phaser.World#destroy +*/ +Phaser.World.prototype.destroy = function () { + + this.camera.x = 0; + this.camera.y = 0; + + this.game.input.reset(true); + + this.removeAll(); + +} /** * @name Phaser.World#width @@ -222,7 +221,7 @@ Object.defineProperty(Phaser.World.prototype, "centerY", { Object.defineProperty(Phaser.World.prototype, "randomX", { get: function () { - return Math.round(Math.random() * this.bounds.width); + return this.game.rnd.integerInRange(this.bounds.x, this.bounds.width); } }); @@ -235,7 +234,7 @@ Object.defineProperty(Phaser.World.prototype, "randomX", { Object.defineProperty(Phaser.World.prototype, "randomY", { get: function () { - return Math.round(Math.random() * this.bounds.height); + return this.game.rnd.integerInRange(this.bounds.y, this.bounds.height); } }); diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js index 00d8406a..1a7419d0 100644 --- a/src/gameobjects/GameObjectFactory.js +++ b/src/gameobjects/GameObjectFactory.js @@ -48,7 +48,7 @@ Phaser.GameObjectFactory.prototype = { */ existing: function (object) { - return this.world.group.add(object); + return this.world.add(object); }, @@ -64,7 +64,7 @@ Phaser.GameObjectFactory.prototype = { */ sprite: function (x, y, key, frame) { - return this.world.group.add(new Phaser.Sprite(this.game, x, y, key, frame)); + return this.world.create(x, y, key, frame); }, @@ -72,17 +72,20 @@ Phaser.GameObjectFactory.prototype = { * Create a new Sprite with specific position and sprite sheet key that will automatically be added as a child of the given parent. * * @method child + * @param {Phaser.Group} group - The Group to add this child to. * @param {number} x - X position of the new sprite. * @param {number} y - Y position of the new sprite. * @param {string|RenderTexture} [key] - The image key as defined in the Game.Cache to use as the texture for this sprite OR a RenderTexture. * @param {string|number} [frame] - If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name. * @returns {Description} Description. */ - child: function (parent, x, y, key, frame) { + child: function (group, x, y, key, frame) { - var child = this.world.group.add(new Phaser.Sprite(this.game, x, y, key, frame)); - parent.addChild(child); - return child; + return group.create(x, y, key, frame); + + // var child = new Phaser.Sprite(this.game, x, y, key, frame); + // parent.addChild(child); + // return child; }, @@ -142,7 +145,7 @@ Phaser.GameObjectFactory.prototype = { */ tileSprite: function (x, y, width, height, key, frame) { - return this.world.group.add(new Phaser.TileSprite(this.game, x, y, width, height, key, frame)); + return this.world.add(new Phaser.TileSprite(this.game, x, y, width, height, key, frame)); }, @@ -157,7 +160,7 @@ Phaser.GameObjectFactory.prototype = { */ text: function (x, y, text, style) { - return this.world.group.add(new Phaser.Text(this.game, x, y, text, style)); + return this.world.add(new Phaser.Text(this.game, x, y, text, style)); }, @@ -176,7 +179,7 @@ Phaser.GameObjectFactory.prototype = { */ button: function (x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) { - return this.world.group.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame)); + return this.world.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame)); }, @@ -190,7 +193,7 @@ Phaser.GameObjectFactory.prototype = { */ graphics: function (x, y) { - return this.world.group.add(new Phaser.Graphics(this.game, x, y)); + return this.world.add(new Phaser.Graphics(this.game, x, y)); }, @@ -221,7 +224,7 @@ Phaser.GameObjectFactory.prototype = { */ bitmapText: function (x, y, text, style) { - return this.world.group.add(new Phaser.BitmapText(this.game, x, y, text, style)); + return this.world.add(new Phaser.BitmapText(this.game, x, y, text, style)); }, @@ -239,7 +242,7 @@ Phaser.GameObjectFactory.prototype = { */ tilemap: function (x, y, key, resizeWorld, tileWidth, tileHeight) { - return this.world.group.add(new Phaser.Tilemap(this.game, key, x, y, resizeWorld, tileWidth, tileHeight)); + return this.world.add(new Phaser.Tilemap(this.game, key, x, y, resizeWorld, tileWidth, tileHeight)); },