diff --git a/README.md b/README.md index b893f29d..ea4af105 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Version 1.1.2 * New: Phaser.Button now has the ability to set over/out/up/down sound effects so they play automatically based on those events. * New: Added init method to plugins, to be called as they are added to the PluginManager (thanks beeglebug) * New: Physics.Body now has a center property (issue 142, thanks MikeMnD) +* New: Lots of fixes across Full Screen Mode support. Input now works, scaling restores properly, world scale is correct and anti-alias support added. * Updated: Fixed a few final bugs in the Sprite body and bounds calculations, in turn this resolved the Tilemap collision issues in the 1.1 release. * Updated: Finished documentation for the Phaser.Button class. * Updated: Fixed the Invaders game sample and enhanced it. @@ -51,6 +52,9 @@ Version 1.1.2 * Updated: hexToRGB now accepts short hex codes (#EEE) (thanks beeglebug) * Updated: State functions (preload, update, render, etc) are now passed the current game as a parameter (thanks beeglebug) * Updated: If your game is running in Canvas (not WebGL) you can now set Stage.backgroundColor to rgba style CSS strings, allowing for semi-transparent game backgrounds. +* Updated: event.preventDefault() has been added to all Mouse event handlers. +* Updated: Sprite.deltaX/Y removed due to non-use. prevX/Y values moved to Sprite._cache.prevX/Y. +* Updated: Due to missing extends parameter the Sprite prototype was picking up functions from classes it never meant to (Button, TilemapLayer), now fully isolated. * Fixed issue 135 - Added typeof checks into most ArcadePhysics functions to avoid errors with zero values. * Fixed issue 136 - distanceTo using worldX/Y instead of x/y. * Fixed lots of examples where the cursor keys / space bar were not locked from moving the browser page (if you find any more, please tell us!) @@ -58,6 +62,10 @@ Version 1.1.2 * Fixed an issue where if the Starling XML file didn't contain a frameX/Y value it would crash on import. * Fixed the Multiple Animations Example - it's now a lovely underwater scene :) * Fixed issue 141 - If a Sprite is dragged and you release the Pointer while not over the Sprite, it will think it's still over it (thanks Paratron) +* Fixed issue 88 - Incorrect game.input.x/y values on click with scaled stage (thanks DrHackenstein) +* Fixed issue 143 - Entering full screen mode made the Input x/y coordinates go wrong. + + diff --git a/examples/groups/bring a child to top.js b/examples/groups/bring a child to top.js index 07a2f82a..425524ba 100644 --- a/examples/groups/bring a child to top.js +++ b/examples/groups/bring a child to top.js @@ -1,34 +1,40 @@ - var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); function preload() { - game.load.spritesheet('button', 'assets/buttons/number-buttons.png', 160, 160); -} -var container; + // Enable scaling + game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + game.stage.scale.maxWidth = 1024; + game.stage.scale.maxHeight = 672; + game.stage.scale.refresh(); + + game.load.image('atari1', 'assets/sprites/atari130xe.png'); + game.load.image('atari2', 'assets/sprites/atari800xl.png'); + game.load.image('atari4', 'assets/sprites/atari800.png'); + game.load.image('sonic', 'assets/sprites/sonic_havok_sanity.png'); + game.load.image('duck', 'assets/sprites/darkwing_crazy.png'); + game.load.image('firstaid', 'assets/sprites/firstaid.png'); + game.load.image('diamond', 'assets/sprites/diamond.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + +} function create() { - container = game.add.group(); + // This returns an array of all the image keys in the cache + var images = game.cache.getImageKeys(); - // Add buttons to container. - container.add(game.add.button(200, 100, 'button', bringMeToTop, this, 0, 0, 0)); - container.add(game.add.button(300, 100, 'button', bringMeToTop, this, 1, 1, 1)); - container.add(game.add.button(100, 200, 'button', bringMeToTop, this, 2, 2, 2)); - container.add(game.add.button(400, 200, 'button', bringMeToTop, this, 3, 3, 3)); - container.add(game.add.button(300, 300, 'button', bringMeToTop, this, 4, 4, 4)); - container.add(game.add.button(200, 300, 'button', bringMeToTop, this, 5, 5, 5)); + // Now let's create some random sprites and enable them all for drag and 'bring to top' + for (var i = 0; i < 20; i++) + { + var img = game.rnd.pick(images); + var tempSprite = game.add.sprite(game.world.randomX, game.world.randomY, img); + tempSprite.inputEnabled = true; + tempSprite.input.enableDrag(false, true); + } } function render() { - - game.debug.renderText('Tap or click button to bring it to the top.', 32, 32); - -} - -function bringMeToTop(btn) { - - container.bringToTop(btn); - -} + game.debug.renderInputInfo(32, 32); +} \ No newline at end of file diff --git a/examples/wip/button scale.js b/examples/wip/button scale.js new file mode 100644 index 00000000..ac3ae049 --- /dev/null +++ b/examples/wip/button scale.js @@ -0,0 +1,113 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + // Enable scaling + // game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + // game.stage.scale.maxWidth = 1500; + // game.stage.scale.maxHeight = 1000; + // game.stage.scale.startFullScreen(); + // game.stage.scale.refresh(); + + game.load.spritesheet('button', 'assets/buttons/button_sprite_sheet.png', 193, 71); + + game.load.image('sky0','assets/skies/space2.png'); + game.load.image('sky1','assets/skies/cavern1.png'); + game.load.image('sky2','assets/skies/chrome.png'); + game.load.image('sky3','assets/skies/fire.png'); + game.load.image('sky4','assets/skies/fog.png'); + game.load.image('sky5','assets/skies/sky1.png'); + game.load.image('sky6','assets/skies/toxic.png'); + +} + +var background; +var button1; +var button2; +var button3; +var button4; +var button5; +var button6; + +function create() { + + background = game.add.sprite(0, 0, 'sky0'); + background.name = 'background'; + + // Standard button (also used as our pointer tracker) + button1 = game.add.button(100, 100, 'button', changeSky, this, 2, 1, 0); + button1.name = 'sky1'; + button1.anchor.setTo(0.5, 0.5); + + // Rotated button + button2 = game.add.button(330, 200, 'button', changeSky, this, 2, 1, 0); + button2.name = 'sky2'; + button2.angle = 24; + button2.anchor.setTo(0.5, 0.5); + + // Width scaled button + button3 = game.add.button(100, 300, 'button', changeSky, this, 2, 1, 0); + button3.name = 'sky3'; + button3.width = 300; + button3.anchor.setTo(0, 0.5); + // button3.angle = 0.1; + + // Scaled button + button4 = game.add.button(300, 450, 'button', changeSky, this, 2, 1, 0); + button4.name = 'sky4'; + button4.scale.setTo(2, 2); + + // Shrunk button + button5 = game.add.button(100, 450, 'button', changeSky, this, 2, 1, 0); + button5.name = 'sky5'; + button5.scale.setTo(0.5, 0.5); + + // Scaled and Rotated button + button6 = game.add.button(570, 200, 'button', changeSky, this, 2, 1, 0); // anchor 0.5 + button6.name = 'sky6'; + button6.angle = 32; + button6.scale.setTo(2, 2); + button6.anchor.setTo(0.5, 0.5); + + // works regardless of world angle, parent angle or camera position + // game.world.setBounds(0, 0, 2000, 2000); + // game.world.angle = 10; + // game.camera.x = 300; + + // Phaser.Canvas.setSmoothingEnabled(false); + + game.input.onDown.add(gofull, this); + +} + +function gofull() { + + game.stage.scale.startFullScreen(false); + +} + +function changeSky (button) { + + background.loadTexture(button.name); + +} + +function render () { + + game.debug.renderSpriteCorners(button1, false, true); + game.debug.renderSpriteCorners(button2, false, true); + game.debug.renderSpriteCorners(button3, false, true); + game.debug.renderSpriteCorners(button4, false, true); + game.debug.renderSpriteCorners(button5, false, true); + game.debug.renderSpriteCorners(button6, false, true); + + // game.debug.renderWorldTransformInfo(button1, 32, 132); + // game.debug.renderText('sx: ' + button3.scale.x + ' sy: ' + button3.scale.y + ' w: ' + button3.width + ' cw: ' + button3._cache.width, 32, 20); + // game.debug.renderText('ox: ' + game.stage.offset.x + ' oy: ' + game.stage.offset.y, 32, 20); + // game.debug.renderPoint(button3.input._tempPoint); + // game.debug.renderPoint(button6.input._tempPoint); + + game.debug.renderInputInfo(32, 32); + +} diff --git a/examples/wip/mouse scale.js b/examples/wip/mouse scale.js new file mode 100644 index 00000000..5fc9ed18 --- /dev/null +++ b/examples/wip/mouse scale.js @@ -0,0 +1,68 @@ +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + // Enable scaling + game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + game.stage.scale.maxWidth = 1500; + game.stage.scale.maxHeight = 1000; + game.stage.scale.refresh(); + + game.load.image('atari1', 'assets/sprites/atari130xe.png'); + game.load.image('atari2', 'assets/sprites/atari800xl.png'); + game.load.image('atari4', 'assets/sprites/atari800.png'); + game.load.image('sonic', 'assets/sprites/sonic_havok_sanity.png'); + game.load.image('duck', 'assets/sprites/darkwing_crazy.png'); + game.load.image('firstaid', 'assets/sprites/firstaid.png'); + game.load.image('diamond', 'assets/sprites/diamond.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + +} + +function create() { + + game.world.setBounds(0, 0, 2000, 2000); + + // This returns an array of all the image keys in the cache + var images = game.cache.getImageKeys(); + + // Now let's create some random sprites and enable them all for drag and 'bring to top' + for (var i = 0; i < 200; i++) + { + var img = game.rnd.pick(images); + var tempSprite = game.add.sprite(game.world.randomX, game.world.randomY, img); + tempSprite.inputEnabled = true; + tempSprite.input.enableDrag(false, true); + } + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function update() { + + if (cursors.up.isDown) + { + game.camera.y -= 4; + } + else if (cursors.down.isDown) + { + game.camera.y += 4; + } + + if (cursors.left.isDown) + { + game.camera.x -= 4; + } + else if (cursors.right.isDown) + { + game.camera.x += 4; + } + +} + +function render() { + + game.debug.renderInputInfo(32, 32); + +} \ No newline at end of file diff --git a/examples/wip/offset.js b/examples/wip/offset.js new file mode 100644 index 00000000..28c56259 --- /dev/null +++ b/examples/wip/offset.js @@ -0,0 +1,33 @@ +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'); + +} + +var sprite1; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + sprite1 = game.add.sprite(350, 300, 'atari'); + sprite1.name = 'atari'; + sprite1.anchor.setTo(0.5, -2); + +} + +function update() { + + sprite1.angle += 1; + +} + + +function render() { + + game.debug.renderSpriteCorners(sprite1); + +} + diff --git a/examples/wip/sprite vs sprite.js b/examples/wip/sprite vs sprite.js new file mode 100644 index 00000000..37f0ee32 --- /dev/null +++ b/examples/wip/sprite vs sprite.js @@ -0,0 +1,60 @@ +var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { 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(50, 250, 'atari'); + sprite1.name = 'atari'; + sprite1.body.immovable = true; + + sprite2 = game.add.sprite(0, 0, 'mushroom'); + sprite2.name = 'mushroom'; + +} + +function update() { + + sprite1.body.x = game.input.x; //uncoment for tests + + if (sprite2.y > 400) + { + sprite2.x = 0; + sprite2.y = 0; + } + + sprite2.body.velocity.x = 100; + sprite2.body.velocity.y = 50; + + // object1, object2, collideCallback, processCallback, callbackContext + game.physics.collide(sprite1, sprite2, collisionHandler, null, this); + +} + +function collisionHandler (obj1, obj2) { + + game.stage.backgroundColor = '#992d2d'; + + console.log(obj1.name + ' collided with ' + obj2.name); + +} + +function render() { + 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/Group.js b/src/core/Group.js index 8ebf5bcc..8f6f30ce 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -82,6 +82,11 @@ Phaser.Group = function (game, parent, name, useStage) { */ this.scale = new Phaser.Point(1, 1); + /** + * @property {any} cursor - The current display object that the Group cursor is pointing to. You can move the cursor with Group.next and Group.previous. + */ + this.cursor = null; + }; Phaser.Group.prototype = { diff --git a/src/gameobjects/Bullet.js b/src/gameobjects/Bullet.js deleted file mode 100644 index 4da6912e..00000000 --- a/src/gameobjects/Bullet.js +++ /dev/null @@ -1,623 +0,0 @@ -/** -* @author Richard Davey -* @copyright 2013 Photon Storm Ltd. -* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} -*/ - -/** -* Warning: Bullet is an experimental object that we don't advise using for now. -* -* A Bullet is like a stripped-down Sprite, useful for when you just need to get something moving around the screen quickly with little of the extra -* features that a Sprite supports. -* Bullet is MISSING the following: -* -* animation, all input events, crop support, health/damage, loadTexture -* -* @class Phaser.Bullet -* @constructor -* @param {Phaser.Game} game - Current game instance. -* @param {number} x - X position of the new bullet. -* @param {number} y - Y position of the new bullet. -* @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. -* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. -*/ -Phaser.Bullet = function (game, x, y, key, frame) { - - x = x || 0; - y = y || 0; - key = key || null; - frame = frame || null; - - /** - * @property {Phaser.Game} game - A reference to the currently running Game. - */ - this.game = game; - - /** - * @property {boolean} exists - If exists = false then the Sprite isn't updated by the core game loop or physics subsystem at all. - * @default - */ - this.exists = true; - - /** - * @property {boolean} alive - This is a handy little var your game can use to determine if a sprite is alive or not, it doesn't effect rendering. - * @default - */ - this.alive = true; - - /** - * @property {Description} group - Description. - * @default - */ - this.group = null; - - /** - * @property {string} name - The user defined name given to this Sprite. - * @default - */ - this.name = ''; - - /** - * @property {Description} type - Description. - */ - this.type = Phaser.BULLET; - - /** - * @property {number} renderOrderID - Description. - * @default - */ - this.renderOrderID = -1; - - /** - * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc. - * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called. - * @property {number} lifespan - * @default - */ - this.lifespan = 0; - - /** - * @property {Events} events - The Signals you can subscribe to that are dispatched when certain things happen on this Sprite or its components - */ - this.events = new Phaser.Events(this); - - /** - * @property {Description} key - Description. - */ - this.key = key; - - if (key instanceof Phaser.RenderTexture) - { - PIXI.Sprite.call(this, key); - - this.currentFrame = this.game.cache.getTextureFrame(key.name); - } - else if (key instanceof PIXI.Texture) - { - PIXI.Sprite.call(this, key); - - this.currentFrame = frame; - } - else - { - if (key == null || this.game.cache.checkImageKey(key) == false) - { - key = '__default'; - } - - PIXI.Sprite.call(this, PIXI.TextureCache[key]); - - if (this.game.cache.isSpriteSheet(key)) - { - /* - this.animations.loadFrameData(this.game.cache.getFrameData(key)); - - if (frame !== null) - { - if (typeof frame === 'string') - { - this.frameName = frame; - } - else - { - this.frame = frame; - } - } - */ - } - else - { - this.currentFrame = this.game.cache.getFrame(key); - } - } - - /** - * The anchor sets the origin point of the texture. - * The default is 0,0 this means the textures origin is the top left - * Setting than anchor to 0.5,0.5 means the textures origin is centered - * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right - * - * @property {Phaser.Point} anchor - */ - this.anchor = new Phaser.Point(); - - /** - * @property {number} x - Description. - */ - this.x = x; - - /** - * @property {number} y - Description. - */ - this.y = y; - - /** - * @property {Description} position - Description. - */ - this.position.x = x; - this.position.y = y; - - /** - * Should this Sprite be automatically culled if out of range of the camera? - * A culled sprite has its visible property set to 'false'. - * Note that this check doesn't look at this Sprites children, which may still be in camera range. - * So you should set autoCull to false if the Sprite will have children likely to still be in camera range. - * - * @property {boolean} autoCull - * @default - */ - this.autoCull = false; - - /** - * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. - */ - this.scale = new Phaser.Point(1, 1); - - /** - * @property {Phaser.Point} _cache - A mini cache for storing all of the calculated values. - * @private - */ - this._cache = { - - dirty: false, - - // Transform cache - a00: -1, a01: -1, a02: -1, a10: -1, a11: -1, a12: -1, id: -1, - - // Input specific transform cache - i01: -1, i10: -1, idi: -1, - - // Bounds check - left: null, right: null, top: null, bottom: null, - - // The previous calculated position - x: -1, y: -1, - - // The actual scale values based on the worldTransform - scaleX: 1, scaleY: 1, - - // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size - width: this.currentFrame.sourceSizeW, height: this.currentFrame.sourceSizeH, - - // The actual width/height of the image if from a trimmed atlas, multiplied by the final calculated scale size - halfWidth: Math.floor(this.currentFrame.sourceSizeW / 2), halfHeight: Math.floor(this.currentFrame.sourceSizeH / 2), - - boundsX: 0, boundsY: 0, - - // If this sprite visible to the camera (regardless of being set to visible or not) - cameraVisible: true - - }; - - /** - * @property {Phaser.Point} offset - Corner point defaults. - */ - this.offset = new Phaser.Point; - - /** - * @property {Phaser.Point} center - Description. - */ - this.center = new Phaser.Point(x + Math.floor(this._cache.width / 2), y + Math.floor(this._cache.height / 2)); - - /** - * @property {Phaser.Point} topLeft - Description. - */ - this.topLeft = new Phaser.Point(x, y); - - /** - * @property {Phaser.Point} topRight - Description. - */ - this.topRight = new Phaser.Point(x + this._cache.width, y); - - /** - * @property {Phaser.Point} bottomRight - Description. - */ - this.bottomRight = new Phaser.Point(x + this._cache.width, y + this._cache.height); - - /** - * @property {Phaser.Point} bottomLeft - Description. - */ - this.bottomLeft = new Phaser.Point(x, y + this._cache.height); - - /** - * @property {Phaser.Rectangle} bounds - Description. - */ - this.bounds = new Phaser.Rectangle(x, y, this._cache.width, this._cache.height); - - /** - * @property {Phaser.Physics.Arcade.Body} body - Set-up the physics body. - */ - this.body = new Phaser.Physics.Arcade.Body(this); - - /** - * @property {Description} inWorld - World bounds check. - */ - this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds); - - /** - * @property {number} inWorldThreshold - World bounds check. - * @default - */ - this.inWorldThreshold = 0; - - /** - * @property {boolean} outOfBoundsKill - Kills this sprite as soon as it goes outside of the World bounds. - * @default - */ - this.outOfBoundsKill = false; - - /** - * @property {boolean} _outOfBoundsFired - Description. - * @private - * @default - */ - this._outOfBoundsFired = false; - - /** - * A Sprite that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera. - * @property {boolean} fixedToCamera - Fixes this Sprite to the Camera. - * @default - */ - this.fixedToCamera = false; - -}; - -Phaser.Bullet.prototype = Object.create(PIXI.Sprite.prototype); -Phaser.Bullet.prototype.constructor = Phaser.Bullet; - -/** -* Automatically called by World.preUpdate. You can create your own update in Objects that extend Phaser.Sprite. -* @method Phaser.Sprite.prototype.preUpdate -*/ -Phaser.Bullet.prototype.preUpdate = function() { - - if (!this.exists) - { - this.renderOrderID = -1; - return; - } - - if (this.lifespan > 0) - { - this.lifespan -= this.game.time.elapsed; - - if (this.lifespan <= 0) - { - this.kill(); - return; - } - } - - this._cache.dirty = false; - - if (this.visible) - { - this.renderOrderID = this.game.world.currentRenderOrderID++; - } - - this.prevX = this.x; - this.prevY = this.y; - - // |a c tx| - // |b d ty| - // |0 0 1| - - if (this.worldTransform[1] != this._cache.i01 || this.worldTransform[3] != this._cache.i10) - { - this._cache.a00 = this.worldTransform[0]; // scaleX a - this._cache.a01 = this.worldTransform[1]; // skewY c - this._cache.a10 = this.worldTransform[3]; // skewX b - this._cache.a11 = this.worldTransform[4]; // scaleY d - - this._cache.i01 = this.worldTransform[1]; // skewY c (remains non-modified for input checks) - this._cache.i10 = this.worldTransform[3]; // skewX b (remains non-modified for input checks) - - this._cache.scaleX = Math.sqrt((this._cache.a00 * this._cache.a00) + (this._cache.a01 * this._cache.a01)); // round this off a bit? - this._cache.scaleY = Math.sqrt((this._cache.a10 * this._cache.a10) + (this._cache.a11 * this._cache.a11)); // round this off a bit? - - this._cache.a01 *= -1; - this._cache.a10 *= -1; - - this._cache.dirty = true; - } - - if (this.worldTransform[2] != this._cache.a02 || this.worldTransform[5] != this._cache.a12) - { - this._cache.a02 = this.worldTransform[2]; // translateX tx - this._cache.a12 = this.worldTransform[5]; // translateY ty - this._cache.dirty = true; - } - - // Re-run the camera visibility check - if (this._cache.dirty) - { - this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.bounds, 0); - - if (this.autoCull == true) - { - // Won't get rendered but will still get its transform updated - this.renderable = this._cache.cameraVisible; - } - - // Update our physics bounds - if (this.body) - { - this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY); - } - } - - if (this.body) - { - this.body.preUpdate(); - } - -} - -Phaser.Bullet.prototype.postUpdate = function() { - - if (this.exists) - { - // The sprite is positioned in this call, after taking into consideration motion updates and collision - if (this.body) - { - this.body.postUpdate(); - } - - if (this.fixedToCamera) - { - this._cache.x = this.game.camera.view.x + this.x; - this._cache.y = this.game.camera.view.y + this.y; - } - else - { - this._cache.x = this.x; - this._cache.y = this.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; - } - } - -} - -Phaser.Bullet.prototype.deltaAbsX = function () { - return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); -} - -Phaser.Bullet.prototype.deltaAbsY = function () { - return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY()); -} - -Phaser.Bullet.prototype.deltaX = function () { - return this.x - this.prevX; -} - -Phaser.Bullet.prototype.deltaY = function () { - return this.y - this.prevY; -} - -/** -* Description. -* -* @method Phaser.Bullet.prototype.revive -*/ -Phaser.Bullet.prototype.revive = function(health) { - - if (typeof health === 'undefined') { health = 1; } - - this.alive = true; - this.exists = true; - this.visible = true; - this.health = health; - - this.events.onRevived.dispatch(this); - -} - -/** -* Description. -* -* @method Phaser.Bullet.prototype.kill -*/ -Phaser.Bullet.prototype.kill = function() { - - this.alive = false; - this.exists = false; - this.visible = false; - this.events.onKilled.dispatch(this); - -} - -/** -* Description. -* -* @method Phaser.Bullet.prototype.destroy -*/ -Phaser.Bullet.prototype.destroy = function() { - - if (this.group) - { - this.group.remove(this); - } - - this.events.destroy(); - - this.alive = false; - this.exists = false; - this.visible = false; - - this.game = null; - -} - -/** -* Description. -* -* @method Phaser.Sprite.prototype.reset -*/ -Phaser.Bullet.prototype.reset = function(x, y) { - - this.x = x; - this.y = y; - this.position.x = this.x; - this.position.y = this.y; - this.alive = true; - this.exists = true; - this.visible = true; - this.renderable = true; - this._outOfBoundsFired = false; - - if (this.body) - { - this.body.reset(); - } - -} - -/** -* Description. -* -* @method Phaser.Sprite.prototype.updateBounds -*/ -Phaser.Bullet.prototype.updateBounds = function() { - - // Update the edge points - - this.offset.setTo(this._cache.a02 - (this.anchor.x * this._cache.width), this._cache.a12 - (this.anchor.y * this._cache.height)); - - this.getLocalPosition(this.center, this.offset.x + this._cache.halfWidth, this.offset.y + this._cache.halfHeight); - this.getLocalPosition(this.topLeft, this.offset.x, this.offset.y); - this.getLocalPosition(this.topRight, this.offset.x + this._cache.width, this.offset.y); - this.getLocalPosition(this.bottomLeft, this.offset.x, this.offset.y + this._cache.height); - this.getLocalPosition(this.bottomRight, this.offset.x + this._cache.width, this.offset.y + this._cache.height); - - this._cache.left = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x); - this._cache.right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x); - this._cache.top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y); - this._cache.bottom = Phaser.Math.max(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y); - - this.bounds.setTo(this._cache.left, this._cache.top, this._cache.right - this._cache.left, this._cache.bottom - this._cache.top); - - // This is the coordinate the Bullet was at when the last bounds was created - this._cache.boundsX = this._cache.x; - this._cache.boundsY = this._cache.y; - - if (this.inWorld == false) - { - // Bullet WAS out of the screen, is it still? - this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold); - - if (this.inWorld) - { - // It's back again, reset the OOB check - this._outOfBoundsFired = false; - } - } - else - { - // Bullet WAS in the screen, has it now left? - this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold); - - if (this.inWorld == false) - { - this.events.onOutOfBounds.dispatch(this); - this._outOfBoundsFired = true; - - if (this.outOfBoundsKill) - { - this.kill(); - } - } - } - -} - -/** -* Description. -* -* @method Phaser.Bullet.prototype.getLocalPosition -* @param {Description} p - Description. -* @param {number} x - Description. -* @param {number} y - Description. -* @return {Description} Description. -*/ -Phaser.Bullet.prototype.getLocalPosition = function(p, x, y) { - - p.x = ((this._cache.a11 * this._cache.id * x + -this._cache.a01 * this._cache.id * y + (this._cache.a12 * this._cache.a01 - this._cache.a02 * this._cache.a11) * this._cache.id) * this._cache.scaleX) + this._cache.a02; - p.y = ((this._cache.a00 * this._cache.id * y + -this._cache.a10 * this._cache.id * x + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.a10) * this._cache.id) * this._cache.scaleY) + this._cache.a12; - - return p; - -} - -/** -* Description. -* -* @method Phaser.Bullet.prototype.bringToTop -*/ -Phaser.Bullet.prototype.bringToTop = function() { - - if (this.group) - { - this.group.bringToTop(this); - } - else - { - this.game.world.bringToTop(this); - } - -} - -/** -* Indicates the rotation of the Bullet, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. -* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90. -* If you wish to work in radians instead of degrees use the property Bullet.rotation instead. -* @name Phaser.Bullet#angle -* @property {number} angle - Gets or sets the Bullets angle of rotation in degrees. -*/ -Object.defineProperty(Phaser.Bullet.prototype, 'angle', { - - get: function() { - return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation)); - }, - - set: function(value) { - this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value)); - } - -}); - -/** -* Is this sprite visible to the camera or not? -* @returns {boolean} -*/ -Object.defineProperty(Phaser.Bullet.prototype, "inCamera", { - - get: function () { - return this._cache.cameraVisible; - } - -}); diff --git a/src/gameobjects/Button.js b/src/gameobjects/Button.js index ea51a574..2b09aafd 100644 --- a/src/gameobjects/Button.js +++ b/src/gameobjects/Button.js @@ -186,7 +186,8 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, }; -Phaser.Button.prototype = Phaser.Utils.extend(true, Phaser.Sprite.prototype, PIXI.Sprite.prototype); +Phaser.Button.prototype = Object.create(Phaser.Sprite.prototype); +Phaser.Button.prototype = Phaser.Utils.extend(true, Phaser.Button.prototype, Phaser.Sprite.prototype, PIXI.Sprite.prototype); Phaser.Button.prototype.constructor = Phaser.Button; /** diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index 35349736..6126606e 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -165,6 +165,11 @@ Phaser.Sprite = function (game, x, y, key, frame) { this.position.x = x; this.position.y = y; + /** + * @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container. + */ + this.world = new Phaser.Point(x, y); + /** * Should this Sprite be automatically culled if out of range of the camera? * A culled sprite has its renderable property set to 'false'. @@ -196,6 +201,9 @@ Phaser.Sprite = function (game, x, y, key, frame) { // Bounds check left: null, right: null, top: null, bottom: null, + // delta cache + prevX: x, prevY: y, + // The previous calculated position x: -1, y: -1, @@ -307,11 +315,6 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this.cameraOffset = new Phaser.Point; - /** - * @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container. - */ - this.world = new Phaser.Point; - /** * You can crop the Sprites texture by modifying the crop properties. For example crop.width = 50 would set the Sprite to only render 50px wide. * The crop is only applied if you have set Sprite.cropEnabled to true. @@ -374,7 +377,7 @@ Phaser.Sprite.prototype.preUpdate = function() { this.updateCrop(); // Re-run the camera visibility check - if (this._cache.dirty || this.world.x !== this.prevX || this.world.y !== this.prevY) + if (this._cache.dirty || this.world.x !== this._cache.prevX || this.world.y !== this._cache.prevY) { this.updateBounds(); } @@ -384,7 +387,7 @@ Phaser.Sprite.prototype.preUpdate = function() { this.body.preUpdate(); } -} +}; /** * Internal function called by preUpdate. @@ -394,8 +397,8 @@ Phaser.Sprite.prototype.preUpdate = function() { */ Phaser.Sprite.prototype.updateCache = function() { - this.prevX = this.world.x; - this.prevY = this.world.y; + this._cache.prevX = this.world.x; + this._cache.prevY = this.world.y; if (this.fixedToCamera) { @@ -430,7 +433,7 @@ Phaser.Sprite.prototype.updateCache = function() { this._cache.a02 = this.worldTransform[2]; // translateX tx this._cache.a12 = this.worldTransform[5]; // translateY ty -} +}; /** * Internal function called by preUpdate. @@ -457,7 +460,7 @@ Phaser.Sprite.prototype.updateAnimation = function() { } -} +}; /** * Internal function called by preUpdate. @@ -486,7 +489,7 @@ Phaser.Sprite.prototype.updateCrop = function() { PIXI.Texture.frameUpdates.push(this.texture); } -} +}; /** * Internal function called by preUpdate. @@ -555,7 +558,7 @@ Phaser.Sprite.prototype.updateBounds = function() { this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY); } -} +}; /** * Gets the local position of a coordinate relative to the Sprite, factoring in rotation and scale. @@ -577,7 +580,7 @@ Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) { return p; -} +}; /** * Gets the local unmodified position of a coordinate relative to the Sprite, factoring in rotation and scale. @@ -597,8 +600,7 @@ Phaser.Sprite.prototype.getLocalUnmodifiedPosition = function(p, gx, gy) { return p; -} - +}; /** * Resets the Sprite.crop value back to the frame dimensions. @@ -612,7 +614,7 @@ Phaser.Sprite.prototype.resetCrop = function() { this.texture.setFrame(this.crop); this.cropEnabled = false; -} +}; /** * Internal function called by the World postUpdate cycle. @@ -647,7 +649,7 @@ Phaser.Sprite.prototype.postUpdate = function() { this.position.y = this._cache.y; } -} +}; /** * Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache. @@ -701,51 +703,7 @@ Phaser.Sprite.prototype.loadTexture = function (key, frame) { } } -} - -/** -* Returns the absolute delta x value. -* -* @method Phaser.Sprite#deltaAbsX -* @memberof Phaser.Sprite -* @return {number} The absolute delta value. -*/ -Phaser.Sprite.prototype.deltaAbsX = function () { - return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); -} - -/** -* Returns the absolute delta y value. -* -* @method Phaser.Sprite#deltaAbsY -* @memberof Phaser.Sprite -* @return {number} The absolute delta value. -*/ -Phaser.Sprite.prototype.deltaAbsY = function () { - return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY()); -} - -/** -* Returns the delta x value. -* -* @method Phaser.Sprite#deltaX -* @memberof Phaser.Sprite -* @return {number} The delta value. -*/ -Phaser.Sprite.prototype.deltaX = function () { - return this.x - this.prevX; -} - -/** -* Returns the delta y value. -* -* @method Phaser.Sprite#deltaY -* @memberof Phaser.Sprite -* @return {number} The delta value. -*/ -Phaser.Sprite.prototype.deltaY = function () { - return this.y - this.prevY; -} +}; /** * Moves the sprite so its center is located on the given x and y coordinates. @@ -763,7 +721,7 @@ Phaser.Sprite.prototype.centerOn = function(x, y) { this.y = y + (this.y - this.center.y); return this; -} +}; /** * Brings a 'dead' Sprite back to life, optionally giving it the health value specified. @@ -791,7 +749,7 @@ Phaser.Sprite.prototype.revive = function(health) { return this; -} +}; /** * Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false. @@ -816,7 +774,7 @@ Phaser.Sprite.prototype.kill = function() { return this; -} +}; /** * Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present @@ -853,7 +811,7 @@ Phaser.Sprite.prototype.destroy = function() { this.game = null; -} +}; /** * Damages the Sprite, this removes the given amount from the Sprites health property. @@ -878,7 +836,7 @@ Phaser.Sprite.prototype.damage = function(amount) { return this; -} +}; /** * Resets the Sprite. This places the Sprite at the given x/y world coordinates and then @@ -915,7 +873,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) { return this; -} +}; /** * Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only @@ -938,7 +896,7 @@ Phaser.Sprite.prototype.bringToTop = function() { return this; -} +}; /** * Play an animation based on the given key. The animation should previously have been added via sprite.animations.add() @@ -959,7 +917,7 @@ Phaser.Sprite.prototype.play = function (name, frameRate, loop, killOnComplete) return this.animations.play(name, frameRate, loop, killOnComplete); } -} +}; /** * Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. diff --git a/src/input/Mouse.js b/src/input/Mouse.js index cf44e993..3a781c01 100644 --- a/src/input/Mouse.js +++ b/src/input/Mouse.js @@ -117,6 +117,8 @@ Phaser.Mouse.prototype = { */ onMouseDown: function (event) { + event.preventDefault(); + if (this.mouseDownCallback) { this.mouseDownCallback.call(this.callbackContext, event); @@ -140,6 +142,8 @@ Phaser.Mouse.prototype = { */ onMouseMove: function (event) { + event.preventDefault(); + if (this.mouseMoveCallback) { this.mouseMoveCallback.call(this.callbackContext, event); @@ -163,6 +167,8 @@ Phaser.Mouse.prototype = { */ onMouseUp: function (event) { + event.preventDefault(); + if (this.mouseUpCallback) { this.mouseUpCallback.call(this.callbackContext, event); diff --git a/src/input/Pointer.js b/src/input/Pointer.js index 2558d1a7..402e2e55 100644 --- a/src/input/Pointer.js +++ b/src/input/Pointer.js @@ -278,8 +278,8 @@ Phaser.Pointer.prototype = { if (this.game.input.multiInputOverride == Phaser.Input.MOUSE_OVERRIDES_TOUCH || this.game.input.multiInputOverride == Phaser.Input.MOUSE_TOUCH_COMBINE || (this.game.input.multiInputOverride == Phaser.Input.TOUCH_OVERRIDES_MOUSE && this.game.input.currentPointers == 0)) { - this.game.input.x = this.x * this.game.input.scale.x; - this.game.input.y = this.y * this.game.input.scale.y; + this.game.input.x = this.x; + this.game.input.y = this.y; this.game.input.position.setTo(this.x, this.y); this.game.input.onDown.dispatch(this, event); this.game.input.resetSpeed(this.x, this.y); diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index 42ae010a..c825042f 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -404,12 +404,6 @@ Phaser.Physics.Arcade.prototype = { this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true); - // console.log('getTiles', this._tx, this._ty); - if (this.game.input.keyboard.isDown(Phaser.Keyboard.SHIFT)) - { - console.log('cst', this._mapData, sprite.body.x, sprite.body.y); - } - if (this._mapData.length == 0) { return; diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index 10f81ffc..eba8cf1a 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -547,7 +547,7 @@ Phaser.Physics.Arcade.Body.prototype = { }, /** - * Returns the delta x value. + * Returns the delta x value. The difference between Body.x now and in the previous step. * * @method Phaser.Physics.Arcade.Body#deltaX * @return {number} The delta value. @@ -557,7 +557,7 @@ Phaser.Physics.Arcade.Body.prototype = { }, /** - * Returns the delta y value. + * Returns the delta y value. The difference between Body.y now and in the previous step. * * @method Phaser.Physics.Arcade.Body#deltaY * @return {number} The delta value. diff --git a/src/system/StageScaleMode.js b/src/system/StageScaleMode.js index e21657bb..142e4610 100644 --- a/src/system/StageScaleMode.js +++ b/src/system/StageScaleMode.js @@ -85,15 +85,27 @@ Phaser.StageScaleMode = function (game, width, height) { /** * @property {number} width - Width of the stage after calculation. - * @default */ - this.width = 0; + this.width = width; /** * @property {number} height - Height of the stage after calculation. - * @default */ - this.height = 0; + this.height = height; + + /** + * @property {number} _width - Cached stage width for full screen mode. + * @default + * @private + */ + this._width = 0; + + /** + * @property {number} _height - Cached stage height for full screen mode. + * @default + * @private + */ + this._height = 0; /** * @property {number} maxIterations - The maximum number of times it will try to resize the canvas to fill the browser. @@ -152,6 +164,18 @@ Phaser.StageScaleMode = function (game, width, height) { window.addEventListener('resize', function (event) { return _this.checkResize(event); }, false); + + document.addEventListener('webkitfullscreenchange', function (event) { + return _this.fullScreenChange(event); + }, false); + + document.addEventListener('mozfullscreenchange', function (event) { + return _this.fullScreenChange(event); + }, false); + + document.addEventListener('fullscreenchange', function (event) { + return _this.fullScreenChange(event); + }, false); }; @@ -179,16 +203,27 @@ Phaser.StageScaleMode.prototype = { * Tries to enter the browser into full screen mode. * Please note that this needs to be supported by the web browser and isn't the same thing as setting your game to fill the browser. * @method Phaser.StageScaleMode#startFullScreen + * @param {boolean} antialias - You can toggle the anti-alias feature of the canvas before jumping in to full screen (false = retain pixel art, true = smooth art) */ - startFullScreen: function () { + startFullScreen: function (antialias) { if (this.isFullScreen) { return; } + if (typeof antialias !== 'undefined') + { + Phaser.Canvas.setSmoothingEnabled(this.game.context, antialias); + } + var element = this.game.canvas; + this._width = this.width; + this._height = this.height; + + console.log('startFullScreen', this._width, this._height); + if (element['requestFullScreen']) { element['requestFullScreen'](); @@ -202,9 +237,6 @@ Phaser.StageScaleMode.prototype = { element['webkitRequestFullScreen'](Element.ALLOW_KEYBOARD_INPUT); } - this.game.stage.canvas.style['width'] = '100%'; - this.game.stage.canvas.style['height'] = '100%'; - }, /** @@ -228,6 +260,44 @@ Phaser.StageScaleMode.prototype = { }, + /** + * Called automatically when the browser enters of leaves full screen mode. + * @method Phaser.StageScaleMode#fullScreenChange + * @param {Event} event - The fullscreenchange event + * @protected + */ + fullScreenChange: function (event) { + + if (this.isFullScreen) + { + this.game.stage.canvas.style['width'] = '100%'; + this.game.stage.canvas.style['height'] = '100%'; + + this.setMaximum(); + + this.game.input.scale.setTo(this.game.width / this.width, this.game.height / this.height); + + this.aspectRatio = this.width / this.height; + this.scaleFactor.x = this.game.width / this.width; + this.scaleFactor.y = this.game.height / this.height; + } + else + { + this.game.stage.canvas.style['width'] = this.game.width + 'px'; + this.game.stage.canvas.style['height'] = this.game.height + 'px'; + + this.width = this._width; + this.height = this._height; + + this.game.input.scale.setTo(this.game.width / this.width, this.game.height / this.height); + + this.aspectRatio = this.width / this.height; + this.scaleFactor.x = this.game.width / this.width; + this.scaleFactor.y = this.game.height / this.height; + } + + }, + /** * Checks if the browser is in the correct orientation for your game (if forceLandscape or forcePortrait have been set) * @method Phaser.StageScaleMode#checkOrientationState @@ -495,8 +565,8 @@ Phaser.StageScaleMode.prototype = { */ setExactFit: function () { - var availableWidth = window.innerWidth - 0; - var availableHeight = window.innerHeight - 5; + var availableWidth = window.innerWidth; + var availableHeight = window.innerHeight; // console.log('available', availableWidth, availableHeight); @@ -518,8 +588,6 @@ Phaser.StageScaleMode.prototype = { this.height = availableHeight; } - console.log('setExactFit', this.width, this.height, this.game.stage.offset); - } }; @@ -533,12 +601,7 @@ Object.defineProperty(Phaser.StageScaleMode.prototype, "isFullScreen", { get: function () { - if (document['fullscreenElement'] === null || document['mozFullScreenElement'] === null || document['webkitFullscreenElement'] === null) - { - return false; - } - - return true; + return (document['fullscreenElement'] || document['mozFullScreenElement'] || document['webkitFullscreenElement']) } diff --git a/src/tilemap/TilemapLayer.js b/src/tilemap/TilemapLayer.js index 65b3e370..df5c8ad6 100644 --- a/src/tilemap/TilemapLayer.js +++ b/src/tilemap/TilemapLayer.js @@ -166,7 +166,8 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, }; -Phaser.TilemapLayer.prototype = Phaser.Utils.extend(true, Phaser.Sprite.prototype, PIXI.Sprite.prototype); +Phaser.TilemapLayer.prototype = Object.create(Phaser.Sprite.prototype); +Phaser.TilemapLayer.prototype = Phaser.Utils.extend(true, Phaser.TilemapLayer.prototype, Phaser.Sprite.prototype, PIXI.Sprite.prototype); Phaser.TilemapLayer.prototype.constructor = Phaser.TilemapLayer; diff --git a/src/utils/Debug.js b/src/utils/Debug.js index d252d883..3ce3beff 100644 --- a/src/utils/Debug.js +++ b/src/utils/Debug.js @@ -222,6 +222,7 @@ Phaser.Utils.Debug.prototype = { this.context.strokeStyle = 'rgba(255, 0, 255, 0.7)'; this.context.stroke(); + this.renderPoint(sprite.offset); this.renderPoint(sprite.center); this.renderPoint(sprite.topLeft); this.renderPoint(sprite.topRight);