diff --git a/Phaser/Game.ts b/Phaser/Game.ts index 52db70dc..7df89909 100644 --- a/Phaser/Game.ts +++ b/Phaser/Game.ts @@ -416,6 +416,8 @@ module Phaser { this.onUpdateCallback.call(this.callbackContext); } + this.world.postUpdate(); + this.renderer.render(); if (this._loadComplete && this.onRenderCallback) diff --git a/Phaser/World.ts b/Phaser/World.ts index 2eb6dd88..0b1aabbf 100644 --- a/Phaser/World.ts +++ b/Phaser/World.ts @@ -96,6 +96,17 @@ module Phaser { } + /** + * This is called automatically every frame, and is where main logic happens. + */ + public postUpdate() { + + //this.physics.postUpdate(); + this.group.postUpdate(); + this.cameras.postUpdate(); + + } + /** * Clean up memory. */ diff --git a/Phaser/cameras/Camera.ts b/Phaser/cameras/Camera.ts index 66a40c9b..b8badc77 100644 --- a/Phaser/cameras/Camera.ts +++ b/Phaser/cameras/Camera.ts @@ -291,10 +291,6 @@ module Phaser { { this.modified = true; } - else if (this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) - { - this.modified = false; - } this.fx.preUpdate(); @@ -365,6 +361,42 @@ module Phaser { } } + } + + /** + * Update focusing and scrolling. + */ + public postUpdate() { + + if (this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) + { + this.modified = false; + } + + // Make sure we didn't go outside the cameras worldBounds + if (this.worldBounds !== null) + { + if (this.worldView.x < this.worldBounds.left) + { + this.worldView.x = this.worldBounds.left; + } + + if (this.worldView.x > this.worldBounds.right - this.width) + { + this.worldView.x = (this.worldBounds.right - this.width) + 1; + } + + if (this.worldView.y < this.worldBounds.top) + { + this.worldView.y = this.worldBounds.top; + } + + if (this.worldView.y > this.worldBounds.bottom - this.height) + { + this.worldView.y = (this.worldBounds.bottom - this.height) + 1; + } + } + this.fx.postUpdate(); } @@ -380,11 +412,12 @@ module Phaser { this.game.stage.context.fillStyle = color; this.game.stage.context.fillText('Camera ID: ' + this.ID + ' (' + this.screenView.width + ' x ' + this.screenView.height + ')', x, y); this.game.stage.context.fillText('X: ' + this.screenView.x + ' Y: ' + this.screenView.y + ' rotation: ' + this.transform.rotation, x, y + 14); - this.game.stage.context.fillText('World X: ' + this.worldView.x.toFixed(1) + ' World Y: ' + this.worldView.y.toFixed(1), x, y + 28); + this.game.stage.context.fillText('World X: ' + this.worldView.x + ' World Y: ' + this.worldView.y + ' W: ' + this.worldView.width + ' H: ' + this.worldView.height + ' R: ' + this.worldView.right + ' B: ' + this.worldView.bottom, x, y + 28); + this.game.stage.context.fillText('ScreenView X: ' + this.screenView.x + ' Y: ' + this.screenView.y + ' W: ' + this.screenView.width + ' H: ' + this.screenView.height, x, y + 42); if (this.worldBounds) { - this.game.stage.context.fillText('Bounds: ' + this.worldBounds.width + ' x ' + this.worldBounds.height, x, y + 42); + this.game.stage.context.fillText('Bounds: ' + this.worldBounds.width + ' x ' + this.worldBounds.height, x, y + 56); } } diff --git a/Phaser/cameras/CameraManager.ts b/Phaser/cameras/CameraManager.ts index c3bbc476..2b85559a 100644 --- a/Phaser/cameras/CameraManager.ts +++ b/Phaser/cameras/CameraManager.ts @@ -83,7 +83,24 @@ module Phaser { * Update cameras. */ public update() { - this._cameras.forEach((camera) => camera.update()); + + for (var i = 0; i < this._cameras.length; i++) + { + this._cameras[i].update(); + } + + } + + /** + * postUpdate cameras. + */ + public postUpdate() { + + for (var i = 0; i < this._cameras.length; i++) + { + this._cameras[i].postUpdate(); + } + } /** diff --git a/Phaser/components/sprite/Input.ts b/Phaser/components/sprite/Input.ts index 91641e98..6adac87f 100644 --- a/Phaser/components/sprite/Input.ts +++ b/Phaser/components/sprite/Input.ts @@ -258,7 +258,7 @@ module Phaser.Components.Sprite { } else { - return RectangleUtils.contains(this.sprite.worldView, pointer.scaledX, pointer.scaledY); + return RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY()); } } @@ -279,10 +279,10 @@ module Phaser.Components.Sprite { } else if (this._pointerData[pointer.id].isOver == true) { - if (RectangleUtils.contains(this.sprite.worldView, pointer.scaledX, pointer.scaledY)) + if (RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY())) { - this._pointerData[pointer.id].x = pointer.scaledX - this.sprite.x; - this._pointerData[pointer.id].y = pointer.scaledY - this.sprite.y; + this._pointerData[pointer.id].x = pointer.x - this.sprite.x; + this._pointerData[pointer.id].y = pointer.y - this.sprite.y; return true; } else diff --git a/Phaser/core/Group.ts b/Phaser/core/Group.ts index 3fe8f725..ad9397d7 100644 --- a/Phaser/core/Group.ts +++ b/Phaser/core/Group.ts @@ -186,7 +186,28 @@ module Phaser { { this.modified = true; } - else if (this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) + + this._i = 0; + + while (this._i < this.length) + { + this._member = this.members[this._i++]; + + if (this._member != null && this._member.exists && this._member.active) + { + this._member.preUpdate(); + this._member.update(); + } + } + } + + /** + * Calls update on all members of this Group who have a status of active=true and exists=true + * You can also call Object.postUpdate directly, which will bypass the active/exists check. + */ + public postUpdate() { + + if (this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { this.modified = false; } @@ -199,8 +220,6 @@ module Phaser { if (this._member != null && this._member.exists && this._member.active) { - this._member.preUpdate(); - this._member.update(); this._member.postUpdate(); } } @@ -398,10 +417,10 @@ module Phaser { * @param y {number} Y position of the new sprite. * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite * @param [frame] {string|number} 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. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) * @returns {Sprite} The newly created sprite object. */ - public addNewSprite(x: number, y: number, key?: string = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DISABLED): Sprite { + public addNewSprite(x: number, y: number, key?: string = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DYNAMIC): Sprite { return this.add(new Sprite(this.game, x, y, key, frame, bodyType)); } diff --git a/Phaser/gameobjects/GameObjectFactory.ts b/Phaser/gameobjects/GameObjectFactory.ts index 22a6de4b..d74ac54c 100644 --- a/Phaser/gameobjects/GameObjectFactory.ts +++ b/Phaser/gameobjects/GameObjectFactory.ts @@ -72,7 +72,7 @@ module Phaser { * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) * @returns {Sprite} The newly created sprite object. */ - public sprite(x: number, y: number, key?: string = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DISABLED): Sprite { + public sprite(x: number, y: number, key?: string = '', frame? = null, bodyType?: number = Phaser.Types.BODY_DYNAMIC): Sprite { return this._world.group.add(new Sprite(this._game, x, y, key, frame, bodyType)); } diff --git a/Phaser/gameobjects/Sprite.ts b/Phaser/gameobjects/Sprite.ts index c58cda21..001d59b1 100644 --- a/Phaser/gameobjects/Sprite.ts +++ b/Phaser/gameobjects/Sprite.ts @@ -23,9 +23,9 @@ module Phaser { * @param [x] {number} the initial x position of the sprite. * @param [y] {number} the initial y position of the sprite. * @param [key] {string} Key of the graphic you want to load for this sprite. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) */ - constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, frame? = null, bodyType?: number = Phaser.Types.BODY_DISABLED) { + constructor(game: Game, x?: number = 0, y?: number = 0, key?: string = null, frame? = null, bodyType?: number = Phaser.Types.BODY_DYNAMIC) { this.game = game; this.type = Phaser.Types.SPRITE; @@ -43,7 +43,6 @@ module Phaser { this.transform = new Phaser.Components.Transform(this); this.animations = new Phaser.Components.AnimationManager(this); this.texture = new Phaser.Components.Texture(this); - this.body = new Phaser.Physics.Body(this, bodyType); this.input = new Phaser.Components.Sprite.Input(this); this.events = new Phaser.Components.Sprite.Events(this); @@ -68,6 +67,7 @@ module Phaser { } } + this.body = new Phaser.Physics.Body(this, bodyType); this.worldView = new Rectangle(x, y, this.width, this.height); } @@ -233,8 +233,10 @@ module Phaser { */ public preUpdate() { - this.worldView.x = this.x - (this.game.world.cameras.default.worldView.x * this.transform.scrollFactor.x); - this.worldView.y = this.y - (this.game.world.cameras.default.worldView.y * this.transform.scrollFactor.y); + //this.worldView.x = this.x * this.transform.scrollFactor.x; + //this.worldView.y = this.y * this.transform.scrollFactor.y; + this.worldView.x = this.x - this.transform.origin.x; + this.worldView.y = this.y - this.transform.origin.y; this.worldView.width = this.width; this.worldView.height = this.height; diff --git a/Phaser/input/Input.ts b/Phaser/input/Input.ts index 5153f9f3..6c76469d 100644 --- a/Phaser/input/Input.ts +++ b/Phaser/input/Input.ts @@ -42,11 +42,15 @@ module Phaser { this.onTap = new Phaser.Signal(); this.onHold = new Phaser.Signal(); + this.scale = new Vec2(1, 1); this.speed = new Vec2; this.position = new Vec2; this._oldPosition = new Vec2; this.circle = new Circle(0, 0, 44); + this.camera = this._game.camera; + + this.activePointer = this.mousePointer; this.currentPointers = 0; } @@ -63,6 +67,20 @@ module Phaser { **/ private _oldPosition: Vec2 = null; + /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + private _x: number = 0; + + /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + private _y: number = 0; + /** * You can disable all Input by setting Input.disabled = true. While set all new input related events will be ignored. * If you need to disable just one type of input, for example mouse, use Input.mouse.disabled = true instead @@ -93,6 +111,13 @@ module Phaser { */ public static MOUSE_TOUCH_COMBINE: number = 2; + /** + * The camera being used for mouse and touch based pointers to calculate their world coordinates. + * @property camera + * @type {Camera} + **/ + public camera: Camera; + /** * Phaser.Mouse handler * @type {Mouse} @@ -147,30 +172,11 @@ module Phaser { public circle: Circle = null; /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private - */ - private _x: number = 0; - - /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private - */ - private _y: number = 0; - - /** - * - * @type {Number} + * The scale by which all input coordinates are multiplied, calculated by the StageScaleMode. + * In an un-scaled game the values will be x: 1 and y: 1. + * @type {Vec2} */ - public scaleX: number = 1; - - /** - * - * @type {Number} - */ - public scaleY: number = 1; + public scale: Vec2 = null; /** * The maximum number of Pointers allowed to be active at any one time. @@ -347,37 +353,39 @@ module Phaser { public pointer10: Pointer = null; /** - * The screen X coordinate + * The most recently active Pointer object. + * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse. + * @property activePointer + * @type {Pointer} + **/ + public activePointer: Pointer = null; + + /** + * The X coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values. * @property x * @type {Number} **/ public get x(): number { - return this._x; - } public set x(value: number) { - this._x = Math.round(value); - } /** - * The screen Y coordinate + * The Y coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenY/clientY for source values. * @property y * @type {Number} **/ public get y(): number { - return this._y; - } public set y(value: number) { - this._y = Math.round(value); - } /** @@ -469,7 +477,6 @@ module Phaser { **/ public update() { - // Swap for velocity vector - and add it to Pointer? this.speed.x = this.position.x - this._oldPosition.x; this.speed.y = this.position.y - this._oldPosition.y; @@ -488,6 +495,7 @@ module Phaser { if (this.pointer9) { this.pointer9.update(); } if (this.pointer10) { this.pointer10.update(); } + } /** @@ -883,18 +891,14 @@ module Phaser { * @param {Camera} [camera] */ public getWorldX(camera?: Camera = this._game.camera) { - return camera.worldView.x + this.x; - } /** * @param {Camera} [camera] */ public getWorldY(camera?: Camera = this._game.camera) { - return camera.worldView.y + this.y; - } /** @@ -904,12 +908,12 @@ module Phaser { */ public renderDebugInfo(x: number, y: number, color?: string = 'rgb(255,255,255)') { - this._game.stage.context.font = '14px Courier'; this._game.stage.context.fillStyle = color; this._game.stage.context.fillText('Input', x, y); - this._game.stage.context.fillText('Screen X: ' + this.x + ' Screen Y: ' + this.y, x, y + 14); + this._game.stage.context.fillText('X: ' + this.x + ' Y: ' + this.y, x, y + 14); this._game.stage.context.fillText('World X: ' + this.getWorldX() + ' World Y: ' + this.getWorldY(), x, y + 28); - this._game.stage.context.fillText('Scale X: ' + this.scaleX.toFixed(1) + ' Scale Y: ' + this.scaleY.toFixed(1), x, y + 42); + this._game.stage.context.fillText('Scale X: ' + this.scale.x.toFixed(1) + ' Scale Y: ' + this.scale.x.toFixed(1), x, y + 42); + this._game.stage.context.fillText('Screen X: ' + this.activePointer.screenX + ' Screen Y: ' + this.activePointer.screenY, x, y + 56); } diff --git a/Phaser/input/Pointer.ts b/Phaser/input/Pointer.ts index a5edaf65..e9afa9b3 100644 --- a/Phaser/input/Pointer.ts +++ b/Phaser/input/Pointer.ts @@ -170,14 +170,14 @@ module Phaser { public screenY: number = -1; /** - * The horizontal coordinate of point relative to the game element + * The horizontal coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property x * @type {Number} */ public x: number = -1; /** - * The vertical coordinate of point relative to the game element + * The vertical coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property y * @type {Number} */ @@ -263,39 +263,19 @@ module Phaser { public targetObject = null; /** - * Gets the X value of this Pointer in world coordinate space (is it properly scaled?) + * Gets the X value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ - public getWorldX(camera?: Camera = this.game.camera) { - + public worldX(camera?: Camera = this.game.input.camera) { return camera.worldView.x + this.x; - } /** - * Gets the Y value of this Pointer in world coordinate space + * Gets the Y value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ - public getWorldY(camera?: Camera = this.game.camera) { - + public worldY(camera?: Camera = this.game.input.camera) { return camera.worldView.y + this.y; - - } - - /** - * Gets the X value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - public get scaledX():number { - return Math.floor(this.x * this.game.input.scaleX); - } - - /** - * Gets the Y value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - public get scaledY():number { - return Math.floor(this.y * this.game.input.scaleY); } /** @@ -329,15 +309,18 @@ module Phaser { this.timeDown = this.game.time.now; this._holdSent = false; + // This sets the x/y and other local values + this.move(event); + // x and y are the old values here? this.positionDown.setTo(this.x, this.y); - this.move(event); - if (this.game.input.multiInputOverride == Input.MOUSE_OVERRIDES_TOUCH || this.game.input.multiInputOverride == Input.MOUSE_TOUCH_COMBINE || (this.game.input.multiInputOverride == Input.TOUCH_OVERRIDES_MOUSE && this.game.input.currentPointers == 0)) { - this.game.input.x = this.x * this.game.input.scaleX; - this.game.input.y = this.y * this.game.input.scaleY; + //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.onDown.dispatch(this); } @@ -407,8 +390,8 @@ module Phaser { this.screenX = event.screenX; this.screenY = event.screenY; - this.x = this.pageX - this.game.stage.offset.x; - this.y = this.pageY - this.game.stage.offset.y; + this.x = (this.pageX - this.game.stage.offset.x) * this.game.input.scale.x; + this.y = (this.pageY - this.game.stage.offset.y) * this.game.input.scale.y; this.position.setTo(this.x, this.y); this.circle.x = this.x; @@ -416,8 +399,9 @@ module Phaser { if (this.game.input.multiInputOverride == Input.MOUSE_OVERRIDES_TOUCH || this.game.input.multiInputOverride == Input.MOUSE_TOUCH_COMBINE || (this.game.input.multiInputOverride == Input.TOUCH_OVERRIDES_MOUSE && this.game.input.currentPointers == 0)) { - this.game.input.x = this.x * this.game.input.scaleX; - this.game.input.y = this.y * this.game.input.scaleY; + this.game.input.activePointer = this; + this.game.input.x = this.x; + this.game.input.y = this.y; this.game.input.position.setTo(this.game.input.x, this.game.input.y); this.game.input.circle.x = this.game.input.x; this.game.input.circle.y = this.game.input.y; diff --git a/Phaser/physics/Body.ts b/Phaser/physics/Body.ts index cd2d17fa..aaa547b1 100644 --- a/Phaser/physics/Body.ts +++ b/Phaser/physics/Body.ts @@ -18,11 +18,15 @@ module Phaser.Physics { // Fixture properties // Will extend into its own class at a later date - can move the fixture defs there and add shape support, but this will do for 1.0 release - this.bounds = new Rectangle(sprite.x + Math.round(sprite.width / 2), sprite.y + Math.round(sprite.height / 2), sprite.width, sprite.height); - this.bounce = Vec2Utils.clone(this.game.world.physics.bounce); + this.bounds = new Rectangle; + + this._width = sprite.width; + this._height = sprite.height; + // Body properties this.gravity = Vec2Utils.clone(this.game.world.physics.gravity); + this.bounce = Vec2Utils.clone(this.game.world.physics.bounce); this.velocity = new Vec2; this.acceleration = new Vec2; @@ -49,7 +53,7 @@ module Phaser.Physics { public game: Game; /** - * Reference to the sprite Sprite + * Reference to the parent Sprite */ public sprite: Phaser.Sprite; @@ -94,17 +98,41 @@ module Phaser.Physics { + private _width: number = 0; + private _height: number = 0; + + public get x(): number { + return this.sprite.x + this.offset.x; + } + + public get y(): number { + return this.sprite.y + this.offset.y; + } + + public set width(value: number) { + this._width = value; + } + + public set height(value: number) { + this._height = value; + } + + public get width(): number { + return this._width * this.sprite.transform.scale.x; + } + + public get height(): number { + return this._height * this.sprite.transform.scale.y; + } public preUpdate() { this.oldPosition.copyFrom(this.position); - this.bounds.x = this.position.x - this.bounds.halfWidth; - this.bounds.y = this.position.y - this.bounds.halfHeight; - - if (this.sprite.transform.scale.equals(1) == false) - { - } + this.bounds.x = this.x; + this.bounds.y = this.y; + this.bounds.width = this.width; + this.bounds.height = this.height; } @@ -117,14 +145,13 @@ module Phaser.Physics { { this.game.world.physics.updateMotion(this); - this.sprite.x = (this.position.x - this.bounds.halfWidth) - this.offset.x; - this.sprite.y = (this.position.y - this.bounds.halfHeight) - this.offset.y; - this.wasTouching = this.touching; this.touching = Phaser.Types.NONE; } + this.position.setTo(this.x, this.y); + } public get hullWidth(): number { diff --git a/Phaser/physics/PhysicsManager.ts b/Phaser/physics/PhysicsManager.ts index d11399da..ab24ed07 100644 --- a/Phaser/physics/PhysicsManager.ts +++ b/Phaser/physics/PhysicsManager.ts @@ -62,9 +62,6 @@ module Phaser.Physics { private _quadTree: QuadTree; private _quadTreeResult: bool; - - - public bounds: Rectangle; public gravity: Vec2; @@ -148,13 +145,15 @@ module Phaser.Physics { body.velocity.x += this._velocityDelta; this._delta = body.velocity.x * this.game.time.elapsed; body.velocity.x += this._velocityDelta; - body.position.x += this._delta; + //body.position.x += this._delta; + body.sprite.x += this._delta; this._velocityDelta = (this.computeVelocity(body.velocity.y, body.gravity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2; body.velocity.y += this._velocityDelta; this._delta = body.velocity.y * this.game.time.elapsed; body.velocity.y += this._velocityDelta; - body.position.y += this._delta; + //body.position.y += this._delta; + body.sprite.y += this._delta; } @@ -748,6 +747,8 @@ module Phaser.Physics { this._quadTreeResult = this._quadTree.execute(); + console.log('over', this._quadTreeResult); + this._quadTree.destroy(); this._quadTree = null; diff --git a/Phaser/renderers/CanvasRenderer.ts b/Phaser/renderers/CanvasRenderer.ts index 72aedd85..cd5777d1 100644 --- a/Phaser/renderers/CanvasRenderer.ts +++ b/Phaser/renderers/CanvasRenderer.ts @@ -215,24 +215,13 @@ module Phaser { */ public inCamera(camera: Camera, sprite: Sprite): bool { - return true; - - /* - // Object fixed in place regardless of the camera scrolling? Then it's always visible - if (sprite.scrollFactor.x == 0 && sprite.scrollFactor.y == 0) + if (sprite.transform.scrollFactor.equals(0)) { return true; } - this._dx = sprite.frameBounds.x - (camera.worldView.x * sprite.scrollFactor.x); - this._dy = sprite.frameBounds.y - (camera.worldView.y * sprite.scrollFactor.y); - this._dw = sprite.frameBounds.width * sprite.scale.x; - this._dh = sprite.frameBounds.height * sprite.scale.y; - - //return (camera.screenView.x + camera.worldView.width > this._dx) && (camera.screenView.x < this._dx + this._dw) && (camera.screenView.y + camera.worldView.height > this._dy) && (camera.screenView.y < this._dy + this._dh); - - */ + return RectangleUtils.intersects(sprite.worldView, camera.worldView); } diff --git a/Phaser/renderers/HeadlessRenderer.ts b/Phaser/renderers/HeadlessRenderer.ts index 7225c950..f130147e 100644 --- a/Phaser/renderers/HeadlessRenderer.ts +++ b/Phaser/renderers/HeadlessRenderer.ts @@ -10,39 +10,29 @@ module Phaser { this._game = game; } - /** - * The essential reference to the main game object - */ private _game: Phaser.Game; public render() {} - public renderGameObject(object) { - } + public inCamera(camera: Camera, sprite: Sprite): bool { return true; } - public renderSprite(camera: Camera, sprite: Sprite): bool { - return true; - } + public renderGameObject(object) {} - public renderScrollZone(camera: Camera, scrollZone: ScrollZone): bool { - return true; - } + public renderSprite(camera: Camera, sprite: Sprite): bool { return true; } + + public renderScrollZone(camera: Camera, scrollZone: ScrollZone): bool { return true; } public renderCircle(camera: Camera, circle: Circle, context, outline?: bool = true, fill?: bool = true, lineColor?: string = 'rgb(0,255,0)', fillColor?: string = 'rgba(0,100,0.0.3)', lineWidth?: number = 1): bool { return true; } - public preRenderCamera(camera: Camera) { - } + public preRenderCamera(camera: Camera) { } - public postRenderCamera(camera: Camera) { - } + public postRenderCamera(camera: Camera) { } - public preRenderGroup(camera: Camera, group: Group) { - } + public preRenderGroup(camera: Camera, group: Group) { } - public postRenderGroup(camera: Camera, group: Group) { - } + public postRenderGroup(camera: Camera, group: Group) { } } diff --git a/Phaser/renderers/IRenderer.ts b/Phaser/renderers/IRenderer.ts index 07acbc94..07fd14d9 100644 --- a/Phaser/renderers/IRenderer.ts +++ b/Phaser/renderers/IRenderer.ts @@ -13,7 +13,8 @@ module Phaser { postRenderGroup(camera: Camera, group: Group); preRenderCamera(camera: Camera); postRenderCamera(camera: Camera); - + + inCamera(camera: Camera, sprite: Sprite): bool; } diff --git a/Phaser/system/StageScaleMode.ts b/Phaser/system/StageScaleMode.ts index fd3e5fe1..317c6911 100644 --- a/Phaser/system/StageScaleMode.ts +++ b/Phaser/system/StageScaleMode.ts @@ -446,8 +446,7 @@ module Phaser { this._game.stage.canvas.style.width = this.width + 'px'; this._game.stage.canvas.style.height = this.height + 'px'; - this._game.input.scaleX = this._game.stage.width / this.width; - this._game.input.scaleY = this._game.stage.height / this.height; + this._game.input.scale.setTo(this._game.stage.width / this.width, this._game.stage.height / this.height); if (this.pageAlignHorizontally) { diff --git a/Phaser/utils/DebugUtils.ts b/Phaser/utils/DebugUtils.ts index 8a775fbe..d27b0cb6 100644 --- a/Phaser/utils/DebugUtils.ts +++ b/Phaser/utils/DebugUtils.ts @@ -26,10 +26,44 @@ module Phaser { static renderSpriteInfo(sprite: Sprite, x: number, y: number, color?: string = 'rgb(255,255,255)') { DebugUtils.game.stage.context.fillStyle = color; - DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ')', x, y); + DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y); DebugUtils.game.stage.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14); - //DebugUtils.game.stage.context.fillText('dx: ' + this._dx.toFixed(1) + ' dy: ' + this._dy.toFixed(1) + ' dw: ' + this._dw.toFixed(1) + ' dh: ' + this._dh.toFixed(1), x, y + 28); - //DebugUtils.game.stage.context.fillText('sx: ' + this._sx.toFixed(1) + ' sy: ' + this._sy.toFixed(1) + ' sw: ' + this._sw.toFixed(1) + ' sh: ' + this._sh.toFixed(1), x, y + 42); + DebugUtils.game.stage.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28); + DebugUtils.game.stage.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42); + DebugUtils.game.stage.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56); + DebugUtils.game.stage.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 70); + + } + + static renderSpriteBounds(sprite: Sprite, camera?: Camera = null, color?: string = 'rgba(0,255,0,0.2)') { + + if (camera == null) + { + camera = DebugUtils.game.camera; + } + + //var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + //var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + var dx = sprite.worldView.x; + var dy = sprite.worldView.y; + + DebugUtils.game.stage.context.fillStyle = color; + DebugUtils.game.stage.context.fillRect(dx, dy, sprite.width, sprite.height); + + } + + static renderSpritePhysicsBody(sprite: Sprite, camera?: Camera = null, color?: string = 'rgba(255,0,0,0.2)') { + + if (camera == null) + { + camera = DebugUtils.game.camera; + } + + var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.body.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.body.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + + DebugUtils.game.stage.context.fillStyle = color; + DebugUtils.game.stage.context.fillRect(dx, dy, sprite.body.width, sprite.body.height); } diff --git a/README.md b/README.md index d6b9efea..8c7c8478 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,13 @@ TODO: * Added JSON Texture Atlas object support. * RenderOrderID won't work across cameras - but then neither do Pointers yet anyway * Swap to using time based motion (like the tweens) rather than delta timer - it just doesn't work well on slow phones -* Bug in World drag +* Pointer.getWorldX(camera) needs to take camera scale into consideration +* Add a 'click to bring to top' demo (+ Group feature?) * Add clip support + shape options to Texture Component. +Make sure I'm using Point and not Vec2 when it's not a directional vector I need + V1.0.0 @@ -103,6 +106,11 @@ V1.0.0 * Created a Transform component containing scale, skew, rotation, scrollFactor, origin and rotationOffset. Added to Sprite, Camera, Group. * Created a Texture component containing image data, alpha, flippedX, flippedY, etc. Added to Sprite, Camera, Group. * Added CameraManager.swap and CameraManager.sort methods and added a z-index property to Camera to control render order. +* Added World.postUpdate loop + Group and Camera postUpdate methods. +* Fixed issue stopping Pointer from working in world coordinates and fixed the world drag example. +* For consistency renamed input.scaledX/Y = input.scale. +* Added input.activePointer which contains a reference to the most recently active pointer. + diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index f5e72a6e..0c682e29 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -69,6 +69,10 @@ + + + world sprite.ts + create group 1.ts @@ -90,12 +94,20 @@ + + + game scale 1.ts + motion lock 2.ts motion lock.ts + + + multitouch.ts + over sprite 1.ts diff --git a/Tests/cameras/world sprite.js b/Tests/cameras/world sprite.js new file mode 100644 index 00000000..588a638a --- /dev/null +++ b/Tests/cameras/world sprite.js @@ -0,0 +1,62 @@ +/// +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + function init() { + game.world.setSize(1920, 1200, true); + game.load.image('backdrop', 'assets/pics/remember-me.jpg'); + game.load.image('ball', 'assets/sprites/mana_card.png'); + game.load.start(); + } + var ball; + function create() { + game.add.sprite(0, 0, 'backdrop'); + ball = game.add.sprite(200, 200, 'ball'); + ball.body.offset.setTo(-16, -16); + ball.body.width = 100; + ball.body.height = 100; + ball.body.velocity.x = 50; + ball.transform.scale.setTo(2, 2); + } + function update() { + /* + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + game.camera.x -= 4; + //ball.x -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + game.camera.x += 4; + //ball.x += 4; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + game.camera.y -= 4; + //ball.y -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + game.camera.y += 4; + //ball.y += 4; + } + */ + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + ball.x -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + ball.x += 4; + } + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + ball.y -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + ball.y += 4; + } + } + function render() { + game.camera.renderDebugInfo(32, 32); + Phaser.DebugUtils.renderSpriteInfo(ball, 32, 200); + //Phaser.DebugUtils.renderSpriteBounds(ball); + Phaser.DebugUtils.renderSpritePhysicsBody(ball); + } +})(); diff --git a/Tests/cameras/world sprite.ts b/Tests/cameras/world sprite.ts new file mode 100644 index 00000000..597b4c67 --- /dev/null +++ b/Tests/cameras/world sprite.ts @@ -0,0 +1,91 @@ +/// +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render); + + function init() { + + game.world.setSize(1920, 1200, true); + + game.load.image('backdrop', 'assets/pics/remember-me.jpg'); + game.load.image('ball', 'assets/sprites/mana_card.png'); + + game.load.start(); + + } + + var ball: Phaser.Sprite; + + function create() { + + game.add.sprite(0, 0, 'backdrop'); + + ball = game.add.sprite(200, 200, 'ball'); + + ball.body.offset.setTo(-16, -16); + ball.body.width = 100; + ball.body.height = 100; + + ball.body.velocity.x = 50; + ball.transform.scale.setTo(2, 2); + + } + + function update() { + + /* + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + game.camera.x -= 4; + //ball.x -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + game.camera.x += 4; + //ball.x += 4; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + game.camera.y -= 4; + //ball.y -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + game.camera.y += 4; + //ball.y += 4; + } + */ + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + ball.x -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + ball.x += 4; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + ball.y -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + ball.y += 4; + } + + } + + function render() { + + game.camera.renderDebugInfo(32, 32); + Phaser.DebugUtils.renderSpriteInfo(ball, 32, 200); + //Phaser.DebugUtils.renderSpriteBounds(ball); + Phaser.DebugUtils.renderSpritePhysicsBody(ball); + + } + +})(); diff --git a/Tests/index.php b/Tests/index.php index 55369666..ff75d675 100644 --- a/Tests/index.php +++ b/Tests/index.php @@ -93,7 +93,6 @@ if (isset($_GET['m'])) View JavaScript View TypeScript -

You'll learn best from these Tests by viewing the source code.
diff --git a/Tests/input/game scale 1.js b/Tests/input/game scale 1.js new file mode 100644 index 00000000..1c00f49a --- /dev/null +++ b/Tests/input/game scale 1.js @@ -0,0 +1,35 @@ +/// +(function () { + // Here we create a tiny game (320x240 in size) + var game = new Phaser.Game(this, 'game', 320, 240, init, create, update, render); + function init() { + // This sets a limit on the up-scale + game.stage.scale.maxWidth = 800; + game.stage.scale.maxHeight = 600; + // Then we tell Phaser that we want it to scale up to whatever the browser can handle, but to do it proportionally + game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + game.load.image('melon', 'assets/sprites/melon.png'); + game.load.start(); + } + function create() { + game.world.setSize(2000, 2000); + for(var i = 0; i < 1000; i++) { + game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); + } + } + function update() { + if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) { + game.camera.x -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) { + game.camera.x += 4; + } + if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) { + game.camera.y -= 4; + } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) { + game.camera.y += 4; + } + } + function render() { + game.input.renderDebugInfo(16, 16); + } +})(); diff --git a/Tests/input/game scale 1.ts b/Tests/input/game scale 1.ts new file mode 100644 index 00000000..01448f7d --- /dev/null +++ b/Tests/input/game scale 1.ts @@ -0,0 +1,62 @@ +/// + +(function () { + + // Here we create a tiny game (320x240 in size) + var game = new Phaser.Game(this, 'game', 320, 240, init, create, update, render); + + function init() { + + // This sets a limit on the up-scale + game.stage.scale.maxWidth = 800; + game.stage.scale.maxHeight = 600; + + // Then we tell Phaser that we want it to scale up to whatever the browser can handle, but to do it proportionally + game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + + game.load.image('melon', 'assets/sprites/melon.png'); + + game.load.start(); + + } + + function create() { + + game.world.setSize(2000, 2000); + + for (var i = 0; i < 1000; i++) + { + game.add.sprite(game.world.randomX, game.world.randomY, 'melon'); + } + + } + + function update() { + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + game.camera.x -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + game.camera.x += 4; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + game.camera.y -= 4; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + game.camera.y += 4; + } + + } + + function render() { + + game.input.renderDebugInfo(16, 16); + + } + +})(); diff --git a/Tests/input/multitouch.js b/Tests/input/multitouch.js new file mode 100644 index 00000000..e0f2c4d4 --- /dev/null +++ b/Tests/input/multitouch.js @@ -0,0 +1,10 @@ +/// +(function () { + var game = new Phaser.Game(this, 'game', 800, 600, null, null, null, render); + function render() { + game.input.pointer1.renderDebug(); + game.input.pointer2.renderDebug(); + game.input.pointer3.renderDebug(); + game.input.pointer4.renderDebug(); + } +})(); diff --git a/Tests/input/multitouch.ts b/Tests/input/multitouch.ts new file mode 100644 index 00000000..f38ffa72 --- /dev/null +++ b/Tests/input/multitouch.ts @@ -0,0 +1,16 @@ +/// + +(function () { + + var game = new Phaser.Game(this, 'game', 800, 600, null, null, null, render); + + function render() { + + game.input.pointer1.renderDebug(); + game.input.pointer2.renderDebug(); + game.input.pointer3.renderDebug(); + game.input.pointer4.renderDebug(); + + } + +})(); diff --git a/Tests/input/over sprite 2.js b/Tests/input/over sprite 2.js index 52eb22b8..f73e906b 100644 --- a/Tests/input/over sprite 2.js +++ b/Tests/input/over sprite 2.js @@ -10,8 +10,8 @@ function create() { // Create a load of sprites for(var i = 0; i < 26; i++) { - var tempSprite = game.add.sprite(i * 32, 100, 'sprite', Phaser.Types.BODY_DYNAMIC); - tempSprite.input.enabled = true; + var tempSprite = game.add.sprite(i * 32, 100, 'sprite'); + tempSprite.input.start(0, false, true); tempSprite.events.onInputOver.add(dropSprite, this); } } diff --git a/Tests/input/over sprite 2.ts b/Tests/input/over sprite 2.ts index 475166ae..fbaf704a 100644 --- a/Tests/input/over sprite 2.ts +++ b/Tests/input/over sprite 2.ts @@ -19,8 +19,8 @@ // Create a load of sprites for (var i = 0; i < 26; i++) { - var tempSprite: Phaser.Sprite = game.add.sprite(i * 32, 100, 'sprite', Phaser.Types.BODY_DYNAMIC); - tempSprite.input.enabled = true; + var tempSprite: Phaser.Sprite = game.add.sprite(i * 32, 100, 'sprite'); + tempSprite.input.start(0, false, true); tempSprite.events.onInputOver.add(dropSprite, this); } diff --git a/Tests/input/world drag.js b/Tests/input/world drag.js index 685e7198..f6a3d3ab 100644 --- a/Tests/input/world drag.js +++ b/Tests/input/world drag.js @@ -35,5 +35,6 @@ game.camera.renderDebugInfo(32, 32); test.body.renderDebugInfo(300, 32); Phaser.DebugUtils.renderSpriteInfo(test, 32, 200); + game.input.renderDebugInfo(300, 200); } })(); diff --git a/Tests/input/world drag.ts b/Tests/input/world drag.ts index 8cb78a8c..afbb9f87 100644 --- a/Tests/input/world drag.ts +++ b/Tests/input/world drag.ts @@ -66,6 +66,8 @@ Phaser.DebugUtils.renderSpriteInfo(test, 32, 200); + game.input.renderDebugInfo(300, 200); + } })(); diff --git a/Tests/phaser.js b/Tests/phaser.js index 4839d5cb..a07d9581 100644 --- a/Tests/phaser.js +++ b/Tests/phaser.js @@ -3051,7 +3051,7 @@ var Phaser; if(this.enabled == false || this.sprite.visible == false) { return false; } else { - return Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.scaledX, pointer.scaledY); + return Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY()); } }; Input.prototype.update = /** @@ -3064,9 +3064,9 @@ var Phaser; if(this.draggable && this._draggedPointerID == pointer.id) { return this.updateDrag(pointer); } else if(this._pointerData[pointer.id].isOver == true) { - if(Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.scaledX, pointer.scaledY)) { - this._pointerData[pointer.id].x = pointer.scaledX - this.sprite.x; - this._pointerData[pointer.id].y = pointer.scaledY - this.sprite.y; + if(Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY())) { + this._pointerData[pointer.id].x = pointer.x - this.sprite.x; + this._pointerData[pointer.id].y = pointer.y - this.sprite.y; return true; } else { this._pointerOutHandler(pointer); @@ -3721,15 +3721,19 @@ var Phaser; this.angularDrag = 0; this.maxAngular = 10000; this.mass = 1; + this._width = 0; + this._height = 0; this.sprite = sprite; this.game = sprite.game; this.type = type; // Fixture properties // Will extend into its own class at a later date - can move the fixture defs there and add shape support, but this will do for 1.0 release - this.bounds = new Phaser.Rectangle(sprite.x + Math.round(sprite.width / 2), sprite.y + Math.round(sprite.height / 2), sprite.width, sprite.height); - this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce); + this.bounds = new Phaser.Rectangle(); + this._width = sprite.width; + this._height = sprite.height; // Body properties this.gravity = Phaser.Vec2Utils.clone(this.game.world.physics.gravity); + this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce); this.velocity = new Phaser.Vec2(); this.acceleration = new Phaser.Vec2(); this.drag = Phaser.Vec2Utils.clone(this.game.world.physics.drag); @@ -3744,12 +3748,46 @@ var Phaser; this.oldPosition = new Phaser.Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight); this.offset = new Phaser.Vec2(); } + Object.defineProperty(Body.prototype, "x", { + get: function () { + return this.sprite.x + this.offset.x; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Body.prototype, "y", { + get: function () { + return this.sprite.y + this.offset.y; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Body.prototype, "width", { + get: function () { + return this._width * this.sprite.transform.scale.x; + }, + set: function (value) { + this._width = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Body.prototype, "height", { + get: function () { + return this._height * this.sprite.transform.scale.y; + }, + set: function (value) { + this._height = value; + }, + enumerable: true, + configurable: true + }); Body.prototype.preUpdate = function () { this.oldPosition.copyFrom(this.position); - this.bounds.x = this.position.x - this.bounds.halfWidth; - this.bounds.y = this.position.y - this.bounds.halfHeight; - if(this.sprite.transform.scale.equals(1) == false) { - } + this.bounds.x = this.x; + this.bounds.y = this.y; + this.bounds.width = this.width; + this.bounds.height = this.height; }; Body.prototype.postUpdate = // Shall we do this? Or just update the values directly in the separate functions? But then the bounds will be out of sync - as long as // the bounds are updated and used in calculations then we can do one final sprite movement here I guess? @@ -3757,11 +3795,10 @@ var Phaser; // if this is all it does maybe move elsewhere? Sprite postUpdate? if(this.type !== Phaser.Types.BODY_DISABLED) { this.game.world.physics.updateMotion(this); - this.sprite.x = (this.position.x - this.bounds.halfWidth) - this.offset.x; - this.sprite.y = (this.position.y - this.bounds.halfHeight) - this.offset.y; this.wasTouching = this.touching; this.touching = Phaser.Types.NONE; } + this.position.setTo(this.x, this.y); }; Object.defineProperty(Body.prototype, "hullWidth", { get: function () { @@ -3922,14 +3959,14 @@ var Phaser; * @param [x] {number} the initial x position of the sprite. * @param [y] {number} the initial y position of the sprite. * @param [key] {string} Key of the graphic you want to load for this sprite. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) */ function Sprite(game, x, y, key, frame, bodyType) { if (typeof x === "undefined") { x = 0; } if (typeof y === "undefined") { y = 0; } if (typeof key === "undefined") { key = null; } if (typeof frame === "undefined") { frame = null; } - if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; } + if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; } /** * A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew. */ @@ -3963,7 +4000,6 @@ var Phaser; this.transform = new Phaser.Components.Transform(this); this.animations = new Phaser.Components.AnimationManager(this); this.texture = new Phaser.Components.Texture(this); - this.body = new Phaser.Physics.Body(this, bodyType); this.input = new Phaser.Components.Sprite.Input(this); this.events = new Phaser.Components.Sprite.Events(this); if(key !== null) { @@ -3978,6 +4014,7 @@ var Phaser; this.frame = frame; } } + this.body = new Phaser.Physics.Body(this, bodyType); this.worldView = new Phaser.Rectangle(x, y, this.width, this.height); } Object.defineProperty(Sprite.prototype, "rotation", { @@ -4053,8 +4090,10 @@ var Phaser; * Pre-update is called right before update() on each object in the game loop. */ function () { - this.worldView.x = this.x - (this.game.world.cameras.default.worldView.x * this.transform.scrollFactor.x); - this.worldView.y = this.y - (this.game.world.cameras.default.worldView.y * this.transform.scrollFactor.y); + //this.worldView.x = this.x * this.transform.scrollFactor.x; + //this.worldView.y = this.y * this.transform.scrollFactor.y; + this.worldView.x = this.x - this.transform.origin.x; + this.worldView.y = this.y - this.transform.origin.y; this.worldView.width = this.width; this.worldView.height = this.height; if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) { @@ -4702,8 +4741,6 @@ var Phaser; function () { if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) { this.modified = true; - } else if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { - this.modified = false; } this._i = 0; while(this._i < this.length) { @@ -4711,6 +4748,21 @@ var Phaser; if(this._member != null && this._member.exists && this._member.active) { this._member.preUpdate(); this._member.update(); + } + } + }; + Group.prototype.postUpdate = /** + * Calls update on all members of this Group who have a status of active=true and exists=true + * You can also call Object.postUpdate directly, which will bypass the active/exists check. + */ + function () { + if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { + this.modified = false; + } + this._i = 0; + while(this._i < this.length) { + this._member = this.members[this._i++]; + if(this._member != null && this._member.exists && this._member.active) { this._member.postUpdate(); } } @@ -4846,13 +4898,13 @@ var Phaser; * @param y {number} Y position of the new sprite. * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite * @param [frame] {string|number} 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. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) * @returns {Sprite} The newly created sprite object. */ function (x, y, key, frame, bodyType) { if (typeof key === "undefined") { key = ''; } if (typeof frame === "undefined") { frame = null; } - if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; } + if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; } return this.add(new Phaser.Sprite(this.game, x, y, key, frame, bodyType)); }; Group.prototype.setObjectIDs = /** @@ -7760,8 +7812,6 @@ var Phaser; function () { if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) { this.modified = true; - } else if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { - this.modified = false; } this.fx.preUpdate(); if(this._target !== null) { @@ -7804,6 +7854,29 @@ var Phaser; this.worldView.y = (this.worldBounds.bottom - this.height) + 1; } } + }; + Camera.prototype.postUpdate = /** + * Update focusing and scrolling. + */ + function () { + if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { + this.modified = false; + } + // Make sure we didn't go outside the cameras worldBounds + if(this.worldBounds !== null) { + if(this.worldView.x < this.worldBounds.left) { + this.worldView.x = this.worldBounds.left; + } + if(this.worldView.x > this.worldBounds.right - this.width) { + this.worldView.x = (this.worldBounds.right - this.width) + 1; + } + if(this.worldView.y < this.worldBounds.top) { + this.worldView.y = this.worldBounds.top; + } + if(this.worldView.y > this.worldBounds.bottom - this.height) { + this.worldView.y = (this.worldBounds.bottom - this.height) + 1; + } + } this.fx.postUpdate(); }; Camera.prototype.renderDebugInfo = /** @@ -7817,9 +7890,10 @@ var Phaser; this.game.stage.context.fillStyle = color; this.game.stage.context.fillText('Camera ID: ' + this.ID + ' (' + this.screenView.width + ' x ' + this.screenView.height + ')', x, y); this.game.stage.context.fillText('X: ' + this.screenView.x + ' Y: ' + this.screenView.y + ' rotation: ' + this.transform.rotation, x, y + 14); - this.game.stage.context.fillText('World X: ' + this.worldView.x.toFixed(1) + ' World Y: ' + this.worldView.y.toFixed(1), x, y + 28); + this.game.stage.context.fillText('World X: ' + this.worldView.x + ' World Y: ' + this.worldView.y + ' W: ' + this.worldView.width + ' H: ' + this.worldView.height + ' R: ' + this.worldView.right + ' B: ' + this.worldView.bottom, x, y + 28); + this.game.stage.context.fillText('ScreenView X: ' + this.screenView.x + ' Y: ' + this.screenView.y + ' W: ' + this.screenView.width + ' H: ' + this.screenView.height, x, y + 42); if(this.worldBounds) { - this.game.stage.context.fillText('Bounds: ' + this.worldBounds.width + ' x ' + this.worldBounds.height, x, y + 42); + this.game.stage.context.fillText('Bounds: ' + this.worldBounds.width + ' x ' + this.worldBounds.height, x, y + 56); } }; Camera.prototype.destroy = /** @@ -7959,9 +8033,17 @@ var Phaser; * Update cameras. */ function () { - this._cameras.forEach(function (camera) { - return camera.update(); - }); + for(var i = 0; i < this._cameras.length; i++) { + this._cameras[i].update(); + } + }; + CameraManager.prototype.postUpdate = /** + * postUpdate cameras. + */ + function () { + for(var i = 0; i < this._cameras.length; i++) { + this._cameras[i].postUpdate(); + } }; CameraManager.prototype.addCamera = /** * Create a new camera with specific position and size. @@ -10295,7 +10377,7 @@ var Phaser; function (x, y, key, frame, bodyType) { if (typeof key === "undefined") { key = ''; } if (typeof frame === "undefined") { frame = null; } - if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; } + if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; } return this._world.group.add(new Phaser.Sprite(this._game, x, y, key, frame, bodyType)); }; GameObjectFactory.prototype.dynamicTexture = /** @@ -10967,8 +11049,7 @@ var Phaser; } this._game.stage.canvas.style.width = this.width + 'px'; this._game.stage.canvas.style.height = this.height + 'px'; - this._game.input.scaleX = this._game.stage.width / this.width; - this._game.input.scaleY = this._game.stage.height / this.height; + this._game.input.scale.setTo(this._game.stage.width / this.width, this._game.stage.height / this.height); if(this.pageAlignHorizontally) { if(this.width < window.innerWidth && this.incorrectOrientation == false) { this._game.stage.canvas.style.marginLeft = Math.round((window.innerWidth - this.width) / 2) + 'px'; @@ -12032,12 +12113,14 @@ var Phaser; body.velocity.x += this._velocityDelta; this._delta = body.velocity.x * this.game.time.elapsed; body.velocity.x += this._velocityDelta; - body.position.x += this._delta; + //body.position.x += this._delta; + body.sprite.x += this._delta; this._velocityDelta = (this.computeVelocity(body.velocity.y, body.gravity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2; body.velocity.y += this._velocityDelta; this._delta = body.velocity.y * this.game.time.elapsed; body.velocity.y += this._velocityDelta; - body.position.y += this._delta; + //body.position.y += this._delta; + body.sprite.y += this._delta; }; PhysicsManager.prototype.computeVelocity = /** * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity. @@ -12531,6 +12614,7 @@ var Phaser; this._quadTree = new Phaser.QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height); this._quadTree.load(object1, object2, notifyCallback, processCallback, context); this._quadTreeResult = this._quadTree.execute(); + console.log('over', this._quadTreeResult); this._quadTree.destroy(); this._quadTree = null; return this._quadTreeResult; @@ -12932,6 +13016,14 @@ var Phaser; this.group.update(); this.cameras.update(); }; + World.prototype.postUpdate = /** + * This is called automatically every frame, and is where main logic happens. + */ + function () { + //this.physics.postUpdate(); + this.group.postUpdate(); + this.cameras.postUpdate(); + }; World.prototype.destroy = /** * Clean up memory. */ @@ -14136,13 +14228,13 @@ var Phaser; */ this.screenY = -1; /** - * The horizontal coordinate of point relative to the game element + * The horizontal coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property x * @type {Number} */ this.x = -1; /** - * The vertical coordinate of point relative to the game element + * The vertical coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property y * @type {Number} */ @@ -14220,44 +14312,22 @@ var Phaser; enumerable: true, configurable: true }); - Pointer.prototype.getWorldX = /** - * Gets the X value of this Pointer in world coordinate space (is it properly scaled?) + Pointer.prototype.worldX = /** + * Gets the X value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ function (camera) { - if (typeof camera === "undefined") { camera = this.game.camera; } + if (typeof camera === "undefined") { camera = this.game.input.camera; } return camera.worldView.x + this.x; }; - Pointer.prototype.getWorldY = /** - * Gets the Y value of this Pointer in world coordinate space + Pointer.prototype.worldY = /** + * Gets the Y value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ function (camera) { - if (typeof camera === "undefined") { camera = this.game.camera; } + if (typeof camera === "undefined") { camera = this.game.input.camera; } return camera.worldView.y + this.y; }; - Object.defineProperty(Pointer.prototype, "scaledX", { - get: /** - * Gets the X value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - function () { - return Math.floor(this.x * this.game.input.scaleX); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Pointer.prototype, "scaledY", { - get: /** - * Gets the Y value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - function () { - return Math.floor(this.y * this.game.input.scaleY); - }, - enumerable: true, - configurable: true - }); Pointer.prototype.start = /** * Called when the Pointer is pressed onto the touchscreen * @method start @@ -14281,12 +14351,15 @@ var Phaser; this.isUp = false; this.timeDown = this.game.time.now; this._holdSent = false; + // This sets the x/y and other local values + this.move(event); // x and y are the old values here? this.positionDown.setTo(this.x, this.y); - this.move(event); 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.scaleX; - this.game.input.y = this.y * this.game.input.scaleY; + //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.onDown.dispatch(this); } this._stateReset = false; @@ -14335,14 +14408,15 @@ var Phaser; this.pageY = event.pageY; this.screenX = event.screenX; this.screenY = event.screenY; - this.x = this.pageX - this.game.stage.offset.x; - this.y = this.pageY - this.game.stage.offset.y; + this.x = (this.pageX - this.game.stage.offset.x) * this.game.input.scale.x; + this.y = (this.pageY - this.game.stage.offset.y) * this.game.input.scale.y; this.position.setTo(this.x, this.y); this.circle.x = this.x; this.circle.y = this.y; 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.scaleX; - this.game.input.y = this.y * this.game.input.scaleY; + this.game.input.activePointer = this; + this.game.input.x = this.x; + this.game.input.y = this.y; this.game.input.position.setTo(this.game.input.x, this.game.input.y); this.game.input.circle.x = this.game.input.x; this.game.input.circle.y = this.game.input.y; @@ -15209,6 +15283,18 @@ var Phaser; **/ this._oldPosition = null; /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + this._x = 0; + /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + this._y = 0; + /** * You can disable all Input by setting Input.disabled = true. While set all new input related events will be ignored. * If you need to disable just one type of input, for example mouse, use Input.mouse.disabled = true instead * @type {Boolean} @@ -15239,27 +15325,11 @@ var Phaser; **/ this.circle = null; /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private + * The scale by which all input coordinates are multiplied, calculated by the StageScaleMode. + * In an un-scaled game the values will be x: 1 and y: 1. + * @type {Vec2} */ - this._x = 0; - /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private - */ - this._y = 0; - /** - * - * @type {Number} - */ - this.scaleX = 1; - /** - * - * @type {Number} - */ - this.scaleY = 1; + this.scale = null; /** * The maximum number of Pointers allowed to be active at any one time. * For lots of games it's useful to set this to 1 @@ -15352,6 +15422,13 @@ var Phaser; * @type {Pointer} **/ this.pointer10 = null; + /** + * The most recently active Pointer object. + * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse. + * @property activePointer + * @type {Pointer} + **/ + this.activePointer = null; this.inputObjects = []; this.totalTrackedObjects = 0; this._game = game; @@ -15370,10 +15447,13 @@ var Phaser; this.onUp = new Phaser.Signal(); this.onTap = new Phaser.Signal(); this.onHold = new Phaser.Signal(); + this.scale = new Phaser.Vec2(1, 1); this.speed = new Phaser.Vec2(); this.position = new Phaser.Vec2(); this._oldPosition = new Phaser.Vec2(); this.circle = new Phaser.Circle(0, 0, 44); + this.camera = this._game.camera; + this.activePointer = this.mousePointer; this.currentPointers = 0; } Input.MOUSE_OVERRIDES_TOUCH = 0; @@ -15381,7 +15461,8 @@ var Phaser; Input.MOUSE_TOUCH_COMBINE = 2; Object.defineProperty(Input.prototype, "x", { get: /** - * The screen X coordinate + * The X coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values. * @property x * @type {Number} **/ @@ -15396,7 +15477,8 @@ var Phaser; }); Object.defineProperty(Input.prototype, "y", { get: /** - * The screen Y coordinate + * The Y coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenY/clientY for source values. * @property y * @type {Number} **/ @@ -15467,7 +15549,6 @@ var Phaser; * @method update **/ function () { - // Swap for velocity vector - and add it to Pointer? this.speed.x = this.position.x - this._oldPosition.x; this.speed.y = this.position.y - this._oldPosition.y; this._oldPosition.copyFrom(this.position); @@ -15766,12 +15847,12 @@ var Phaser; */ function (x, y, color) { if (typeof color === "undefined") { color = 'rgb(255,255,255)'; } - this._game.stage.context.font = '14px Courier'; this._game.stage.context.fillStyle = color; this._game.stage.context.fillText('Input', x, y); - this._game.stage.context.fillText('Screen X: ' + this.x + ' Screen Y: ' + this.y, x, y + 14); + this._game.stage.context.fillText('X: ' + this.x + ' Y: ' + this.y, x, y + 14); this._game.stage.context.fillText('World X: ' + this.getWorldX() + ' World Y: ' + this.getWorldY(), x, y + 28); - this._game.stage.context.fillText('Scale X: ' + this.scaleX.toFixed(1) + ' Scale Y: ' + this.scaleY.toFixed(1), x, y + 42); + this._game.stage.context.fillText('Scale X: ' + this.scale.x.toFixed(1) + ' Scale Y: ' + this.scale.x.toFixed(1), x, y + 42); + this._game.stage.context.fillText('Screen X: ' + this.activePointer.screenX + ' Screen Y: ' + this.activePointer.screenY, x, y + 56); }; Input.prototype.getDistance = /** * Get the distance between two Pointer objects @@ -15806,6 +15887,9 @@ var Phaser; } HeadlessRenderer.prototype.render = function () { }; + HeadlessRenderer.prototype.inCamera = function (camera, sprite) { + return true; + }; HeadlessRenderer.prototype.renderGameObject = function (object) { }; HeadlessRenderer.prototype.renderSprite = function (camera, sprite) { @@ -15981,24 +16065,12 @@ var Phaser; * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. */ function (camera, sprite) { - return true; - /* - // Object fixed in place regardless of the camera scrolling? Then it's always visible - if (sprite.scrollFactor.x == 0 && sprite.scrollFactor.y == 0) - { - return true; + if(sprite.transform.scrollFactor.equals(0)) { + return true; } - - this._dx = sprite.frameBounds.x - (camera.worldView.x * sprite.scrollFactor.x); - this._dy = sprite.frameBounds.y - (camera.worldView.y * sprite.scrollFactor.y); - this._dw = sprite.frameBounds.width * sprite.scale.x; - this._dh = sprite.frameBounds.height * sprite.scale.y; - - //return (camera.screenView.x + camera.worldView.width > this._dx) && (camera.screenView.x < this._dx + this._dw) && (camera.screenView.y + camera.worldView.height > this._dy) && (camera.screenView.y < this._dy + this._dh); - - */ - }; + return Phaser.RectangleUtils.intersects(sprite.worldView, camera.worldView); + }; CanvasRenderer.prototype.inScreen = function (camera) { return true; }; @@ -16372,11 +16444,37 @@ var Phaser; function renderSpriteInfo(sprite, x, y, color) { if (typeof color === "undefined") { color = 'rgb(255,255,255)'; } DebugUtils.game.stage.context.fillStyle = color; - DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ')', x, y); + DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y); DebugUtils.game.stage.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14); - //DebugUtils.game.stage.context.fillText('dx: ' + this._dx.toFixed(1) + ' dy: ' + this._dy.toFixed(1) + ' dw: ' + this._dw.toFixed(1) + ' dh: ' + this._dh.toFixed(1), x, y + 28); - //DebugUtils.game.stage.context.fillText('sx: ' + this._sx.toFixed(1) + ' sy: ' + this._sy.toFixed(1) + ' sw: ' + this._sw.toFixed(1) + ' sh: ' + this._sh.toFixed(1), x, y + 42); - }; + DebugUtils.game.stage.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28); + DebugUtils.game.stage.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42); + DebugUtils.game.stage.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56); + DebugUtils.game.stage.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 70); + }; + DebugUtils.renderSpriteBounds = function renderSpriteBounds(sprite, camera, color) { + if (typeof camera === "undefined") { camera = null; } + if (typeof color === "undefined") { color = 'rgba(0,255,0,0.2)'; } + if(camera == null) { + camera = DebugUtils.game.camera; + } + //var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + //var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + var dx = sprite.worldView.x; + var dy = sprite.worldView.y; + DebugUtils.game.stage.context.fillStyle = color; + DebugUtils.game.stage.context.fillRect(dx, dy, sprite.width, sprite.height); + }; + DebugUtils.renderSpritePhysicsBody = function renderSpritePhysicsBody(sprite, camera, color) { + if (typeof camera === "undefined") { camera = null; } + if (typeof color === "undefined") { color = 'rgba(255,0,0,0.2)'; } + if(camera == null) { + camera = DebugUtils.game.camera; + } + var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.body.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.body.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + DebugUtils.game.stage.context.fillStyle = color; + DebugUtils.game.stage.context.fillRect(dx, dy, sprite.body.width, sprite.body.height); + }; return DebugUtils; })(); Phaser.DebugUtils = DebugUtils; @@ -16651,6 +16749,7 @@ var Phaser; if(this._loadComplete && this.onUpdateCallback) { this.onUpdateCallback.call(this.callbackContext); } + this.world.postUpdate(); this.renderer.render(); if(this._loadComplete && this.onRenderCallback) { this.onRenderCallback.call(this.callbackContext); diff --git a/Tests/physics/aabb 1.js b/Tests/physics/aabb 1.js index d8fd9fbd..a1d610f0 100644 --- a/Tests/physics/aabb 1.js +++ b/Tests/physics/aabb 1.js @@ -33,5 +33,6 @@ } function render() { atari.body.renderDebugInfo(16, 16); + Phaser.DebugUtils.renderSpritePhysicsBody(atari); } })(); diff --git a/Tests/physics/aabb 1.ts b/Tests/physics/aabb 1.ts index 0295c21f..df5ac64b 100644 --- a/Tests/physics/aabb 1.ts +++ b/Tests/physics/aabb 1.ts @@ -57,6 +57,7 @@ function render() { atari.body.renderDebugInfo(16, 16); + Phaser.DebugUtils.renderSpritePhysicsBody(atari); } diff --git a/Tests/physics/aabb vs aabb 1.js b/Tests/physics/aabb vs aabb 1.js index 01407402..71a16648 100644 --- a/Tests/physics/aabb vs aabb 1.js +++ b/Tests/physics/aabb vs aabb 1.js @@ -39,9 +39,12 @@ atari.body.acceleration.y = 150; } // collide? - } + game.collide(atari, card); + } function render() { atari.body.renderDebugInfo(16, 16); card.body.renderDebugInfo(200, 16); + Phaser.DebugUtils.renderSpritePhysicsBody(atari); + Phaser.DebugUtils.renderSpritePhysicsBody(card); } })(); diff --git a/Tests/physics/aabb vs aabb 1.ts b/Tests/physics/aabb vs aabb 1.ts index 25e16c23..bbaf3f5e 100644 --- a/Tests/physics/aabb vs aabb 1.ts +++ b/Tests/physics/aabb vs aabb 1.ts @@ -64,6 +64,7 @@ } // collide? + game.collide(atari, card); } @@ -72,6 +73,9 @@ atari.body.renderDebugInfo(16, 16); card.body.renderDebugInfo(200, 16); + Phaser.DebugUtils.renderSpritePhysicsBody(atari); + Phaser.DebugUtils.renderSpritePhysicsBody(card); + } })(); diff --git a/build/phaser.d.ts b/build/phaser.d.ts index 797452bf..379a1323 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -2344,7 +2344,7 @@ module Phaser.Physics { */ public game: Game; /** - * Reference to the sprite Sprite + * Reference to the parent Sprite */ public sprite: Sprite; /** @@ -2379,6 +2379,12 @@ module Phaser.Physics { public oldPosition: Vec2; public offset: Vec2; public bounds: Rectangle; + private _width; + private _height; + public x : number; + public y : number; + public width : number; + public height : number; public preUpdate(): void; public postUpdate(): void; public hullWidth : number; @@ -2411,7 +2417,7 @@ module Phaser { * @param [x] {number} the initial x position of the sprite. * @param [y] {number} the initial y position of the sprite. * @param [key] {string} Key of the graphic you want to load for this sprite. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) */ constructor(game: Game, x?: number, y?: number, key?: string, frame?, bodyType?: number); /** @@ -2865,6 +2871,11 @@ module Phaser { */ public update(): void; /** + * Calls update on all members of this Group who have a status of active=true and exists=true + * You can also call Object.postUpdate directly, which will bypass the active/exists check. + */ + public postUpdate(): void; + /** * Calls render on all members of this Group who have a status of visible=true and exists=true * You can also call Object.render directly, which will bypass the visible/exists check. */ @@ -2901,7 +2912,7 @@ module Phaser { * @param y {number} Y position of the new sprite. * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite * @param [frame] {string|number} 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. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) * @returns {Sprite} The newly created sprite object. */ public addNewSprite(x: number, y: number, key?: string, frame?, bodyType?: number): Sprite; @@ -4490,6 +4501,10 @@ module Phaser { */ public update(): void; /** + * Update focusing and scrolling. + */ + public postUpdate(): void; + /** * Render debug infos. (including id, position, rotation, scrolling factor, worldBounds and some other properties) * @param x {number} X position of the debug info to be rendered. * @param y {number} Y position of the debug info to be rendered. @@ -4576,6 +4591,10 @@ module Phaser { */ public update(): void; /** + * postUpdate cameras. + */ + public postUpdate(): void; + /** * Create a new camera with specific position and size. * * @param x {number} X position of the new camera. @@ -6989,6 +7008,10 @@ module Phaser { */ public update(): void; /** + * This is called automatically every frame, and is where main logic happens. + */ + public postUpdate(): void; + /** * Clean up memory. */ public destroy(): void; @@ -7618,13 +7641,13 @@ module Phaser { */ public screenY: number; /** - * The horizontal coordinate of point relative to the game element + * The horizontal coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property x * @type {Number} */ public x: number; /** - * The vertical coordinate of point relative to the game element + * The vertical coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property y * @type {Number} */ @@ -7690,25 +7713,15 @@ module Phaser { **/ public targetObject; /** - * Gets the X value of this Pointer in world coordinate space (is it properly scaled?) + * Gets the X value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ - public getWorldX(camera?: Camera): number; + public worldX(camera?: Camera): number; /** - * Gets the Y value of this Pointer in world coordinate space + * Gets the Y value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ - public getWorldY(camera?: Camera): number; - /** - * Gets the X value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - public scaledX : number; - /** - * Gets the Y value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - public scaledY : number; + public worldY(camera?: Camera): number; /** * Called when the Pointer is pressed onto the touchscreen * @method start @@ -8187,6 +8200,18 @@ module Phaser { **/ private _oldPosition; /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + private _x; + /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + private _y; + /** * You can disable all Input by setting Input.disabled = true. While set all new input related events will be ignored. * If you need to disable just one type of input, for example mouse, use Input.mouse.disabled = true instead * @type {Boolean} @@ -8212,6 +8237,12 @@ module Phaser { */ static MOUSE_TOUCH_COMBINE: number; /** + * The camera being used for mouse and touch based pointers to calculate their world coordinates. + * @property camera + * @type {Camera} + **/ + public camera: Camera; + /** * Phaser.Mouse handler * @type {Mouse} */ @@ -8257,27 +8288,11 @@ module Phaser { **/ public circle: Circle; /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private + * The scale by which all input coordinates are multiplied, calculated by the StageScaleMode. + * In an un-scaled game the values will be x: 1 and y: 1. + * @type {Vec2} */ - private _x; - /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private - */ - private _y; - /** - * - * @type {Number} - */ - public scaleX: number; - /** - * - * @type {Number} - */ - public scaleY: number; + public scale: Vec2; /** * The maximum number of Pointers allowed to be active at any one time. * For lots of games it's useful to set this to 1 @@ -8428,13 +8443,22 @@ module Phaser { **/ public pointer10: Pointer; /** - * The screen X coordinate + * The most recently active Pointer object. + * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse. + * @property activePointer + * @type {Pointer} + **/ + public activePointer: Pointer; + /** + * The X coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values. * @property x * @type {Number} **/ public x : number; /** - * The screen Y coordinate + * The Y coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenY/clientY for source values. * @property y * @type {Number} **/ @@ -8554,16 +8578,15 @@ module Phaser { postRenderGroup(camera: Camera, group: Group); preRenderCamera(camera: Camera); postRenderCamera(camera: Camera); + inCamera(camera: Camera, sprite: Sprite): bool; } } module Phaser { class HeadlessRenderer implements IRenderer { constructor(game: Game); - /** - * The essential reference to the main game object - */ private _game; public render(): void; + public inCamera(camera: Camera, sprite: Sprite): bool; public renderGameObject(object): void; public renderSprite(camera: Camera, sprite: Sprite): bool; public renderScrollZone(camera: Camera, scrollZone: ScrollZone): bool; @@ -8642,6 +8665,8 @@ module Phaser { * @param [color] {number} color of the debug info to be rendered. (format is css color string) */ static renderSpriteInfo(sprite: Sprite, x: number, y: number, color?: string): void; + static renderSpriteBounds(sprite: Sprite, camera?: Camera, color?: string): void; + static renderSpritePhysicsBody(sprite: Sprite, camera?: Camera, color?: string): void; } } /** diff --git a/build/phaser.js b/build/phaser.js index 4839d5cb..a07d9581 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -3051,7 +3051,7 @@ var Phaser; if(this.enabled == false || this.sprite.visible == false) { return false; } else { - return Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.scaledX, pointer.scaledY); + return Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY()); } }; Input.prototype.update = /** @@ -3064,9 +3064,9 @@ var Phaser; if(this.draggable && this._draggedPointerID == pointer.id) { return this.updateDrag(pointer); } else if(this._pointerData[pointer.id].isOver == true) { - if(Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.scaledX, pointer.scaledY)) { - this._pointerData[pointer.id].x = pointer.scaledX - this.sprite.x; - this._pointerData[pointer.id].y = pointer.scaledY - this.sprite.y; + if(Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY())) { + this._pointerData[pointer.id].x = pointer.x - this.sprite.x; + this._pointerData[pointer.id].y = pointer.y - this.sprite.y; return true; } else { this._pointerOutHandler(pointer); @@ -3721,15 +3721,19 @@ var Phaser; this.angularDrag = 0; this.maxAngular = 10000; this.mass = 1; + this._width = 0; + this._height = 0; this.sprite = sprite; this.game = sprite.game; this.type = type; // Fixture properties // Will extend into its own class at a later date - can move the fixture defs there and add shape support, but this will do for 1.0 release - this.bounds = new Phaser.Rectangle(sprite.x + Math.round(sprite.width / 2), sprite.y + Math.round(sprite.height / 2), sprite.width, sprite.height); - this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce); + this.bounds = new Phaser.Rectangle(); + this._width = sprite.width; + this._height = sprite.height; // Body properties this.gravity = Phaser.Vec2Utils.clone(this.game.world.physics.gravity); + this.bounce = Phaser.Vec2Utils.clone(this.game.world.physics.bounce); this.velocity = new Phaser.Vec2(); this.acceleration = new Phaser.Vec2(); this.drag = Phaser.Vec2Utils.clone(this.game.world.physics.drag); @@ -3744,12 +3748,46 @@ var Phaser; this.oldPosition = new Phaser.Vec2(sprite.x + this.bounds.halfWidth, sprite.y + this.bounds.halfHeight); this.offset = new Phaser.Vec2(); } + Object.defineProperty(Body.prototype, "x", { + get: function () { + return this.sprite.x + this.offset.x; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Body.prototype, "y", { + get: function () { + return this.sprite.y + this.offset.y; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Body.prototype, "width", { + get: function () { + return this._width * this.sprite.transform.scale.x; + }, + set: function (value) { + this._width = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Body.prototype, "height", { + get: function () { + return this._height * this.sprite.transform.scale.y; + }, + set: function (value) { + this._height = value; + }, + enumerable: true, + configurable: true + }); Body.prototype.preUpdate = function () { this.oldPosition.copyFrom(this.position); - this.bounds.x = this.position.x - this.bounds.halfWidth; - this.bounds.y = this.position.y - this.bounds.halfHeight; - if(this.sprite.transform.scale.equals(1) == false) { - } + this.bounds.x = this.x; + this.bounds.y = this.y; + this.bounds.width = this.width; + this.bounds.height = this.height; }; Body.prototype.postUpdate = // Shall we do this? Or just update the values directly in the separate functions? But then the bounds will be out of sync - as long as // the bounds are updated and used in calculations then we can do one final sprite movement here I guess? @@ -3757,11 +3795,10 @@ var Phaser; // if this is all it does maybe move elsewhere? Sprite postUpdate? if(this.type !== Phaser.Types.BODY_DISABLED) { this.game.world.physics.updateMotion(this); - this.sprite.x = (this.position.x - this.bounds.halfWidth) - this.offset.x; - this.sprite.y = (this.position.y - this.bounds.halfHeight) - this.offset.y; this.wasTouching = this.touching; this.touching = Phaser.Types.NONE; } + this.position.setTo(this.x, this.y); }; Object.defineProperty(Body.prototype, "hullWidth", { get: function () { @@ -3922,14 +3959,14 @@ var Phaser; * @param [x] {number} the initial x position of the sprite. * @param [y] {number} the initial y position of the sprite. * @param [key] {string} Key of the graphic you want to load for this sprite. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) */ function Sprite(game, x, y, key, frame, bodyType) { if (typeof x === "undefined") { x = 0; } if (typeof y === "undefined") { y = 0; } if (typeof key === "undefined") { key = null; } if (typeof frame === "undefined") { frame = null; } - if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; } + if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; } /** * A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew. */ @@ -3963,7 +4000,6 @@ var Phaser; this.transform = new Phaser.Components.Transform(this); this.animations = new Phaser.Components.AnimationManager(this); this.texture = new Phaser.Components.Texture(this); - this.body = new Phaser.Physics.Body(this, bodyType); this.input = new Phaser.Components.Sprite.Input(this); this.events = new Phaser.Components.Sprite.Events(this); if(key !== null) { @@ -3978,6 +4014,7 @@ var Phaser; this.frame = frame; } } + this.body = new Phaser.Physics.Body(this, bodyType); this.worldView = new Phaser.Rectangle(x, y, this.width, this.height); } Object.defineProperty(Sprite.prototype, "rotation", { @@ -4053,8 +4090,10 @@ var Phaser; * Pre-update is called right before update() on each object in the game loop. */ function () { - this.worldView.x = this.x - (this.game.world.cameras.default.worldView.x * this.transform.scrollFactor.x); - this.worldView.y = this.y - (this.game.world.cameras.default.worldView.y * this.transform.scrollFactor.y); + //this.worldView.x = this.x * this.transform.scrollFactor.x; + //this.worldView.y = this.y * this.transform.scrollFactor.y; + this.worldView.x = this.x - this.transform.origin.x; + this.worldView.y = this.y - this.transform.origin.y; this.worldView.width = this.width; this.worldView.height = this.height; if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) { @@ -4702,8 +4741,6 @@ var Phaser; function () { if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) { this.modified = true; - } else if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { - this.modified = false; } this._i = 0; while(this._i < this.length) { @@ -4711,6 +4748,21 @@ var Phaser; if(this._member != null && this._member.exists && this._member.active) { this._member.preUpdate(); this._member.update(); + } + } + }; + Group.prototype.postUpdate = /** + * Calls update on all members of this Group who have a status of active=true and exists=true + * You can also call Object.postUpdate directly, which will bypass the active/exists check. + */ + function () { + if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { + this.modified = false; + } + this._i = 0; + while(this._i < this.length) { + this._member = this.members[this._i++]; + if(this._member != null && this._member.exists && this._member.active) { this._member.postUpdate(); } } @@ -4846,13 +4898,13 @@ var Phaser; * @param y {number} Y position of the new sprite. * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite * @param [frame] {string|number} 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. - * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DISABLED) + * @param [bodyType] {number} The physics body type of the object (defaults to BODY_DYNAMIC) * @returns {Sprite} The newly created sprite object. */ function (x, y, key, frame, bodyType) { if (typeof key === "undefined") { key = ''; } if (typeof frame === "undefined") { frame = null; } - if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; } + if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; } return this.add(new Phaser.Sprite(this.game, x, y, key, frame, bodyType)); }; Group.prototype.setObjectIDs = /** @@ -7760,8 +7812,6 @@ var Phaser; function () { if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) { this.modified = true; - } else if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { - this.modified = false; } this.fx.preUpdate(); if(this._target !== null) { @@ -7804,6 +7854,29 @@ var Phaser; this.worldView.y = (this.worldBounds.bottom - this.height) + 1; } } + }; + Camera.prototype.postUpdate = /** + * Update focusing and scrolling. + */ + function () { + if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) { + this.modified = false; + } + // Make sure we didn't go outside the cameras worldBounds + if(this.worldBounds !== null) { + if(this.worldView.x < this.worldBounds.left) { + this.worldView.x = this.worldBounds.left; + } + if(this.worldView.x > this.worldBounds.right - this.width) { + this.worldView.x = (this.worldBounds.right - this.width) + 1; + } + if(this.worldView.y < this.worldBounds.top) { + this.worldView.y = this.worldBounds.top; + } + if(this.worldView.y > this.worldBounds.bottom - this.height) { + this.worldView.y = (this.worldBounds.bottom - this.height) + 1; + } + } this.fx.postUpdate(); }; Camera.prototype.renderDebugInfo = /** @@ -7817,9 +7890,10 @@ var Phaser; this.game.stage.context.fillStyle = color; this.game.stage.context.fillText('Camera ID: ' + this.ID + ' (' + this.screenView.width + ' x ' + this.screenView.height + ')', x, y); this.game.stage.context.fillText('X: ' + this.screenView.x + ' Y: ' + this.screenView.y + ' rotation: ' + this.transform.rotation, x, y + 14); - this.game.stage.context.fillText('World X: ' + this.worldView.x.toFixed(1) + ' World Y: ' + this.worldView.y.toFixed(1), x, y + 28); + this.game.stage.context.fillText('World X: ' + this.worldView.x + ' World Y: ' + this.worldView.y + ' W: ' + this.worldView.width + ' H: ' + this.worldView.height + ' R: ' + this.worldView.right + ' B: ' + this.worldView.bottom, x, y + 28); + this.game.stage.context.fillText('ScreenView X: ' + this.screenView.x + ' Y: ' + this.screenView.y + ' W: ' + this.screenView.width + ' H: ' + this.screenView.height, x, y + 42); if(this.worldBounds) { - this.game.stage.context.fillText('Bounds: ' + this.worldBounds.width + ' x ' + this.worldBounds.height, x, y + 42); + this.game.stage.context.fillText('Bounds: ' + this.worldBounds.width + ' x ' + this.worldBounds.height, x, y + 56); } }; Camera.prototype.destroy = /** @@ -7959,9 +8033,17 @@ var Phaser; * Update cameras. */ function () { - this._cameras.forEach(function (camera) { - return camera.update(); - }); + for(var i = 0; i < this._cameras.length; i++) { + this._cameras[i].update(); + } + }; + CameraManager.prototype.postUpdate = /** + * postUpdate cameras. + */ + function () { + for(var i = 0; i < this._cameras.length; i++) { + this._cameras[i].postUpdate(); + } }; CameraManager.prototype.addCamera = /** * Create a new camera with specific position and size. @@ -10295,7 +10377,7 @@ var Phaser; function (x, y, key, frame, bodyType) { if (typeof key === "undefined") { key = ''; } if (typeof frame === "undefined") { frame = null; } - if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DISABLED; } + if (typeof bodyType === "undefined") { bodyType = Phaser.Types.BODY_DYNAMIC; } return this._world.group.add(new Phaser.Sprite(this._game, x, y, key, frame, bodyType)); }; GameObjectFactory.prototype.dynamicTexture = /** @@ -10967,8 +11049,7 @@ var Phaser; } this._game.stage.canvas.style.width = this.width + 'px'; this._game.stage.canvas.style.height = this.height + 'px'; - this._game.input.scaleX = this._game.stage.width / this.width; - this._game.input.scaleY = this._game.stage.height / this.height; + this._game.input.scale.setTo(this._game.stage.width / this.width, this._game.stage.height / this.height); if(this.pageAlignHorizontally) { if(this.width < window.innerWidth && this.incorrectOrientation == false) { this._game.stage.canvas.style.marginLeft = Math.round((window.innerWidth - this.width) / 2) + 'px'; @@ -12032,12 +12113,14 @@ var Phaser; body.velocity.x += this._velocityDelta; this._delta = body.velocity.x * this.game.time.elapsed; body.velocity.x += this._velocityDelta; - body.position.x += this._delta; + //body.position.x += this._delta; + body.sprite.x += this._delta; this._velocityDelta = (this.computeVelocity(body.velocity.y, body.gravity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2; body.velocity.y += this._velocityDelta; this._delta = body.velocity.y * this.game.time.elapsed; body.velocity.y += this._velocityDelta; - body.position.y += this._delta; + //body.position.y += this._delta; + body.sprite.y += this._delta; }; PhysicsManager.prototype.computeVelocity = /** * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity. @@ -12531,6 +12614,7 @@ var Phaser; this._quadTree = new Phaser.QuadTree(this, this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height); this._quadTree.load(object1, object2, notifyCallback, processCallback, context); this._quadTreeResult = this._quadTree.execute(); + console.log('over', this._quadTreeResult); this._quadTree.destroy(); this._quadTree = null; return this._quadTreeResult; @@ -12932,6 +13016,14 @@ var Phaser; this.group.update(); this.cameras.update(); }; + World.prototype.postUpdate = /** + * This is called automatically every frame, and is where main logic happens. + */ + function () { + //this.physics.postUpdate(); + this.group.postUpdate(); + this.cameras.postUpdate(); + }; World.prototype.destroy = /** * Clean up memory. */ @@ -14136,13 +14228,13 @@ var Phaser; */ this.screenY = -1; /** - * The horizontal coordinate of point relative to the game element + * The horizontal coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property x * @type {Number} */ this.x = -1; /** - * The vertical coordinate of point relative to the game element + * The vertical coordinate of point relative to the game element. This value is automatically scaled based on game size. * @property y * @type {Number} */ @@ -14220,44 +14312,22 @@ var Phaser; enumerable: true, configurable: true }); - Pointer.prototype.getWorldX = /** - * Gets the X value of this Pointer in world coordinate space (is it properly scaled?) + Pointer.prototype.worldX = /** + * Gets the X value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ function (camera) { - if (typeof camera === "undefined") { camera = this.game.camera; } + if (typeof camera === "undefined") { camera = this.game.input.camera; } return camera.worldView.x + this.x; }; - Pointer.prototype.getWorldY = /** - * Gets the Y value of this Pointer in world coordinate space + Pointer.prototype.worldY = /** + * Gets the Y value of this Pointer in world coordinates based on the given camera. * @param {Camera} [camera] */ function (camera) { - if (typeof camera === "undefined") { camera = this.game.camera; } + if (typeof camera === "undefined") { camera = this.game.input.camera; } return camera.worldView.y + this.y; }; - Object.defineProperty(Pointer.prototype, "scaledX", { - get: /** - * Gets the X value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - function () { - return Math.floor(this.x * this.game.input.scaleX); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Pointer.prototype, "scaledY", { - get: /** - * Gets the Y value of this Pointer in world coordinate space - * @param {Camera} [camera] - */ - function () { - return Math.floor(this.y * this.game.input.scaleY); - }, - enumerable: true, - configurable: true - }); Pointer.prototype.start = /** * Called when the Pointer is pressed onto the touchscreen * @method start @@ -14281,12 +14351,15 @@ var Phaser; this.isUp = false; this.timeDown = this.game.time.now; this._holdSent = false; + // This sets the x/y and other local values + this.move(event); // x and y are the old values here? this.positionDown.setTo(this.x, this.y); - this.move(event); 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.scaleX; - this.game.input.y = this.y * this.game.input.scaleY; + //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.onDown.dispatch(this); } this._stateReset = false; @@ -14335,14 +14408,15 @@ var Phaser; this.pageY = event.pageY; this.screenX = event.screenX; this.screenY = event.screenY; - this.x = this.pageX - this.game.stage.offset.x; - this.y = this.pageY - this.game.stage.offset.y; + this.x = (this.pageX - this.game.stage.offset.x) * this.game.input.scale.x; + this.y = (this.pageY - this.game.stage.offset.y) * this.game.input.scale.y; this.position.setTo(this.x, this.y); this.circle.x = this.x; this.circle.y = this.y; 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.scaleX; - this.game.input.y = this.y * this.game.input.scaleY; + this.game.input.activePointer = this; + this.game.input.x = this.x; + this.game.input.y = this.y; this.game.input.position.setTo(this.game.input.x, this.game.input.y); this.game.input.circle.x = this.game.input.x; this.game.input.circle.y = this.game.input.y; @@ -15209,6 +15283,18 @@ var Phaser; **/ this._oldPosition = null; /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + this._x = 0; + /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + this._y = 0; + /** * You can disable all Input by setting Input.disabled = true. While set all new input related events will be ignored. * If you need to disable just one type of input, for example mouse, use Input.mouse.disabled = true instead * @type {Boolean} @@ -15239,27 +15325,11 @@ var Phaser; **/ this.circle = null; /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private + * The scale by which all input coordinates are multiplied, calculated by the StageScaleMode. + * In an un-scaled game the values will be x: 1 and y: 1. + * @type {Vec2} */ - this._x = 0; - /** - * X coordinate of the most recent Pointer event - * @type {Number} - * @private - */ - this._y = 0; - /** - * - * @type {Number} - */ - this.scaleX = 1; - /** - * - * @type {Number} - */ - this.scaleY = 1; + this.scale = null; /** * The maximum number of Pointers allowed to be active at any one time. * For lots of games it's useful to set this to 1 @@ -15352,6 +15422,13 @@ var Phaser; * @type {Pointer} **/ this.pointer10 = null; + /** + * The most recently active Pointer object. + * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse. + * @property activePointer + * @type {Pointer} + **/ + this.activePointer = null; this.inputObjects = []; this.totalTrackedObjects = 0; this._game = game; @@ -15370,10 +15447,13 @@ var Phaser; this.onUp = new Phaser.Signal(); this.onTap = new Phaser.Signal(); this.onHold = new Phaser.Signal(); + this.scale = new Phaser.Vec2(1, 1); this.speed = new Phaser.Vec2(); this.position = new Phaser.Vec2(); this._oldPosition = new Phaser.Vec2(); this.circle = new Phaser.Circle(0, 0, 44); + this.camera = this._game.camera; + this.activePointer = this.mousePointer; this.currentPointers = 0; } Input.MOUSE_OVERRIDES_TOUCH = 0; @@ -15381,7 +15461,8 @@ var Phaser; Input.MOUSE_TOUCH_COMBINE = 2; Object.defineProperty(Input.prototype, "x", { get: /** - * The screen X coordinate + * The X coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values. * @property x * @type {Number} **/ @@ -15396,7 +15477,8 @@ var Phaser; }); Object.defineProperty(Input.prototype, "y", { get: /** - * The screen Y coordinate + * The Y coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenY/clientY for source values. * @property y * @type {Number} **/ @@ -15467,7 +15549,6 @@ var Phaser; * @method update **/ function () { - // Swap for velocity vector - and add it to Pointer? this.speed.x = this.position.x - this._oldPosition.x; this.speed.y = this.position.y - this._oldPosition.y; this._oldPosition.copyFrom(this.position); @@ -15766,12 +15847,12 @@ var Phaser; */ function (x, y, color) { if (typeof color === "undefined") { color = 'rgb(255,255,255)'; } - this._game.stage.context.font = '14px Courier'; this._game.stage.context.fillStyle = color; this._game.stage.context.fillText('Input', x, y); - this._game.stage.context.fillText('Screen X: ' + this.x + ' Screen Y: ' + this.y, x, y + 14); + this._game.stage.context.fillText('X: ' + this.x + ' Y: ' + this.y, x, y + 14); this._game.stage.context.fillText('World X: ' + this.getWorldX() + ' World Y: ' + this.getWorldY(), x, y + 28); - this._game.stage.context.fillText('Scale X: ' + this.scaleX.toFixed(1) + ' Scale Y: ' + this.scaleY.toFixed(1), x, y + 42); + this._game.stage.context.fillText('Scale X: ' + this.scale.x.toFixed(1) + ' Scale Y: ' + this.scale.x.toFixed(1), x, y + 42); + this._game.stage.context.fillText('Screen X: ' + this.activePointer.screenX + ' Screen Y: ' + this.activePointer.screenY, x, y + 56); }; Input.prototype.getDistance = /** * Get the distance between two Pointer objects @@ -15806,6 +15887,9 @@ var Phaser; } HeadlessRenderer.prototype.render = function () { }; + HeadlessRenderer.prototype.inCamera = function (camera, sprite) { + return true; + }; HeadlessRenderer.prototype.renderGameObject = function (object) { }; HeadlessRenderer.prototype.renderSprite = function (camera, sprite) { @@ -15981,24 +16065,12 @@ var Phaser; * @return {boolean} Return true if bounds of this sprite intersects the given Rectangle, otherwise return false. */ function (camera, sprite) { - return true; - /* - // Object fixed in place regardless of the camera scrolling? Then it's always visible - if (sprite.scrollFactor.x == 0 && sprite.scrollFactor.y == 0) - { - return true; + if(sprite.transform.scrollFactor.equals(0)) { + return true; } - - this._dx = sprite.frameBounds.x - (camera.worldView.x * sprite.scrollFactor.x); - this._dy = sprite.frameBounds.y - (camera.worldView.y * sprite.scrollFactor.y); - this._dw = sprite.frameBounds.width * sprite.scale.x; - this._dh = sprite.frameBounds.height * sprite.scale.y; - - //return (camera.screenView.x + camera.worldView.width > this._dx) && (camera.screenView.x < this._dx + this._dw) && (camera.screenView.y + camera.worldView.height > this._dy) && (camera.screenView.y < this._dy + this._dh); - - */ - }; + return Phaser.RectangleUtils.intersects(sprite.worldView, camera.worldView); + }; CanvasRenderer.prototype.inScreen = function (camera) { return true; }; @@ -16372,11 +16444,37 @@ var Phaser; function renderSpriteInfo(sprite, x, y, color) { if (typeof color === "undefined") { color = 'rgb(255,255,255)'; } DebugUtils.game.stage.context.fillStyle = color; - DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ')', x, y); + DebugUtils.game.stage.context.fillText('Sprite: ' + ' (' + sprite.width + ' x ' + sprite.height + ') origin: ' + sprite.transform.origin.x + ' x ' + sprite.transform.origin.y, x, y); DebugUtils.game.stage.context.fillText('x: ' + sprite.x.toFixed(1) + ' y: ' + sprite.y.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1), x, y + 14); - //DebugUtils.game.stage.context.fillText('dx: ' + this._dx.toFixed(1) + ' dy: ' + this._dy.toFixed(1) + ' dw: ' + this._dw.toFixed(1) + ' dh: ' + this._dh.toFixed(1), x, y + 28); - //DebugUtils.game.stage.context.fillText('sx: ' + this._sx.toFixed(1) + ' sy: ' + this._sy.toFixed(1) + ' sw: ' + this._sw.toFixed(1) + ' sh: ' + this._sh.toFixed(1), x, y + 42); - }; + DebugUtils.game.stage.context.fillText('wx: ' + sprite.worldView.x + ' wy: ' + sprite.worldView.y + ' ww: ' + sprite.worldView.width.toFixed(1) + ' wh: ' + sprite.worldView.height.toFixed(1) + ' wb: ' + sprite.worldView.bottom + ' wr: ' + sprite.worldView.right, x, y + 28); + DebugUtils.game.stage.context.fillText('sx: ' + sprite.transform.scale.x.toFixed(1) + ' sy: ' + sprite.transform.scale.y.toFixed(1), x, y + 42); + DebugUtils.game.stage.context.fillText('tx: ' + sprite.texture.width.toFixed(1) + ' ty: ' + sprite.texture.height.toFixed(1), x, y + 56); + DebugUtils.game.stage.context.fillText('inCamera: ' + DebugUtils.game.renderer.inCamera(DebugUtils.game.camera, sprite), x, y + 70); + }; + DebugUtils.renderSpriteBounds = function renderSpriteBounds(sprite, camera, color) { + if (typeof camera === "undefined") { camera = null; } + if (typeof color === "undefined") { color = 'rgba(0,255,0,0.2)'; } + if(camera == null) { + camera = DebugUtils.game.camera; + } + //var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + //var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + var dx = sprite.worldView.x; + var dy = sprite.worldView.y; + DebugUtils.game.stage.context.fillStyle = color; + DebugUtils.game.stage.context.fillRect(dx, dy, sprite.width, sprite.height); + }; + DebugUtils.renderSpritePhysicsBody = function renderSpritePhysicsBody(sprite, camera, color) { + if (typeof camera === "undefined") { camera = null; } + if (typeof color === "undefined") { color = 'rgba(255,0,0,0.2)'; } + if(camera == null) { + camera = DebugUtils.game.camera; + } + var dx = (camera.screenView.x * sprite.transform.scrollFactor.x) + sprite.body.x - (camera.worldView.x * sprite.transform.scrollFactor.x); + var dy = (camera.screenView.y * sprite.transform.scrollFactor.y) + sprite.body.y - (camera.worldView.y * sprite.transform.scrollFactor.y); + DebugUtils.game.stage.context.fillStyle = color; + DebugUtils.game.stage.context.fillRect(dx, dy, sprite.body.width, sprite.body.height); + }; return DebugUtils; })(); Phaser.DebugUtils = DebugUtils; @@ -16651,6 +16749,7 @@ var Phaser; if(this._loadComplete && this.onUpdateCallback) { this.onUpdateCallback.call(this.callbackContext); } + this.world.postUpdate(); this.renderer.render(); if(this._loadComplete && this.onRenderCallback) { this.onRenderCallback.call(this.callbackContext);