diff --git a/examples/wip/physics-2.js b/examples/wip/physics-2.js new file mode 100644 index 00000000..def38031 --- /dev/null +++ b/examples/wip/physics-2.js @@ -0,0 +1,107 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('map', 'assets/tilemaps/maps/tile_collision_test.json', null, Phaser.Tilemap.TILED_JSON); + + game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); + game.load.image('phaser', 'assets/sprites/arrow.png'); + game.load.spritesheet('coin', 'assets/sprites/coin.png', 32, 32); + +} + +var map; +var layer; + +var sprite; +var cursors; + +function create() { + + map = game.add.tilemap('map'); + + map.addTilesetImage('ground_1x1'); + // map.addTilesetImage('coin'); + + map.setCollisionBetween(1, 12); + + // map.setTileIndexCallback(26, hitCoin, this); + + // map.setTileLocationCallback(2, 0, 1, 1, hitCoin, this); + + layer = map.createLayer('Tile Layer 1'); + + layer.debug = true; + + layer.resizeWorld(); + + // game.physics.arcade.gravity.y = 100; + + sprite = game.add.sprite(260, 100, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + + game.physics.enable(sprite); + + // sprite.body.setRectangle(16, 16, 8, 8); + + // We'll set a lower max angular velocity here to keep it from going totally nuts + sprite.body.maxAngular = 500; + + // Apply a drag otherwise the sprite will just spin and never slow down + sprite.body.angularDrag = 50; + + // sprite.body.bounce.x = 0.8; + // sprite.body.bounce.y = 0.8; + + debugSprite = sprite; + + game.camera.follow(sprite); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function hitCoin(sprite, tile) { + + tile.tile.alpha = 0.2; + + layer.dirty = true; + + return false; + +} + +function update() { + + game.physics.arcade.collide(sprite, layer); + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + if (cursors.left.isDown) + { + sprite.body.angularVelocity = -300; + } + else if (cursors.right.isDown) + { + sprite.body.angularVelocity = 300; + } + + if (cursors.up.isDown) + { + game.physics.arcade.velocityFromAngle(sprite.angle, 300, sprite.body.velocity); + } + +} + +function render() { + + // game.debug.bodyInfo(sprite, 16, 24); + // game.debug.physicsBody(sprite.body); + + var r = new Phaser.Rectangle(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height); + game.debug.geom(r); + +} \ No newline at end of file diff --git a/examples/wip/sci-fly2.js b/examples/wip/sci-fly2.js index 2bc05e6c..cdc82363 100644 --- a/examples/wip/sci-fly2.js +++ b/examples/wip/sci-fly2.js @@ -1,5 +1,6 @@ -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); +// var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { @@ -48,8 +49,13 @@ function create() { sprite = game.add.sprite(200, 70, 'phaser'); sprite.anchor.setTo(0.5, 0.5); + game.physics.enable(sprite); + sprite.body.setSize(14, 14, 2, 0); + + console.log(sprite.body); + game.camera.follow(sprite); } @@ -72,26 +78,36 @@ function update() { if (cursors.up.isDown) { - sprite.body.velocity.y = -150; + sprite.body.velocity.y = -100; // particleBurst(); } else if (cursors.down.isDown) { - sprite.body.velocity.y = 150; + sprite.body.velocity.y = 100; // particleBurst(); } if (cursors.left.isDown) { - sprite.body.velocity.x = -150; + sprite.body.velocity.x = -100; sprite.scale.x = -1; // particleBurst(); } else if (cursors.right.isDown) { - sprite.body.velocity.x = 150; + sprite.body.velocity.x = 100; sprite.scale.x = 1; // particleBurst(); } } + +function render() { + + // game.debug.text(game.physics.arcade._intersection.width, 32, 32); + // game.debug.text(game.physics.arcade._intersection.height, 32, 64); + + game.debug.text(sprite.body.overlapX, 32, 32); + game.debug.text(sprite.body.overlapY, 32, 64); + +} diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index 5757c366..3c99b627 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -351,8 +351,8 @@ Phaser.Physics.Arcade.Body.prototype = { this.embedded = false; - this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x; - this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y; + // this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x; + // this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y; this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x; this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y; @@ -363,8 +363,8 @@ Phaser.Physics.Arcade.Body.prototype = { this.y = this.preY; this.rotation = this.preRotation; - this.overlapX = 0; - this.overlapY = 0; + // this.overlapX = 0; + // this.overlapY = 0; this.blocked.up = false; this.blocked.down = false; @@ -564,7 +564,8 @@ Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", { * @return {number} */ get: function () { - return Math.floor(this.y + this.height); + // return Math.floor(this.y + this.height); + return this.y + this.height; }, /** @@ -600,7 +601,8 @@ Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", { * @return {number} */ get: function () { - return Math.floor(this.x + this.width); + // return Math.floor(this.x + this.width); + return this.x + this.width; }, /** diff --git a/src/physics/arcade/World.js b/src/physics/arcade/World.js index 289f1eba..da0fc623 100644 --- a/src/physics/arcade/World.js +++ b/src/physics/arcade/World.js @@ -156,7 +156,8 @@ Phaser.Physics.Arcade = function (game) { * @property {number} _intersection - Internal cache var. * @private */ - this._intersection = [0,0,0,0]; + // this._intersection = [0,0,0,0]; + this._intersection = new Phaser.Rectangle(); }; @@ -672,7 +673,7 @@ Phaser.Physics.Arcade.prototype = { // Body1 is moving right and/or Body2 is moving left this._overlap = body1.x + body1.width - body2.x; - if ((this._overlap > this._maxOverlap) || body1.allowCollision.right === false || body2.allowCollision.left === false) + if ((this._overlap > this._maxOverlap) || body1.checkCollision.right === false || body2.checkCollision.left === false) { this._overlap = 0; } @@ -687,7 +688,7 @@ Phaser.Physics.Arcade.prototype = { // Body1 is moving left and/or Body2 is moving right this._overlap = body1.x - body2.width - body2.x; - if ((-this._overlap > this._maxOverlap) || body1.allowCollision.left === false || body2.allowCollision.right === false) + if ((-this._overlap > this._maxOverlap) || body1.checkCollision.left === false || body2.checkCollision.right === false) { this._overlap = 0; } @@ -781,7 +782,7 @@ Phaser.Physics.Arcade.prototype = { // Body1 is moving down and/or Body2 is moving up this._overlap = body1.y + body1.height - body2.y; - if ((this._overlap > this._maxOverlap) || body1.allowCollision.down === false || body2.allowCollision.up === false) + if ((this._overlap > this._maxOverlap) || body1.checkCollision.down === false || body2.checkCollision.up === false) { this._overlap = 0; } @@ -796,7 +797,7 @@ Phaser.Physics.Arcade.prototype = { // Body1 is moving up and/or Body2 is moving down this._overlap = body1.y - body2.height - body2.y; - if ((-this._overlap > this._maxOverlap) || body1.allowCollision.up === false || body2.allowCollision.down === false) + if ((-this._overlap > this._maxOverlap) || body1.checkCollision.up === false || body2.checkCollision.down === false) { this._overlap = 0; } @@ -879,23 +880,18 @@ Phaser.Physics.Arcade.prototype = { */ tileIntersects: function (body, tile) { + this._intersection[0] = 0; + this._intersection[1] = 0; + this._intersection[2] = 0; + this._intersection[3] = 0; + this._intersection[4] = 0; + if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0) { this._intersection[4] = 0; return this._intersection; } - // if (!(body.right < tile.x || body.bottom < tile.y || body.left > tile.right || body.top > tile.bottom)) - // { - // this._intersection[0] = Math.max(body.left, tile.x); // x - // this._intersection[1] = Math.max(body.top, tile.y); // y - // this._intersection[2] = Math.min(body.right, tile.right) - this._intersection[0]; // width - // this._intersection[3] = Math.min(body.bottom, tile.bottom) - this._intersection[1]; // height - // this._intersection[4] = 1; - - // return this._intersection; - // } - if (!(body.right < tile.x || body.bottom < tile.y || body.x > tile.right || body.y > tile.bottom)) { this._intersection[0] = Math.max(body.x, tile.x); // x @@ -920,7 +916,7 @@ Phaser.Physics.Arcade.prototype = { * @param {array} tiles - The array of tiles to collide against. * @returns {boolean} Returns true if the body was separated, otherwise false. */ - OLDseparateTiles: function (body, tiles) { + separateTiles: function (body, tiles) { var tile; var result = false; @@ -946,8 +942,9 @@ Phaser.Physics.Arcade.prototype = { * @param {Phaser.Tile} tile - The tile to collide against. * @returns {boolean} Returns true if the body was separated, otherwise false. */ - OLDseparateTile: function (body, tile) { + separateTile: function (body, tile) { + /* this._intersection = this.tileIntersects(body, tile); // If the intersection area is either entirely null, or has a width/height of zero, we bail out now @@ -955,6 +952,17 @@ Phaser.Physics.Arcade.prototype = { { return false; } + */ + + Phaser.Rectangle.intersection(body, tile, this._intersection); + + if (this._intersection.width === 0 && this._intersection.height === 0) + { + return false; + } + + // console.log(this._intersection); + // console.log(tile, body.x, body.y); // They overlap. Any custom callbacks? if (tile.tile.callback || tile.layer.callbacks[tile.tile.index]) @@ -973,11 +981,112 @@ Phaser.Physics.Arcade.prototype = { } body.overlapX = 0; + + var process = false; + + if (this._intersection.width > 0) + { + // Tile is blocking to the right and body is moving left + if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight) + { + process = true; + body.overlapX = -this._intersection.width; + } + + // Tile is blocking to the left and body is moving right + if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft) + { + process = true; + body.overlapX = this._intersection.width; + } + } + + if (body.overlapX !== 0) + { + if (body.overlapX < 0) + { + body.blocked.left = true; + } + else if (body.overlapX > 0) + { + body.blocked.right = true; + } + + body.x -= body.overlapX; + body.preX -= body.overlapX; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + + if (body.bounce.x === 0) + { + body.velocity.x = 0; + } + else + { + body.velocity.x = -body.velocity.x * body.bounce.x; + } + } + + Phaser.Rectangle.intersection(body, tile, this._intersection); + + if (this._intersection.width === 0 && this._intersection.height === 0) + { + return false; + } + body.overlapY = 0; var process = false; + if (this._intersection.height > 0) + { + // Tile is blocking to the bottom and body is moving up + if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom) + { + process = true; + body.overlapY = -this._intersection.height; + } + + // Tile is blocking to the top and body is moving down + if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop) + { + process = true; + body.overlapY = this._intersection.height; + } + } + + if (body.overlapY !== 0) + { + if (body.overlapY < 0) + { + body.blocked.up = true; + } + else if (body.overlapY > 0) + { + body.blocked.down = true; + } + + body.y -= body.overlapY; + body.preY -= body.overlapY; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + + if (body.bounce.y === 0) + { + body.velocity.y = 0; + } + else + { + body.velocity.y = -body.velocity.y * body.bounce.y; + } + } + + return; + + + /* if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight && !body.blocked.left) + // if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight) { // LEFT body.overlapX = body.x - tile.right; @@ -992,6 +1101,7 @@ Phaser.Physics.Arcade.prototype = { } } else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft && !body.blocked.right) + // else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft) { // RIGHT body.overlapX = body.right - tile.x; @@ -1007,6 +1117,7 @@ Phaser.Physics.Arcade.prototype = { } if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom && !body.blocked.up) + // if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom) { // UP body.overlapY = body.y - tile.bottom; @@ -1021,6 +1132,7 @@ Phaser.Physics.Arcade.prototype = { } } else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop && !body.blocked.down) + // else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop) { // DOWN body.overlapY = body.bottom - tile.y; @@ -1034,8 +1146,10 @@ Phaser.Physics.Arcade.prototype = { body.overlapY = 0; } } + */ // Only separate on the smallest of the two values if it's a single tile + /* if (body.overlapX !== 0 && body.overlapY !== 0) { if (Math.abs(body.overlapX) > Math.abs(body.overlapY)) @@ -1047,9 +1161,10 @@ Phaser.Physics.Arcade.prototype = { body.overlapY = 0; } } + */ // Separate in a single sweep - if (process) +/* if (process) { return this.processTileSeparation(body); } @@ -1057,7 +1172,7 @@ Phaser.Physics.Arcade.prototype = { { return false; } - +*/ }, /** @@ -1069,29 +1184,22 @@ Phaser.Physics.Arcade.prototype = { */ processTileSeparation: function (body) { - if (body.overlapX < 0) - { - body.x -= body.overlapX; - body.preX -= body.overlapX; - // body.left -= body.overlapX; - // body.right -= body.overlapX; - body.blocked.x = Math.floor(body.x); - body.blocked.y = Math.floor(body.y); - body.blocked.left = true; - } - else if (body.overlapX > 0) - { - body.x -= body.overlapX; - body.preX -= body.overlapX; - // body.left -= body.overlapX; - // body.right -= body.overlapX; - body.blocked.x = Math.floor(body.x); - body.blocked.y = Math.floor(body.y); - body.blocked.right = true; - } - if (body.overlapX !== 0) { + if (body.overlapX < 0) + { + body.blocked.left = true; + } + else if (body.overlapX > 0) + { + body.blocked.right = true; + } + + body.x -= body.overlapX; + body.preX -= body.overlapX; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + if (body.bounce.x === 0) { body.velocity.x = 0; @@ -1102,29 +1210,22 @@ Phaser.Physics.Arcade.prototype = { } } - if (body.overlapY < 0) - { - body.y -= body.overlapY; - body.preY -= body.overlapY; - // body.top -= body.overlapY; - // body.bottom -= body.overlapY; - body.blocked.x = Math.floor(body.x); - body.blocked.y = Math.floor(body.y); - body.blocked.up = true; - } - else if (body.overlapY > 0) - { - body.y -= body.overlapY; - body.preY -= body.overlapY; - // body.top -= body.overlapY; - // body.bottom -= body.overlapY; - body.blocked.x = Math.floor(body.x); - body.blocked.y = Math.floor(body.y); - body.blocked.down = true; - } - if (body.overlapY !== 0) { + if (body.overlapY < 0) + { + body.blocked.up = true; + } + else if (body.overlapY > 0) + { + body.blocked.down = true; + } + + body.y -= body.overlapY; + body.preY -= body.overlapY; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + if (body.bounce.y === 0) { body.velocity.y = 0; @@ -1146,7 +1247,7 @@ Phaser.Physics.Arcade.prototype = { * @param {Phaser.Tile} tile - The tile to collide against. * @returns {boolean} Returns true if the bodies were separated, otherwise false. */ - separateTiles: function (body, tiles) { + OLDseparateTiles: function (body, tiles) { // Can't separate two immovable objects (tiles are always immovable) // if (body.immovable) @@ -1167,7 +1268,7 @@ Phaser.Physics.Arcade.prototype = { if (Phaser.Rectangle.intersects(body, tile)) { - if (body.deltaX() < 0 && body.allowCollision.left && tile.tile.faceRight) + if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight) { // LEFT localOverlapX = body.x - tile.right; @@ -1181,7 +1282,7 @@ Phaser.Physics.Arcade.prototype = { body.touching.none = false; } } - else if (body.deltaX() > 0 && body.allowCollision.right && tile.tile.faceLeft) + else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft) { // RIGHT localOverlapX = body.right - tile.x; @@ -1196,7 +1297,7 @@ Phaser.Physics.Arcade.prototype = { } } - if (body.deltaY() < 0 && body.allowCollision.up && tile.tile.faceBottom) + if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom) { // UP localOverlapY = body.y - tile.bottom; @@ -1210,7 +1311,7 @@ Phaser.Physics.Arcade.prototype = { body.touching.none = false; } } - else if (body.deltaY() > 0 && body.allowCollision.down && tile.tile.faceTop) + else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop) { // DOWN localOverlapY = body.bottom - tile.y; @@ -1284,10 +1385,11 @@ Phaser.Physics.Arcade.prototype = { * @param {Phaser.Tile} tile - The tile to collide against. * @returns {boolean} Returns true if the bodies were separated, otherwise false. */ - separateTile: function (body, tile) { + OLDseparateTile: function (body, tile) { // Can't separate two immovable objects (tiles are always immovable) - if (body.immovable || Phaser.Rectangle.intersects(body, tile) === false) + // if (body.immovable || Phaser.Rectangle.intersects(body, tile) === false) + if (Phaser.Rectangle.intersects(body, tile) === false) { // console.log('no intersects'); // console.log('tx', tile.x, 'ty', tile.y, 'tw', tile.width, 'th', tile.height, 'tr', tile.right, 'tb', tile.bottom); @@ -1306,7 +1408,7 @@ Phaser.Physics.Arcade.prototype = { // console.log(Phaser.Rectangle.intersects(body, tile)); // console.log('dx', body.deltaX(), 'dy', body.deltaY(), 'dax', body.deltaAbsX(), 'day', body.deltaAbsY(), 'cax', Math.ceil(body.deltaAbsX()), 'cay', Math.ceil(body.deltaAbsY())); - if (body.deltaX() < 0 && body.allowCollision.left && tile.tile.faceRight) + if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight) { // LEFT body.overlapX = body.x - tile.right; @@ -1320,7 +1422,7 @@ Phaser.Physics.Arcade.prototype = { body.touching.none = false; } } - else if (body.deltaX() > 0 && body.allowCollision.right && tile.tile.faceLeft) + else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft) { // RIGHT body.overlapX = body.right - tile.x; @@ -1335,7 +1437,7 @@ Phaser.Physics.Arcade.prototype = { } } - if (body.deltaY() < 0 && body.allowCollision.up && tile.tile.faceBottom) + if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom) { // UP body.overlapY = body.y - tile.bottom; @@ -1349,7 +1451,7 @@ Phaser.Physics.Arcade.prototype = { body.touching.none = false; } } - else if (body.deltaY() > 0 && body.allowCollision.down && tile.tile.faceTop) + else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop) { // DOWN body.overlapY = body.bottom - tile.y;