mirror of
https://github.com/photonstorm/phaser
synced 2024-11-23 13:13:43 +00:00
Tilemap collision finally getting closer.
This commit is contained in:
parent
e955145707
commit
5297497632
5 changed files with 201 additions and 64 deletions
|
@ -36,7 +36,6 @@ function create() {
|
||||||
game.camera.follow(sprite);
|
game.camera.follow(sprite);
|
||||||
|
|
||||||
// game.physics.arcade.gravity.y = 500;
|
// game.physics.arcade.gravity.y = 500;
|
||||||
// sprite.body.velocity.x = 100;
|
|
||||||
|
|
||||||
cursors = game.input.keyboard.createCursorKeys();
|
cursors = game.input.keyboard.createCursorKeys();
|
||||||
|
|
||||||
|
@ -51,27 +50,32 @@ function update() {
|
||||||
|
|
||||||
if (cursors.up.isDown)
|
if (cursors.up.isDown)
|
||||||
{
|
{
|
||||||
sprite.body.velocity.y = -100;
|
sprite.body.velocity.y = -200;
|
||||||
}
|
}
|
||||||
else if (cursors.down.isDown)
|
else if (cursors.down.isDown)
|
||||||
{
|
{
|
||||||
sprite.body.velocity.y = 100;
|
sprite.body.velocity.y = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursors.left.isDown)
|
if (cursors.left.isDown)
|
||||||
{
|
{
|
||||||
sprite.body.velocity.x = -100;
|
sprite.body.velocity.x = -200;
|
||||||
}
|
}
|
||||||
else if (cursors.right.isDown)
|
else if (cursors.right.isDown)
|
||||||
{
|
{
|
||||||
sprite.body.velocity.x = 100;
|
sprite.body.velocity.x = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
|
|
||||||
game.debug.text(sprite.body.velocity.x, 32, 32);
|
// game.debug.text(sprite.body.deltaAbsX(), 32, 32);
|
||||||
game.debug.text(sprite.body.velocity.y, 64, 32);
|
// game.debug.text(sprite.body.deltaAbsY(), 32, 64);
|
||||||
|
|
||||||
|
// game.debug.text(sprite.body.deltaX(), 400, 32);
|
||||||
|
// game.debug.text(sprite.body.deltaY(), 400, 64);
|
||||||
|
|
||||||
|
game.debug.body(sprite);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -632,12 +632,12 @@ Phaser.Physics.Arcade.Body.render = function (context, body, filled, color) {
|
||||||
if (filled)
|
if (filled)
|
||||||
{
|
{
|
||||||
context.fillStyle = color;
|
context.fillStyle = color;
|
||||||
context.fillRect(body.x - body.game.camera.x, body.y - body.game.camera.y, body.width, body.height);
|
context.fillRect(body.position.x - body.game.camera.x, body.position.y - body.game.camera.y, body.width, body.height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.strokeStyle = color;
|
context.strokeStyle = color;
|
||||||
context.strokeRect(body.x - body.game.camera.x, body.y - body.game.camera.y, body.width, body.height);
|
context.strokeRect(body.position.x - body.game.camera.x, body.position.y - body.game.camera.y, body.width, body.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -606,7 +606,8 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
*/
|
*/
|
||||||
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
|
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
|
||||||
|
|
||||||
this._mapData = tilemapLayer.getIntersectingTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, sprite.body.right, sprite.body.bottom);
|
// this._mapData = tilemapLayer.getIntersectingTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, sprite.body.right, sprite.body.bottom);
|
||||||
|
this._mapData = tilemapLayer.getTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, false, true);
|
||||||
|
|
||||||
if (this._mapData.length === 0)
|
if (this._mapData.length === 0)
|
||||||
{
|
{
|
||||||
|
@ -616,6 +617,8 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
for (var i = 0; i < this._mapData.length; i++)
|
for (var i = 0; i < this._mapData.length; i++)
|
||||||
{
|
{
|
||||||
// console.log('-------------------------------------- tile', this._mapData[i].faceLeft, this._mapData[i].faceRight, this._mapData[i].faceTop, this._mapData[i].faceBottom);
|
// console.log('-------------------------------------- tile', this._mapData[i].faceLeft, this._mapData[i].faceRight, this._mapData[i].faceTop, this._mapData[i].faceBottom);
|
||||||
|
// console.log('-------------------------------------- tile', i, 'of', this._mapData.length, 'xy', this._mapData[i].x, this._mapData[i].y);
|
||||||
|
|
||||||
if (this.separateTile(i, sprite.body, this._mapData[i]))
|
if (this.separateTile(i, sprite.body, this._mapData[i]))
|
||||||
{
|
{
|
||||||
// They collided, is there a custom process callback?
|
// They collided, is there a custom process callback?
|
||||||
|
@ -743,7 +746,9 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
body1.touching.none = false;
|
||||||
body1.touching.right = true;
|
body1.touching.right = true;
|
||||||
|
body2.touching.none = false;
|
||||||
body2.touching.left = true;
|
body2.touching.left = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,7 +763,9 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
body1.touching.none = false;
|
||||||
body1.touching.left = true;
|
body1.touching.left = true;
|
||||||
|
body2.touching.none = false;
|
||||||
body2.touching.right = true;
|
body2.touching.right = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -852,7 +859,9 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
body1.touching.none = false;
|
||||||
body1.touching.down = true;
|
body1.touching.down = true;
|
||||||
|
body2.touching.none = false;
|
||||||
body2.touching.up = true;
|
body2.touching.up = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -867,7 +876,9 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
body1.touching.none = false;
|
||||||
body1.touching.up = true;
|
body1.touching.up = true;
|
||||||
|
body2.touching.none = false;
|
||||||
body2.touching.down = true;
|
body2.touching.down = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1023,8 +1034,8 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
*/
|
*/
|
||||||
separateTile: function (i, body, tile) {
|
separateTile: function (i, body, tile) {
|
||||||
|
|
||||||
// we re-check for collision in case body was separated in a previous step
|
// We re-check for collision in case body was separated in a previous step
|
||||||
if (i > 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
if (!tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
||||||
{
|
{
|
||||||
// no collision so bail out (separted in a previous step)
|
// no collision so bail out (separted in a previous step)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1048,60 +1059,73 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
|
|
||||||
var ox = 0;
|
var ox = 0;
|
||||||
var oy = 0;
|
var oy = 0;
|
||||||
|
var minX = 0;
|
||||||
|
var minY = 1;
|
||||||
|
|
||||||
if (tile.faceLeft || tile.faceRight)
|
if (body.deltaAbsX() > body.deltaAbsY())
|
||||||
{
|
{
|
||||||
if (body.deltaX() < 0 && !body.blocked.left && tile.collideRight && body.checkCollision.left)
|
// Moving faster horizontally, check X axis first
|
||||||
{
|
minX = -1;
|
||||||
// Body is moving LEFT
|
}
|
||||||
if (tile.faceRight && body.x < tile.right)
|
else if (body.deltaAbsX() < body.deltaAbsY())
|
||||||
{
|
{
|
||||||
ox = body.x - tile.right;
|
// Moving faster vertically, check Y axis first
|
||||||
}
|
minY = -1;
|
||||||
}
|
|
||||||
else if (body.deltaX() > 0 && !body.blocked.right && tile.collideLeft && body.checkCollision.right)
|
|
||||||
{
|
|
||||||
// Body is moving RIGHT
|
|
||||||
if (tile.faceLeft && body.right > tile.left)
|
|
||||||
{
|
|
||||||
ox = body.right - tile.left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ox !== 0)
|
|
||||||
{
|
|
||||||
this.processTileSeparationX(body, ox);
|
|
||||||
}
|
|
||||||
|
|
||||||
// That's horizontal done, check if we still intersects? If not then we can return now
|
|
||||||
if (!tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
|
||||||
{
|
|
||||||
return (ox !== 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile.faceTop || tile.faceBottom)
|
if (body.deltaX() !== 0 && body.deltaY() !== 0 && (tile.faceLeft || tile.faceRight) && (tile.faceTop || tile.faceBottom))
|
||||||
{
|
{
|
||||||
if (body.deltaY() < 0 && !body.blocked.up && tile.collideDown && body.checkCollision.up)
|
// We only need do this if both axis have checking faces AND we're moving in both directions
|
||||||
{
|
minX = Math.min(Math.abs(body.position.x - tile.right), Math.abs(body.right - tile.left));
|
||||||
// Body is moving UP
|
minY = Math.min(Math.abs(body.position.y - tile.bottom), Math.abs(body.bottom - tile.top));
|
||||||
if (tile.faceBottom && body.y < tile.bottom)
|
|
||||||
{
|
|
||||||
oy = body.y - tile.bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (body.deltaY() > 0 && !body.blocked.down && tile.collideUp && body.checkCollision.down)
|
|
||||||
{
|
|
||||||
// Body is moving DOWN
|
|
||||||
if (tile.faceTop && body.bottom > tile.top)
|
|
||||||
{
|
|
||||||
oy = body.bottom - tile.top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oy !== 0)
|
// console.log('checking faces', minX, minY);
|
||||||
|
|
||||||
|
// var distLeft = Math.abs(body.position.x - tile.right);
|
||||||
|
// var distRight = Math.abs(body.right - tile.left);
|
||||||
|
// var distTop = Math.abs(body.position.y - tile.bottom);
|
||||||
|
// var distBottom = Math.abs(body.bottom - tile.top);
|
||||||
|
// minX = Math.min(distLeft, distRight);
|
||||||
|
// minY = Math.min(distTop, distBottom);
|
||||||
|
// console.log('dist left', distLeft, 'right', distRight, 'top', distTop, 'bottom', distBottom, 'minX', minX, 'minY', minY);
|
||||||
|
// console.log('tile lr', tile.left, tile.right, 'tb', tile.top, tile.bottom);
|
||||||
|
// console.log('body lr', body.x, body.right, 'tb', body.y, body.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minX < minY)
|
||||||
|
{
|
||||||
|
if (tile.faceLeft || tile.faceRight)
|
||||||
{
|
{
|
||||||
this.processTileSeparationY(body, oy);
|
ox = this.tileCheckX(body, tile);
|
||||||
|
|
||||||
|
// That's horizontal done, check if we still intersects? If not then we can return now
|
||||||
|
if (ox !== 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile.faceTop || tile.faceBottom)
|
||||||
|
{
|
||||||
|
oy = this.tileCheckY(body, tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tile.faceTop || tile.faceBottom)
|
||||||
|
{
|
||||||
|
oy = this.tileCheckY(body, tile);
|
||||||
|
|
||||||
|
// That's vertical done, check if we still intersects? If not then we can return now
|
||||||
|
if (oy !== 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile.faceLeft || tile.faceRight)
|
||||||
|
{
|
||||||
|
ox = this.tileCheckX(body, tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,6 +1133,86 @@ Phaser.Physics.Arcade.prototype = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tileCheckX: function (body, tile) {
|
||||||
|
|
||||||
|
var ox = 0;
|
||||||
|
|
||||||
|
if (body.deltaX() < 0 && !body.blocked.left && tile.collideRight && body.checkCollision.left)
|
||||||
|
{
|
||||||
|
// Body is moving LEFT
|
||||||
|
if (tile.faceRight && body.x < tile.right)
|
||||||
|
{
|
||||||
|
ox = body.x - tile.right;
|
||||||
|
|
||||||
|
if (ox < -this.OVERLAP_BIAS)
|
||||||
|
{
|
||||||
|
ox = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (body.deltaX() > 0 && !body.blocked.right && tile.collideLeft && body.checkCollision.right)
|
||||||
|
{
|
||||||
|
// Body is moving RIGHT
|
||||||
|
if (tile.faceLeft && body.right > tile.left)
|
||||||
|
{
|
||||||
|
ox = body.right - tile.left;
|
||||||
|
|
||||||
|
if (ox > this.OVERLAP_BIAS)
|
||||||
|
{
|
||||||
|
ox = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ox !== 0)
|
||||||
|
{
|
||||||
|
this.processTileSeparationX(body, ox);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ox;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
tileCheckY: function (body, tile) {
|
||||||
|
|
||||||
|
var oy = 0;
|
||||||
|
|
||||||
|
if (body.deltaY() < 0 && !body.blocked.up && tile.collideDown && body.checkCollision.up)
|
||||||
|
{
|
||||||
|
// Body is moving UP
|
||||||
|
if (tile.faceBottom && body.y < tile.bottom)
|
||||||
|
{
|
||||||
|
oy = body.y - tile.bottom;
|
||||||
|
|
||||||
|
if (oy < -this.OVERLAP_BIAS)
|
||||||
|
{
|
||||||
|
oy = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (body.deltaY() > 0 && !body.blocked.down && tile.collideUp && body.checkCollision.down)
|
||||||
|
{
|
||||||
|
// Body is moving DOWN
|
||||||
|
if (tile.faceTop && body.bottom > tile.top)
|
||||||
|
{
|
||||||
|
oy = body.bottom - tile.top;
|
||||||
|
|
||||||
|
if (oy > this.OVERLAP_BIAS)
|
||||||
|
{
|
||||||
|
oy = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oy !== 0)
|
||||||
|
{
|
||||||
|
this.processTileSeparationY(body, oy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return oy;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal function to process the separation of a physics body from a tile.
|
* Internal function to process the separation of a physics body from a tile.
|
||||||
* @method Phaser.Physics.Arcade#processTileSeparationX
|
* @method Phaser.Physics.Arcade#processTileSeparationX
|
||||||
|
|
|
@ -244,6 +244,36 @@ Phaser.Tile.prototype = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this tile interesting?
|
||||||
|
*
|
||||||
|
* @method Phaser.Tile#isInteresting
|
||||||
|
* @param {boolean} collides - If true will check any collides value.
|
||||||
|
* @param {boolean} faces - If true will check any face value.
|
||||||
|
* @return {boolean} True if the Tile is interesting, otherwise false.
|
||||||
|
*/
|
||||||
|
isInteresting: function (collides, faces) {
|
||||||
|
|
||||||
|
if (collides && faces)
|
||||||
|
{
|
||||||
|
// Does this tile EITHER collide OR have an interesting face?
|
||||||
|
return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown || this.faceTop || this.faceBottom || this.faceLeft || this.faceRight);
|
||||||
|
}
|
||||||
|
else if (collides)
|
||||||
|
{
|
||||||
|
// Does this tile collide?
|
||||||
|
return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown);
|
||||||
|
}
|
||||||
|
else if (faces)
|
||||||
|
{
|
||||||
|
// Does this tile have an interesting face?
|
||||||
|
return (this.faceTop || this.faceBottom || this.faceLeft || this.faceRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the tile data and properties from the given tile to this tile.
|
* Copies the tile data and properties from the given tile to this tile.
|
||||||
*
|
*
|
||||||
|
|
|
@ -541,12 +541,14 @@ Phaser.TilemapLayer.prototype.getTilesX = function (x, y, width, height, collide
|
||||||
* @param {number} width - Width of the area to get.
|
* @param {number} width - Width of the area to get.
|
||||||
* @param {number} height - Height of the area to get.
|
* @param {number} height - Height of the area to get.
|
||||||
* @param {boolean} [collides=false] - If true only return tiles that collide on one or more faces.
|
* @param {boolean} [collides=false] - If true only return tiles that collide on one or more faces.
|
||||||
|
* @param {boolean} [interestingFace=false] - If true only return tiles that have interesting faces.
|
||||||
* @return {array} Array with tiles informations (each contains x, y, and the tile).
|
* @return {array} Array with tiles informations (each contains x, y, and the tile).
|
||||||
*/
|
*/
|
||||||
Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) {
|
Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides, interestingFace) {
|
||||||
|
|
||||||
// Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all)
|
// Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all)
|
||||||
if (typeof collides === 'undefined') { collides = false; }
|
if (typeof collides === 'undefined') { collides = false; }
|
||||||
|
if (typeof interestingFace === 'undefined') { interestingFace = false; }
|
||||||
|
|
||||||
// adjust the x,y coordinates for scrollFactor
|
// adjust the x,y coordinates for scrollFactor
|
||||||
x = this._fixX(x);
|
x = this._fixX(x);
|
||||||
|
@ -577,7 +579,7 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
|
||||||
{
|
{
|
||||||
if (this.layer.data[wy] && this.layer.data[wy][wx])
|
if (this.layer.data[wy] && this.layer.data[wy][wx])
|
||||||
{
|
{
|
||||||
if (collides === false || (collides && this.layer.data[wy][wx].canCollide))
|
if ((!collides && !interestingFace) || this.layer.data[wy][wx].isInteresting(collides, interestingFace))
|
||||||
{
|
{
|
||||||
this._results.push(this.layer.data[wy][wx]);
|
this._results.push(this.layer.data[wy][wx]);
|
||||||
}
|
}
|
||||||
|
@ -585,9 +587,6 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG ONLY - REMOVE
|
|
||||||
this.layer.dirty = true;
|
|
||||||
|
|
||||||
return this._results;
|
return this._results;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue