diff --git a/Docs/Screen Shots/phaser_fixed_camera.png b/Docs/Screen Shots/phaser_fixed_camera.png new file mode 100644 index 00000000..28263fa4 Binary files /dev/null and b/Docs/Screen Shots/phaser_fixed_camera.png differ diff --git a/README.md b/README.md index b3095d29..0d465125 100644 --- a/README.md +++ b/README.md @@ -90,12 +90,20 @@ Version 1.0.7 (in progress in the dev branch) * Made Sprite.body optional and added in checks, so you can safely null the Sprite body object if using your own physics system and not impact rendering. * Fixed typo in StageScaleMode so it's not pageAlignVeritcally any longer, but pageAlignVertically. * Fixed issue in Group.countLiving / countDead where the value was off by one (thanks mjablonski) +* Fixed issue with a jittery Camera if you moved a Sprite via velocity instead of x/y placement. +* Added Keyboard.createCursorKeys() which creates an object with 4 Key objects inside it mapped to up, down, left and right. See the new example in the input folder. +* Added Body.skipQuadTree boolean for more fine-grained control over when a body is added to the World QuadTree. +* Re-implemented Angular Velocity and Angular Acceleration on the Sprite.body and created 2 new examples to show use. +* Moved the Camera update checks to World.postUpdate, so all the sprites get the correct adjusted camera position. +* Added Sprite.fixedToCamera boolean. A Sprite that is fixed to the camera doesn't move with the world, but has its x/y coordinates relative to the top-left of the camera. + * TODO: look at Sprite.crop (http://www.html5gamedevs.com/topic/1617-error-in-spritecrop/) * TODO: d-pad example (http://www.html5gamedevs.com/topic/1574-gameinputondown-question/) * TODO: more touch input examples (http://www.html5gamedevs.com/topic/1556-mobile-touch-event/) * TODO: addMarker hh:mm:ss:ms * TODO: swap state (non-destructive shift) +* TODO: rotation offset Version 1.0.6 (September 24th 2013) diff --git a/examples/assets/sprites/arrow.png b/examples/assets/sprites/arrow.png new file mode 100644 index 00000000..45db091a Binary files /dev/null and b/examples/assets/sprites/arrow.png differ diff --git a/examples/assets/sprites/phaser1.png b/examples/assets/sprites/phaser1.png new file mode 100644 index 00000000..0b7f0d52 Binary files /dev/null and b/examples/assets/sprites/phaser1.png differ diff --git a/examples/assets/sprites/phaser2.png b/examples/assets/sprites/phaser2.png new file mode 100644 index 00000000..a37a23af Binary files /dev/null and b/examples/assets/sprites/phaser2.png differ diff --git a/examples/camera/basic follow.php b/examples/camera/basic follow.php index d2e1bfa7..501494ab 100644 --- a/examples/camera/basic follow.php +++ b/examples/camera/basic follow.php @@ -8,7 +8,7 @@ - var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { preload: preload, create: create, update: update }); + var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { preload: preload, create: create, update: update, render: render }); var baddie, keys=Phaser.Keyboard; @@ -28,7 +28,7 @@ game.add.tileSprite(0, 0, 2000, 2000, 'background'); - game.world.setBounds(1400,1400); + game.world.setBounds(0, 0, 1400,1400); for(var i=0,nb=10;i diff --git a/examples/input/cursor key movement.php b/examples/input/cursor key movement.php new file mode 100644 index 00000000..ad3c8aa9 --- /dev/null +++ b/examples/input/cursor key movement.php @@ -0,0 +1,90 @@ + + + + + diff --git a/examples/physics/angular acceleration.php b/examples/physics/angular acceleration.php new file mode 100644 index 00000000..2e28e123 --- /dev/null +++ b/examples/physics/angular acceleration.php @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/examples/physics/angular velocity.php b/examples/physics/angular velocity.php new file mode 100644 index 00000000..076e70cd --- /dev/null +++ b/examples/physics/angular velocity.php @@ -0,0 +1,61 @@ + + + + + \ No newline at end of file diff --git a/examples/physics/Motion.php b/examples/physics/mass velocity test.php similarity index 67% rename from examples/physics/Motion.php rename to examples/physics/mass velocity test.php index 3a24df8e..9707a9d4 100644 --- a/examples/physics/Motion.php +++ b/examples/physics/mass velocity test.php @@ -1,49 +1,41 @@ diff --git a/examples/physics/sprite bounds.php b/examples/physics/sprite bounds.php index 5e05210b..20dafc70 100644 --- a/examples/physics/sprite bounds.php +++ b/examples/physics/sprite bounds.php @@ -22,7 +22,7 @@ fuji = game.add.sprite(game.world.centerX, game.world.centerY, 'fuji'); fuji.anchor.setTo(0, 0.5); - fuji.angle = 34; + // fuji.angle = 34; b = new Phaser.Rectangle(fuji.center.x, fuji.center.y, fuji.width, fuji.height); diff --git a/examples/sprites/sprite rotation.php b/examples/sprites/sprite rotation.php new file mode 100644 index 00000000..706a815f --- /dev/null +++ b/examples/sprites/sprite rotation.php @@ -0,0 +1,46 @@ + + + + + \ No newline at end of file diff --git a/examples/tilemaps/mapcollide.php b/examples/tilemaps/mapcollide.php index fdc3082d..d38fb888 100644 --- a/examples/tilemaps/mapcollide.php +++ b/examples/tilemaps/mapcollide.php @@ -5,8 +5,6 @@ + + diff --git a/src/core/Camera.js b/src/core/Camera.js index 7eda4317..7fe7e3e0 100644 --- a/src/core/Camera.js +++ b/src/core/Camera.js @@ -164,8 +164,7 @@ Phaser.Camera.prototype = { */ focusOnXY: function (x, y) { - this.view.x = Math.round(x - this.view.halfWidth); - this.view.y = Math.round(y - this.view.halfHeight); + this.setPosition(Math.round(x - this.view.halfWidth), Math.round(y - this.view.halfHeight)); }, @@ -185,6 +184,16 @@ Phaser.Camera.prototype = { this.checkBounds(); } + if (this.view.x !== -this.displayObject.position.x) + { + this.displayObject.position.x = -this.view.x; + } + + if (this.view.y !== -this.displayObject.position.y) + { + this.displayObject.position.y = -this.view.y; + } + }, updateTarget: function () { @@ -283,9 +292,6 @@ Phaser.Camera.prototype = { this.view.x = x; this.view.y = y; - this.displayObject.x = -x; - this.displayObject.y = -y; - if (this.bounds) { this.checkBounds(); @@ -323,7 +329,6 @@ Object.defineProperty(Phaser.Camera.prototype, "x", { set: function (value) { this.view.x = value; - this.displayObject.position.x = -value; if (this.bounds) { @@ -347,7 +352,6 @@ Object.defineProperty(Phaser.Camera.prototype, "y", { set: function (value) { this.view.y = value; - this.displayObject.position.y = -value; if (this.bounds) { diff --git a/src/core/World.js b/src/core/World.js index 354a3fb9..ed65fc82 100644 --- a/src/core/World.js +++ b/src/core/World.js @@ -71,8 +71,6 @@ Phaser.World.prototype.boot = function () { */ Phaser.World.prototype.update = function () { - this.camera.update(); - this.currentRenderOrderID = 0; if (this.game.stage._stage.first._iNext) @@ -104,6 +102,8 @@ Phaser.World.prototype.update = function () { */ Phaser.World.prototype.postUpdate = function () { + this.camera.update(); + if (this.game.stage._stage.first._iNext) { var currentNode = this.game.stage._stage.first._iNext; diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index a19c6225..bc27dc15 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -266,12 +266,12 @@ Phaser.Sprite = function (game, x, y, key, frame) { /** * @property {Description} velocity - Description. */ - this.velocity = this.body.velocity; + // this.velocity = this.body.velocity; /** * @property {Description} acceleration - Description. */ - this.acceleration = this.body.acceleration; + // this.acceleration = this.body.acceleration; /** * @property {Description} inWorld - World bounds check. @@ -291,6 +291,13 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this._outOfBoundsFired = false; + /** + * A Sprite that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera. + * @property {boolean} fixedToCamera - Fixes this Sprite to the Camera. + * @default + */ + this.fixedToCamera = false; + }; // Needed to keep the PIXI.Sprite constructor in the prototype chain (as the core pixi renderer uses an instanceof check sadly) @@ -428,8 +435,16 @@ Phaser.Sprite.prototype.postUpdate = function() { this.body.postUpdate(); } - this._cache.x = this.x; - this._cache.y = this.y; + if (this.fixedToCamera) + { + this._cache.x = this.game.camera.view.x + this.x; + this._cache.y = this.game.camera.view.y + this.y; + } + else + { + this._cache.x = this.x; + this._cache.y = this.y; + } if (this.position.x != this._cache.x || this.position.y != this._cache.y) { @@ -644,14 +659,21 @@ Phaser.Sprite.prototype.play = function (name, frameRate, loop) { } +/** +* Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. +* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90. +* If you wish to work in radians instead of degrees use the property Sprite.rotation instead. +* @name Phaser.Sprite#angle +* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees. +*/ Object.defineProperty(Phaser.Sprite.prototype, 'angle', { get: function() { - return Phaser.Math.radToDeg(this.rotation); + return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation)); }, set: function(value) { - this.rotation = Phaser.Math.degToRad(value); + this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value)); } }); diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index 2c6405b8..c48cff67 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -48,9 +48,9 @@ Phaser.Physics.Arcade.prototype = { // If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html // Rotation - this._velocityDelta = (this.computeVelocity(0, false, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2; + this._velocityDelta = (this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2; body.angularVelocity += this._velocityDelta; - body.rotation += body.angularVelocity * this.game.time.physicsElapsed; + body.rotation += (body.angularVelocity * this.game.time.physicsElapsed); body.angularVelocity += this._velocityDelta; // Horizontal @@ -100,7 +100,7 @@ Phaser.Physics.Arcade.prototype = { if (velocity - this._drag > 0) { - velocity = velocity - this._drag; + velocity -= this._drag; } else if (velocity + this._drag < 0) { diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index 853d8002..ae94b6fb 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -9,6 +9,7 @@ Phaser.Physics.Arcade.Body = function (sprite) { this.y = sprite.y; this.preX = sprite.x; this.preY = sprite.y; + this.preRotation = sprite.angle; // un-scaled original size this.sourceWidth = sprite.currentFrame.sourceSizeW; @@ -37,6 +38,7 @@ Phaser.Physics.Arcade.Body = function (sprite) { this.maxAngular = 1000; this.mass = 1; + this.skipQuadTree = false; this.quadTreeIDs = []; this.quadTreeIndex = -1; @@ -105,22 +107,23 @@ Phaser.Physics.Arcade.Body.prototype = { this.preX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x; this.preY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y; - this.rotation = this.sprite.angle; + this.preRotation = this.sprite.angle; this.x = this.preX; this.y = this.preY; + this.rotation = this.preRotation; if (this.moves) { this.game.physics.updateMotion(this); + + if (this.collideWorldBounds) + { + this.checkWorldBounds(); + } } - if (this.collideWorldBounds) - { - this.checkWorldBounds(); - } - - if (this.allowCollision.none == false && this.sprite.visible && this.sprite.alive) + if (this.skipQuadTree == false && this.allowCollision.none == false && this.sprite.visible && this.sprite.alive) { this.quadTreeIDs = []; this.quadTreeIndex = -1; @@ -159,20 +162,12 @@ Phaser.Physics.Arcade.Body.prototype = { this.facing = Phaser.DOWN; } - if (this.deltaX() != 0) - { - this.sprite.x += this.deltaX(); - } - - if (this.deltaY() != 0) - { - this.sprite.y += this.deltaY(); - } + this.sprite.x += this.deltaX(); + this.sprite.y += this.deltaY(); if (this.allowRotation) { - // Needs to use rotation delta - // this.sprite.angle += this.rotation; + this.sprite.angle += this.deltaZ(); } }, @@ -247,6 +242,10 @@ Phaser.Physics.Arcade.Body.prototype = { deltaY: function () { return this.y - this.preY; + }, + + deltaZ: function () { + return this.rotation - this.preRotation; } }; diff --git a/src/tilemap/Tilemap.js b/src/tilemap/Tilemap.js index 203d4495..847ea55c 100644 --- a/src/tilemap/Tilemap.js +++ b/src/tilemap/Tilemap.js @@ -120,7 +120,7 @@ Phaser.Tilemap = function (game, key, x, y, resizeWorld, tileWidth, tileHeight) if (this.currentLayer && resizeWorld) { - this.game.world.setSize(this.currentLayer.widthInPixels, this.currentLayer.heightInPixels, true); + this.game.world.setBounds(0, 0, this.currentLayer.widthInPixels, this.currentLayer.heightInPixels); } };