From 2e576fa9a71a04fc85f64f3e36dabc28e794b607 Mon Sep 17 00:00:00 2001 From: photonstorm Date: Mon, 4 Nov 2013 20:43:59 +0000 Subject: [PATCH] Input Handler updates, orientation screen and World visibility --- README.md | 2 + examples/wip/pivot.js | 49 +++++++++++ src/core/Game.js | 6 +- src/core/World.js | 16 ++++ src/gameobjects/Button.js | 20 +++++ src/input/InputHandler.js | 44 ++++++---- src/input/Pointer.js | 1 - src/system/StageScaleMode.js | 162 +++++++++++++++++++++++++---------- 8 files changed, 236 insertions(+), 64 deletions(-) create mode 100644 examples/wip/pivot.js diff --git a/README.md b/README.md index d5773c02..468a9806 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ Version 1.1.3 - in build * New: Sprite.animations.getAnimation will return an animation instance which was added by name. * New: Added Mouse.button which is set to the button that was pressed: Phaser.Mouse.LEFT_BUTTON, MIDDLE_BUTTON or RIGHT_BUTTON (thanks wKLV) * New: Added Mouse.pointerLock signal which you can listen to whenever the browser enters or leaves pointer lock mode. +* New: StageScaleMode.forceOrientation allows you to lock your game to one orientation and display a Sprite (i.e. a "please rotate" screen) when incorrect. +* New: World.visible boolean added, toggles rendering of the world on/off entirely. * Fixed: Mouse.stop now uses the true useCapture, which means the event listeners stop listening correctly (thanks beeglebug) * Updated: RequestAnimationFrame now retains the callbackID which is passed to cancelRequestAnimationFrame. * Updated: Button now goes back to over state when setFrames used in action (thanks beeglebug) diff --git a/examples/wip/pivot.js b/examples/wip/pivot.js new file mode 100644 index 00000000..3bc4b2ed --- /dev/null +++ b/examples/wip/pivot.js @@ -0,0 +1,49 @@ +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('atari', 'assets/sprites/atari130xe.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + +} + +var sprite1; +var sprite2; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + // This will check Sprite vs. Sprite collision + + sprite1 = game.add.sprite(300, 300, 'atari'); + sprite1.name = 'atari'; + sprite1.body.immovable = true; + + sprite1.anchor.setTo(0.5, 0.5); + sprite1.pivot.x = 250; + sprite1.pivot.y = 300; + + // sprite2 = game.add.sprite(0, 0, 'mushroom'); + // sprite2.name = 'mushroom'; + +} + +function update() { + + sprite1.angle += 1; + sprite1.pivot.x = game.input.x; + sprite1.pivot.y = game.input.y; + +} + +function render() { + + game.debug.renderPixel(sprite1.pivot.x, sprite1.pivot.y); + + // game.debug.renderSpriteInfo(sprite1, 100, 400); + game.debug.renderSpriteBounds(sprite1); + // game.debug.renderSpriteInfo(sprite2, 100, 100); + // game.debug.renderSpriteBounds(sprite2); +} + diff --git a/src/core/Game.js b/src/core/Game.js index 9f4122ea..9b37005b 100644 --- a/src/core/Game.js +++ b/src/core/Game.js @@ -422,7 +422,11 @@ Phaser.Game.prototype = { this.time.update(time); - if (!this._paused) + if (this._paused) + { + this.renderer.render(this.stage._stage); + } + else { this.plugins.preUpdate(); this.physics.preUpdate(); diff --git a/src/core/World.js b/src/core/World.js index 61bc6692..3f2d4609 100644 --- a/src/core/World.js +++ b/src/core/World.js @@ -258,3 +258,19 @@ Object.defineProperty(Phaser.World.prototype, "randomY", { } }); + +/** +* @name Phaser.World#visible +* @property {boolean} visible - Gets or sets the visible state of the World. +*/ +Object.defineProperty(Phaser.World.prototype, "visible", { + + get: function () { + return this._container.visible; + }, + + set: function (value) { + this._container.visible = value; + } + +}); diff --git a/src/gameobjects/Button.js b/src/gameobjects/Button.js index 53f49dd1..77ad8b1d 100644 --- a/src/gameobjects/Button.js +++ b/src/gameobjects/Button.js @@ -169,6 +169,13 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, */ this.freezeFrames = false; + /** + * When the Button is clicked you can optionally force the state to "out". + * @property {boolean} forceOut + * @default + */ + this.forceOut = true; + this.setFrames(overFrame, outFrame, downFrame); if (callback !== null) @@ -513,8 +520,21 @@ Phaser.Button.prototype.onInputUpHandler = function (pointer) { this.onUpSound.play(this.onUpSoundMarker); } + if (this.forceOut && this.freezeFrames == false) + { + if (this._onOutFrameName != null) + { + this.frameName = this._onOutFrameName; + } + else if (this._onOutFrameID != null) + { + this.frame = this._onOutFrameID; + } + } + if (this.onInputUp) { this.onInputUp.dispatch(this, pointer); } + }; diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js index 19879e08..a2d8abaf 100644 --- a/src/input/InputHandler.js +++ b/src/input/InputHandler.js @@ -410,20 +410,25 @@ Phaser.InputHandler.prototype = { */ pointerOver: function (index) { - if (typeof index === 'undefined') + if (this.enabled) { - for (var i = 0; i < 10; i++) + if (typeof index === 'undefined') { - if (this._pointerData[i].isOver) + for (var i = 0; i < 10; i++) { - return true; + if (this._pointerData[i].isOver) + { + return true; + } } } + else + { + return this._pointerData[index].isOver; + } } - else - { - return this._pointerData[index].isOver; - } + + return false; }, @@ -435,20 +440,25 @@ Phaser.InputHandler.prototype = { */ pointerOut: function (pointer) { - if (typeof index === 'undefined') + if (this.enabled) { - for (var i = 0; i < 10; i++) + if (typeof index === 'undefined') { - if (this._pointerData[i].isOut) + for (var i = 0; i < 10; i++) { - return true; + if (this._pointerData[i].isOut) + { + return true; + } } } + else + { + return this._pointerData[index].isOut; + } } - else - { - return this._pointerData[index].isOut; - } + + return false; }, @@ -569,8 +579,6 @@ Phaser.InputHandler.prototype = { return false; } - // For an enabled sprite that may have been clicked - if (this.draggable && this._draggedPointerID == pointer.id) { return this.updateDrag(pointer); diff --git a/src/input/Pointer.js b/src/input/Pointer.js index 402e2e55..855846a6 100644 --- a/src/input/Pointer.js +++ b/src/input/Pointer.js @@ -397,7 +397,6 @@ Phaser.Pointer.prototype = { } return this; - } // Work out which object is on the top diff --git a/src/system/StageScaleMode.js b/src/system/StageScaleMode.js index 142e4610..c9318806 100644 --- a/src/system/StageScaleMode.js +++ b/src/system/StageScaleMode.js @@ -17,45 +17,19 @@ Phaser.StageScaleMode = function (game, width, height) { /** - * @property {number} _startHeight - Stage height when starting the game. - * @default - * @private + * @property {Phaser.Game} game - A reference to the currently running game. */ - this._startHeight = 0; + this.game = game; /** - * @property {boolean} forceLandscape - If the game should be forced to use Landscape mode, this is set to true by Game.Stage - * @default + * @property {number} width - Width of the stage after calculation. */ - this.forceLandscape = false; + this.width = width; /** - * @property {boolean} forcePortrait - If the game should be forced to use Portrait mode, this is set to true by Game.Stage - * @default + * @property {number} height - Height of the stage after calculation. */ - this.forcePortrait = false; - - /** - * @property {boolean} incorrectOrientation - If the game should be forced to use a specific orientation and the device currently isn't in that orientation this is set to true. - * @default - */ - this.incorrectOrientation = false; - - /** - * @property {boolean} pageAlignHorizontally - If you wish to align your game in the middle of the page then you can set this value to true. - - * @default - */ - this.pageAlignHorizontally = false; - - /** - * @property {boolean} pageAlignVertically - If you wish to align your game in the middle of the page then you can set this value to true. - - * @default - */ - this.pageAlignVertically = false; + this.height = height; /** * @property {number} minWidth - Minimum width the canvas should be scaled to (in pixels). @@ -84,14 +58,45 @@ Phaser.StageScaleMode = function (game, width, height) { this.maxHeight = null; /** - * @property {number} width - Width of the stage after calculation. + * @property {number} _startHeight - Stage height when starting the game. + * @default + * @private */ - this.width = width; + this._startHeight = 0; /** - * @property {number} height - Height of the stage after calculation. + * @property {boolean} forceLandscape - If the game should be forced to use Landscape mode, this is set to true by Game.Stage + * @default */ - this.height = height; + this.forceLandscape = false; + + /** + * @property {boolean} forcePortrait - If the game should be forced to use Portrait mode, this is set to true by Game.Stage + * @default + */ + this.forcePortrait = false; + + /** + * @property {boolean} incorrectOrientation - If the game should be forced to use a specific orientation and the device currently isn't in that orientation this is set to true. + * @default + */ + this.incorrectOrientation = false; + + /** + * @property {boolean} pageAlignHorizontally - If you wish to align your game in the middle of the page then you can set this value to true. + * It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing. + * It doesn't care about any other DOM element that may be on the page, it literally just sets the margin. + * @default + */ + this.pageAlignHorizontally = false; + + /** + * @property {boolean} pageAlignVertically - If you wish to align your game in the middle of the page then you can set this value to true. + * It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing. + * It doesn't care about any other DOM element that may be on the page, it literally just sets the margin. + * @default + */ + this.pageAlignVertically = false; /** * @property {number} _width - Cached stage width for full screen mode. @@ -113,18 +118,20 @@ Phaser.StageScaleMode = function (game, width, height) { */ this.maxIterations = 5; - /** - * @property {Phaser.Game} game - A reference to the currently running game. - */ - this.game = game; /** - * @property {Description} enterLandscape - Description. + * @property {PIXI.Sprite} orientationSprite - The Sprite that is optionally displayed if the browser enters an unsupported orientation. + * @default + */ + this.orientationSprite = null; + + /** + * @property {Phaser.Signal} enterLandscape - The event that is dispatched when the browser enters landscape orientation. */ this.enterLandscape = new Phaser.Signal(); /** - * @property {Description} enterPortrait - Description. + * @property {Phaser.Signal} enterPortrait - The event that is dispatched when the browser enters horizontal orientation. */ this.enterPortrait = new Phaser.Signal(); @@ -145,7 +152,7 @@ Phaser.StageScaleMode = function (game, width, height) { } /** - * @property {Description} scaleFactor - Description. + * @property {Phaser.Point} scaleFactor - The scale factor based on the game dimensions vs. the scaled dimensions. */ this.scaleFactor = new Phaser.Point(1, 1); @@ -298,6 +305,54 @@ Phaser.StageScaleMode.prototype = { }, + /** + * If you need your game to run in only one orientation you can force that to happen. + * The optional orientationImage is displayed when the game is in the incorrect orientation. + * @method Phaser.StageScaleMode#forceOrientation + * @param {boolean} forceLandscape - true if the game should run in landscape mode only. + * @param {boolean} forcePortrait - true if the game should run in portrait mode only. + * @param {string} [forcePortrait=''] - The string of an image in the Phaser.Cache to display when this game is in the incorrect orientation. + */ + forceOrientation: function (forceLandscape, forcePortrait, orientationImage) { + + this.forceLandscape = forceLandscape; + + if (typeof forcePortrait === 'undefined') + { + this.forcePortrait = false; + } + + if (typeof orientationImage !== 'undefined') + { + if (orientationImage == null || this.game.cache.checkImageKey(orientationImage) == false) + { + orientationImage = '__default'; + } + + this.orientationSprite = new PIXI.Sprite(PIXI.TextureCache[orientationImage]); + this.orientationSprite.anchor.x = 0.5; + this.orientationSprite.anchor.y = 0.5; + this.orientationSprite.position.x = this.game.width / 2; + this.orientationSprite.position.y = this.game.height / 2; + + this.checkOrientationState(); + + if (this.incorrectOrientation) + { + this.orientationSprite.visible = true; + this.game.world.visible = false; + } + else + { + this.orientationSprite.visible = false; + this.game.world.visible = true; + } + + this.game.stage._stage.addChild(this.orientationSprite); + } + + }, + /** * Checks if the browser is in the correct orientation for your game (if forceLandscape or forcePortrait have been set) * @method Phaser.StageScaleMode#checkOrientationState @@ -312,6 +367,13 @@ Phaser.StageScaleMode.prototype = { // Back to normal this.game.paused = false; this.incorrectOrientation = false; + + if (this.orientationSprite) + { + this.orientationSprite.visible = false; + this.game.world.visible = true; + } + this.refresh(); } } @@ -322,6 +384,13 @@ Phaser.StageScaleMode.prototype = { // Show orientation screen this.game.paused = true; this.incorrectOrientation = true; + + if (this.orientationSprite && this.orientationSprite.visible == false) + { + this.orientationSprite.visible = true; + this.game.world.visible = false; + } + this.refresh(); } } @@ -381,6 +450,9 @@ Phaser.StageScaleMode.prototype = { { this.refresh(); } + + this.checkOrientationState(); + }, /** @@ -420,7 +492,7 @@ Phaser.StageScaleMode.prototype = { /** * Set screen size automatically based on the scaleMode. - * @param {Description} force - If force is true it will try to resize the game regardless of the document dimensions. + * @param {boolean} force - If force is true it will try to resize the game regardless of the document dimensions. */ setScreenSize: function (force) { @@ -533,6 +605,8 @@ Phaser.StageScaleMode.prototype = { this.scaleFactor.x = this.game.width / this.width; this.scaleFactor.y = this.game.height / this.height; + this.checkOrientationState(); + }, /**