From fd5eeb9088403eb869419bfafde305953cabfedb Mon Sep 17 00:00:00 2001 From: photonstorm Date: Tue, 15 Oct 2013 15:24:07 +0100 Subject: [PATCH] Fixed Rectangle intersection issue and tilemap collision is working again. Win! --- examples/tilemaps/wip2.php | 18 +++- src/geom/Rectangle.js | 10 ++- src/physics/arcade/ArcadePhysics.js | 126 ++++++++++++++++------------ src/tilemap/TilemapLayer.js | 2 +- src/utils/Debug.js | 22 +++-- 5 files changed, 104 insertions(+), 74 deletions(-) diff --git a/examples/tilemaps/wip2.php b/examples/tilemaps/wip2.php index 6095d598..74be00c2 100644 --- a/examples/tilemaps/wip2.php +++ b/examples/tilemaps/wip2.php @@ -12,7 +12,8 @@ game.load.tilemap('level3', 'assets/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON); game.load.tileset('tiles', 'assets/maps/cybernoid.png', 16, 16); - game.load.image('phaser', 'assets/sprites/phaser-dude.png'); + // game.load.image('phaser', 'assets/sprites/phaser-dude.png'); + game.load.image('phaser', 'assets/sprites/space-baddie.png'); } @@ -42,6 +43,8 @@ // And this turns off collision on the only tile we don't want collision on :) tileset.setCollision(6, false, false, false, false); + tileset.setCollision(34, false, false, false, false); + tileset.setCollision(35, false, false, false, false); // A TilemapLayer consists of an x,y coordinate (position), a width and height, a Tileset and a Tilemap which it uses for map data. // The x/y coordinates are in World space and you can place the tilemap layer anywhere in the world. @@ -92,6 +95,7 @@ sprite = game.add.sprite(200, 80, 'phaser'); cursors = game.input.keyboard.createCursorKeys(); + } function update() { @@ -102,7 +106,7 @@ if (cursors.up.isDown) { - sprite.body.velocity.y = -100; + sprite.body.velocity.y = -100; // layer.y -= 4; } else if (cursors.down.isDown) @@ -127,6 +131,7 @@ if (overlap.length > 1) { + // console.log('%c ', 'background: #000000') for (var i = 1; i < overlap.length; i++) { game.physics.separateTile(sprite.body, overlap[i]); @@ -139,8 +144,14 @@ layer.render(); + game.debug.renderSpriteInfo(sprite, 32, 450); + // game.debug.renderCameraInfo(game.camera, 32, 32); + + /* game.context.save(); game.context.setTransform(1, 0, 0, 1, 0, 0); + + game.context.fillStyle = 'rgba(255, 0, 0, 0.5)'; if (overlap.length > 1) @@ -178,8 +189,9 @@ } game.context.restore(); + */ - game.debug.renderRectangle(sprite.body.hullX); + // game.debug.renderRectangle(sprite.body.hullX); } diff --git a/src/geom/Rectangle.js b/src/geom/Rectangle.js index 44b6d3f6..f6950e0f 100644 --- a/src/geom/Rectangle.js +++ b/src/geom/Rectangle.js @@ -618,14 +618,16 @@ Phaser.Rectangle.intersection = function (a, b, out) { * @method Phaser.Rectangle.intersects * @param {Phaser.Rectangle} a - The first Rectangle object. * @param {Phaser.Rectangle} b - The second Rectangle object. -* @param {number} tolerance - A tolerance value to allow for an intersection test with padding, default to 0 * @return {boolean} A value of true if the specified object intersects with this Rectangle object; otherwise false. */ -Phaser.Rectangle.intersects = function (a, b, tolerance) { +Phaser.Rectangle.intersects = function (a, b) { - tolerance = tolerance || 0; + return (a.x < b.right && b.x < a.right && a.y < b.bottom && b.y < a.bottom); - return !(a.x > b.right + tolerance || a.right < b.x - tolerance || a.y > b.bottom + tolerance || a.bottom < b.y - tolerance); + // return (a.x <= b.right && b.x <= a.right && a.y <= b.bottom && b.y <= a.bottom); + + // return (a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom); + // return !(a.x > b.right + tolerance || a.right < b.x - tolerance || a.y > b.bottom + tolerance || a.bottom < b.y - tolerance); }; diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index d59a8708..bc4c75c1 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -636,19 +636,26 @@ Phaser.Physics.Arcade.prototype = { separateTile: function (body, tile) { var separatedX = this.separateTileX(body, tile, true); + var separatedY = this.separateTileY(body, tile, true); + /* if (separatedX) { console.log('x overlap', this._overlap); } - var separatedY = this.separateTileY(body, tile, true); if (separatedY) { console.log('y overlap', this._overlap); } + if (separatedX || separatedY) + { + return true; + } + */ + if (separatedX || separatedY) { return true; @@ -667,46 +674,50 @@ Phaser.Physics.Arcade.prototype = { separateTileX: function (body, tile, separate) { // Can't separate two immovable objects (tiles are always immovable) - if (body.immovable) + if (body.immovable || body.deltaX() == 0 || Phaser.Rectangle.intersects(body.hullX, tile) == false) { return false; } this._overlap = 0; - // Phaser.Rectangle.intersectsRaw = function (a, left, right, top, bottom, tolerance) - if (body.deltaX() != 0 && Phaser.Rectangle.intersects(body.hullX, tile, 0)) + // The hulls overlap, let's process it + this._maxOverlap = body.deltaAbsX() + this.OVERLAP_BIAS; + + console.log('sx hulls over'); + console.log('x', body.hullX.x, 'y', body.hullX.y, 'bottom', body.hullX.y, 'right', body.hullX.right); + console.log(tile); + + if (body.deltaX() < 0) { - // The hulls overlap, let's process it - this._maxOverlap = body.deltaAbsX() + this.OVERLAP_BIAS; + // Moving left + this._overlap = tile.right - body.hullX.x; - if (body.deltaX() < 0) + console.log('sx left', this._overlap); + + if ((this._overlap > this._maxOverlap) || body.allowCollision.left == false || tile.tile.collideRight == false) { - // Moving left - this._overlap = tile.right - body.hullX.x; - - if ((this._overlap > this._maxOverlap) || body.allowCollision.left == false || tile.tile.collideRight == false) - { - this._overlap = 0; - } - else - { - body.touching.left = true; - } + this._overlap = 0; } else { - // Moving right - this._overlap = body.hullX.right - tile.left; + body.touching.left = true; + } + } + else + { + // Moving right + this._overlap = body.hullX.right - tile.x; - if ((this._overlap > this._maxOverlap) || body.allowCollision.right == false || tile.tile.collideLeft == false) - { - this._overlap = 0; - } - else - { - body.touching.right = true; - } + console.log('sx right', this._overlap); + + if ((this._overlap > this._maxOverlap) || body.allowCollision.right == false || tile.tile.collideLeft == false) + { + this._overlap = 0; + } + else + { + body.touching.right = true; } } @@ -717,11 +728,15 @@ Phaser.Physics.Arcade.prototype = { { if (body.deltaX() < 0) { + console.log('sx sep left 1', body.x); body.x = body.x + this._overlap; + console.log('sx sep left 2', body.x); } else { + console.log('sx sep right 1', body.x); body.x = body.x - this._overlap; + console.log('sx sep right 2', body.x); } if (body.bounce.x == 0) @@ -732,12 +747,16 @@ Phaser.Physics.Arcade.prototype = { { body.velocity.x = -body.velocity.x * body.bounce.x; } + body.updateHulls(); } + + console.log('%c ', 'background: #7f7f7f') return true; } else { + console.log('%c ', 'background: #7f7f7f') return false; } @@ -752,45 +771,42 @@ Phaser.Physics.Arcade.prototype = { separateTileY: function (body, tile, separate) { // Can't separate two immovable objects (tiles are always immovable) - if (body.immovable) + if (body.immovable || body.deltaY() == 0 || Phaser.Rectangle.intersects(body.hullY, tile) == false) { return false; } this._overlap = 0; - if (body.deltaY() != 0 && Phaser.Rectangle.intersects(body.hullY, tile, 0)) + // The hulls overlap, let's process it + this._maxOverlap = body.deltaAbsY() + this.OVERLAP_BIAS; + + if (body.deltaY() < 0) { - // The hulls overlap, let's process it - this._maxOverlap = body.deltaAbsY() + this.OVERLAP_BIAS; + // Moving up + this._overlap = tile.bottom - body.hullY.y; - if (body.deltaY() < 0) + if ((this._overlap > this._maxOverlap) || body.allowCollision.up == false || tile.tile.collideDown == false) { - // Moving up - this._overlap = tile.bottom - body.hullY.y; - - if ((this._overlap > this._maxOverlap) || body.allowCollision.up == false || tile.tile.collideDown == false) - { - this._overlap = 0; - } - else - { - body.touching.up = true; - } + this._overlap = 0; } else { - // Moving down - this._overlap = body.hullY.bottom - tile.top; + body.touching.up = true; + } + } + else + { + // Moving down + this._overlap = body.hullY.bottom - tile.y; - if ((this._overlap > this._maxOverlap) || body.allowCollision.down == false || tile.tile.collideUp == false) - { - this._overlap = 0; - } - else - { - body.touching.down = true; - } + if ((this._overlap > this._maxOverlap) || body.allowCollision.down == false || tile.tile.collideUp == false) + { + this._overlap = 0; + } + else + { + body.touching.down = true; } } @@ -816,8 +832,10 @@ Phaser.Physics.Arcade.prototype = { { body.velocity.y = -body.velocity.y * body.bounce.y; } + body.updateHulls(); } + return true; } else diff --git a/src/tilemap/TilemapLayer.js b/src/tilemap/TilemapLayer.js index 466026dc..f05a8cb6 100644 --- a/src/tilemap/TilemapLayer.js +++ b/src/tilemap/TilemapLayer.js @@ -267,7 +267,7 @@ Phaser.TilemapLayer.prototype = { if (collides == false || (collides && _tile.collideNone == false)) { - this._results.push({ left: wx * _tile.width, right: (wx * _tile.width) + _tile.width, top: wy * _tile.height, bottom: (wy * _tile.height) + _tile.height, width: _tile.width, height: _tile.height, tx: wx, ty: wy, tile: _tile }); + this._results.push({ x: wx * _tile.width, right: (wx * _tile.width) + _tile.width, y: wy * _tile.height, bottom: (wy * _tile.height) + _tile.height, width: _tile.width, height: _tile.height, tx: wx, ty: wy, tile: _tile }); } } } diff --git a/src/utils/Debug.js b/src/utils/Debug.js index acc90e3f..6905d5ff 100644 --- a/src/utils/Debug.js +++ b/src/utils/Debug.js @@ -76,17 +76,14 @@ Phaser.Utils.Debug.prototype = { return; } - x = x || null; - y = y || null; + if (typeof x !== 'number') { x = 0; } + if (typeof y !== 'number') { y = 0; } + color = color || 'rgb(255,255,255)'; - if (x && y) - { - this.currentX = x; - this.currentY = y; - this.currentColor = color; - } - + this.currentX = x; + this.currentY = y; + this.currentColor = color; this.currentAlpha = this.context.globalAlpha; this.context.save(); @@ -103,6 +100,7 @@ Phaser.Utils.Debug.prototype = { */ stop: function () { + this.context.restore(); this.context.globalAlpha = this.currentAlpha; @@ -460,7 +458,6 @@ Phaser.Utils.Debug.prototype = { this.line('angle: ' + sprite.angle.toFixed(1) + ' rotation: ' + sprite.rotation.toFixed(1)); this.line('visible: ' + sprite.visible + ' in camera: ' + sprite.inCamera); this.line('body x: ' + sprite.body.x.toFixed(1) + ' y: ' + sprite.body.y.toFixed(1)); - this.stop(); // 0 = scaleX // 1 = skewY @@ -476,12 +473,13 @@ Phaser.Utils.Debug.prototype = { // this.line('ty: ' + sprite.worldTransform[5]); // this.line('skew x: ' + sprite.worldTransform[3]); // this.line('skew y: ' + sprite.worldTransform[1]); - // this.line('dx: ' + sprite.body.deltaX()); - // this.line('dy: ' + sprite.body.deltaY()); + this.line('deltaX: ' + sprite.body.deltaX()); + this.line('deltaY: ' + sprite.body.deltaY()); // this.line('sdx: ' + sprite.deltaX()); // this.line('sdy: ' + sprite.deltaY()); // this.line('inCamera: ' + this.game.renderer.spriteRenderer.inCamera(this.game.camera, sprite)); + this.stop(); },