Skip to content

Commit 5297497

Browse files
committed
Tilemap collision finally getting closer.
1 parent e955145 commit 5297497

5 files changed

Lines changed: 183 additions & 46 deletions

File tree

examples/wip/tilemap new 1.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ function create() {
3636
game.camera.follow(sprite);
3737

3838
// game.physics.arcade.gravity.y = 500;
39-
// sprite.body.velocity.x = 100;
4039

4140
cursors = game.input.keyboard.createCursorKeys();
4241

@@ -51,27 +50,32 @@ function update() {
5150

5251
if (cursors.up.isDown)
5352
{
54-
sprite.body.velocity.y = -100;
53+
sprite.body.velocity.y = -200;
5554
}
5655
else if (cursors.down.isDown)
5756
{
58-
sprite.body.velocity.y = 100;
57+
sprite.body.velocity.y = 200;
5958
}
6059

6160
if (cursors.left.isDown)
6261
{
63-
sprite.body.velocity.x = -100;
62+
sprite.body.velocity.x = -200;
6463
}
6564
else if (cursors.right.isDown)
6665
{
67-
sprite.body.velocity.x = 100;
66+
sprite.body.velocity.x = 200;
6867
}
6968

7069
}
7170

7271
function render() {
7372

74-
game.debug.text(sprite.body.velocity.x, 32, 32);
75-
game.debug.text(sprite.body.velocity.y, 64, 32);
73+
// game.debug.text(sprite.body.deltaAbsX(), 32, 32);
74+
// game.debug.text(sprite.body.deltaAbsY(), 32, 64);
75+
76+
// game.debug.text(sprite.body.deltaX(), 400, 32);
77+
// game.debug.text(sprite.body.deltaY(), 400, 64);
78+
79+
game.debug.body(sprite);
7680

7781
}

src/physics/arcade/Body.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,12 +632,12 @@ Phaser.Physics.Arcade.Body.render = function (context, body, filled, color) {
632632
if (filled)
633633
{
634634
context.fillStyle = color;
635-
context.fillRect(body.x - body.game.camera.x, body.y - body.game.camera.y, body.width, body.height);
635+
context.fillRect(body.position.x - body.game.camera.x, body.position.y - body.game.camera.y, body.width, body.height);
636636
}
637637
else
638638
{
639639
context.strokeStyle = color;
640-
context.strokeRect(body.x - body.game.camera.x, body.y - body.game.camera.y, body.width, body.height);
640+
context.strokeRect(body.position.x - body.game.camera.x, body.position.y - body.game.camera.y, body.width, body.height);
641641
}
642642

643643
}

src/physics/arcade/World.js

Lines changed: 136 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,8 @@ Phaser.Physics.Arcade.prototype = {
606606
*/
607607
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
608608

609-
this._mapData = tilemapLayer.getIntersectingTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, sprite.body.right, sprite.body.bottom);
609+
// this._mapData = tilemapLayer.getIntersectingTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, sprite.body.right, sprite.body.bottom);
610+
this._mapData = tilemapLayer.getTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, false, true);
610611

611612
if (this._mapData.length === 0)
612613
{
@@ -616,6 +617,8 @@ Phaser.Physics.Arcade.prototype = {
616617
for (var i = 0; i < this._mapData.length; i++)
617618
{
618619
// console.log('-------------------------------------- tile', this._mapData[i].faceLeft, this._mapData[i].faceRight, this._mapData[i].faceTop, this._mapData[i].faceBottom);
620+
// console.log('-------------------------------------- tile', i, 'of', this._mapData.length, 'xy', this._mapData[i].x, this._mapData[i].y);
621+
619622
if (this.separateTile(i, sprite.body, this._mapData[i]))
620623
{
621624
// They collided, is there a custom process callback?
@@ -743,7 +746,9 @@ Phaser.Physics.Arcade.prototype = {
743746
}
744747
else
745748
{
749+
body1.touching.none = false;
746750
body1.touching.right = true;
751+
body2.touching.none = false;
747752
body2.touching.left = true;
748753
}
749754
}
@@ -758,7 +763,9 @@ Phaser.Physics.Arcade.prototype = {
758763
}
759764
else
760765
{
766+
body1.touching.none = false;
761767
body1.touching.left = true;
768+
body2.touching.none = false;
762769
body2.touching.right = true;
763770
}
764771
}
@@ -852,7 +859,9 @@ Phaser.Physics.Arcade.prototype = {
852859
}
853860
else
854861
{
862+
body1.touching.none = false;
855863
body1.touching.down = true;
864+
body2.touching.none = false;
856865
body2.touching.up = true;
857866
}
858867
}
@@ -867,7 +876,9 @@ Phaser.Physics.Arcade.prototype = {
867876
}
868877
else
869878
{
879+
body1.touching.none = false;
870880
body1.touching.up = true;
881+
body2.touching.none = false;
871882
body2.touching.down = true;
872883
}
873884
}
@@ -1023,8 +1034,8 @@ Phaser.Physics.Arcade.prototype = {
10231034
*/
10241035
separateTile: function (i, body, tile) {
10251036

1026-
// we re-check for collision in case body was separated in a previous step
1027-
if (i > 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
1037+
// We re-check for collision in case body was separated in a previous step
1038+
if (!tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
10281039
{
10291040
// no collision so bail out (separted in a previous step)
10301041
return false;
@@ -1048,64 +1059,157 @@ Phaser.Physics.Arcade.prototype = {
10481059

10491060
var ox = 0;
10501061
var oy = 0;
1062+
var minX = 0;
1063+
var minY = 1;
1064+
1065+
if (body.deltaAbsX() > body.deltaAbsY())
1066+
{
1067+
// Moving faster horizontally, check X axis first
1068+
minX = -1;
1069+
}
1070+
else if (body.deltaAbsX() < body.deltaAbsY())
1071+
{
1072+
// Moving faster vertically, check Y axis first
1073+
minY = -1;
1074+
}
10511075

1052-
if (tile.faceLeft || tile.faceRight)
1076+
if (body.deltaX() !== 0 && body.deltaY() !== 0 && (tile.faceLeft || tile.faceRight) && (tile.faceTop || tile.faceBottom))
10531077
{
1054-
if (body.deltaX() < 0 && !body.blocked.left && tile.collideRight && body.checkCollision.left)
1078+
// We only need do this if both axis have checking faces AND we're moving in both directions
1079+
minX = Math.min(Math.abs(body.position.x - tile.right), Math.abs(body.right - tile.left));
1080+
minY = Math.min(Math.abs(body.position.y - tile.bottom), Math.abs(body.bottom - tile.top));
1081+
1082+
// console.log('checking faces', minX, minY);
1083+
1084+
// var distLeft = Math.abs(body.position.x - tile.right);
1085+
// var distRight = Math.abs(body.right - tile.left);
1086+
// var distTop = Math.abs(body.position.y - tile.bottom);
1087+
// var distBottom = Math.abs(body.bottom - tile.top);
1088+
// minX = Math.min(distLeft, distRight);
1089+
// minY = Math.min(distTop, distBottom);
1090+
// console.log('dist left', distLeft, 'right', distRight, 'top', distTop, 'bottom', distBottom, 'minX', minX, 'minY', minY);
1091+
// console.log('tile lr', tile.left, tile.right, 'tb', tile.top, tile.bottom);
1092+
// console.log('body lr', body.x, body.right, 'tb', body.y, body.bottom);
1093+
}
1094+
1095+
if (minX < minY)
1096+
{
1097+
if (tile.faceLeft || tile.faceRight)
10551098
{
1056-
// Body is moving LEFT
1057-
if (tile.faceRight && body.x < tile.right)
1099+
ox = this.tileCheckX(body, tile);
1100+
1101+
// That's horizontal done, check if we still intersects? If not then we can return now
1102+
if (ox !== 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
10581103
{
1059-
ox = body.x - tile.right;
1104+
return true;
10601105
}
10611106
}
1062-
else if (body.deltaX() > 0 && !body.blocked.right && tile.collideLeft && body.checkCollision.right)
1107+
1108+
if (tile.faceTop || tile.faceBottom)
1109+
{
1110+
oy = this.tileCheckY(body, tile);
1111+
}
1112+
}
1113+
else
1114+
{
1115+
if (tile.faceTop || tile.faceBottom)
10631116
{
1064-
// Body is moving RIGHT
1065-
if (tile.faceLeft && body.right > tile.left)
1117+
oy = this.tileCheckY(body, tile);
1118+
1119+
// That's vertical done, check if we still intersects? If not then we can return now
1120+
if (oy !== 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
10661121
{
1067-
ox = body.right - tile.left;
1122+
return true;
10681123
}
10691124
}
1070-
1071-
if (ox !== 0)
1125+
1126+
if (tile.faceLeft || tile.faceRight)
10721127
{
1073-
this.processTileSeparationX(body, ox);
1128+
ox = this.tileCheckX(body, tile);
10741129
}
1130+
}
1131+
1132+
return (ox !== 0 || oy !== 0);
1133+
1134+
},
1135+
1136+
tileCheckX: function (body, tile) {
1137+
1138+
var ox = 0;
10751139

1076-
// That's horizontal done, check if we still intersects? If not then we can return now
1077-
if (!tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
1140+
if (body.deltaX() < 0 && !body.blocked.left && tile.collideRight && body.checkCollision.left)
1141+
{
1142+
// Body is moving LEFT
1143+
if (tile.faceRight && body.x < tile.right)
10781144
{
1079-
return (ox !== 0);
1145+
ox = body.x - tile.right;
1146+
1147+
if (ox < -this.OVERLAP_BIAS)
1148+
{
1149+
ox = 0;
1150+
}
10801151
}
10811152
}
1082-
1083-
if (tile.faceTop || tile.faceBottom)
1153+
else if (body.deltaX() > 0 && !body.blocked.right && tile.collideLeft && body.checkCollision.right)
10841154
{
1085-
if (body.deltaY() < 0 && !body.blocked.up && tile.collideDown && body.checkCollision.up)
1155+
// Body is moving RIGHT
1156+
if (tile.faceLeft && body.right > tile.left)
10861157
{
1087-
// Body is moving UP
1088-
if (tile.faceBottom && body.y < tile.bottom)
1158+
ox = body.right - tile.left;
1159+
1160+
if (ox > this.OVERLAP_BIAS)
10891161
{
1090-
oy = body.y - tile.bottom;
1162+
ox = 0;
10911163
}
10921164
}
1093-
else if (body.deltaY() > 0 && !body.blocked.down && tile.collideUp && body.checkCollision.down)
1165+
}
1166+
1167+
if (ox !== 0)
1168+
{
1169+
this.processTileSeparationX(body, ox);
1170+
}
1171+
1172+
return ox;
1173+
1174+
},
1175+
1176+
tileCheckY: function (body, tile) {
1177+
1178+
var oy = 0;
1179+
1180+
if (body.deltaY() < 0 && !body.blocked.up && tile.collideDown && body.checkCollision.up)
1181+
{
1182+
// Body is moving UP
1183+
if (tile.faceBottom && body.y < tile.bottom)
10941184
{
1095-
// Body is moving DOWN
1096-
if (tile.faceTop && body.bottom > tile.top)
1185+
oy = body.y - tile.bottom;
1186+
1187+
if (oy < -this.OVERLAP_BIAS)
10971188
{
1098-
oy = body.bottom - tile.top;
1189+
oy = 0;
10991190
}
11001191
}
1101-
1102-
if (oy !== 0)
1192+
}
1193+
else if (body.deltaY() > 0 && !body.blocked.down && tile.collideUp && body.checkCollision.down)
1194+
{
1195+
// Body is moving DOWN
1196+
if (tile.faceTop && body.bottom > tile.top)
11031197
{
1104-
this.processTileSeparationY(body, oy);
1198+
oy = body.bottom - tile.top;
1199+
1200+
if (oy > this.OVERLAP_BIAS)
1201+
{
1202+
oy = 0;
1203+
}
11051204
}
11061205
}
11071206

1108-
return (ox !== 0 || oy !== 0);
1207+
if (oy !== 0)
1208+
{
1209+
this.processTileSeparationY(body, oy);
1210+
}
1211+
1212+
return oy;
11091213

11101214
},
11111215

src/tilemap/Tile.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,36 @@ Phaser.Tile.prototype = {
244244

245245
},
246246

247+
/**
248+
* Is this tile interesting?
249+
*
250+
* @method Phaser.Tile#isInteresting
251+
* @param {boolean} collides - If true will check any collides value.
252+
* @param {boolean} faces - If true will check any face value.
253+
* @return {boolean} True if the Tile is interesting, otherwise false.
254+
*/
255+
isInteresting: function (collides, faces) {
256+
257+
if (collides && faces)
258+
{
259+
// Does this tile EITHER collide OR have an interesting face?
260+
return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown || this.faceTop || this.faceBottom || this.faceLeft || this.faceRight);
261+
}
262+
else if (collides)
263+
{
264+
// Does this tile collide?
265+
return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown);
266+
}
267+
else if (faces)
268+
{
269+
// Does this tile have an interesting face?
270+
return (this.faceTop || this.faceBottom || this.faceLeft || this.faceRight);
271+
}
272+
273+
return false;
274+
275+
},
276+
247277
/**
248278
* Copies the tile data and properties from the given tile to this tile.
249279
*

src/tilemap/TilemapLayer.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -541,12 +541,14 @@ Phaser.TilemapLayer.prototype.getTilesX = function (x, y, width, height, collide
541541
* @param {number} width - Width of the area to get.
542542
* @param {number} height - Height of the area to get.
543543
* @param {boolean} [collides=false] - If true only return tiles that collide on one or more faces.
544+
* @param {boolean} [interestingFace=false] - If true only return tiles that have interesting faces.
544545
* @return {array} Array with tiles informations (each contains x, y, and the tile).
545546
*/
546-
Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) {
547+
Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides, interestingFace) {
547548

548549
// Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all)
549550
if (typeof collides === 'undefined') { collides = false; }
551+
if (typeof interestingFace === 'undefined') { interestingFace = false; }
550552

551553
// adjust the x,y coordinates for scrollFactor
552554
x = this._fixX(x);
@@ -577,17 +579,14 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
577579
{
578580
if (this.layer.data[wy] && this.layer.data[wy][wx])
579581
{
580-
if (collides === false || (collides && this.layer.data[wy][wx].canCollide))
582+
if ((!collides && !interestingFace) || this.layer.data[wy][wx].isInteresting(collides, interestingFace))
581583
{
582584
this._results.push(this.layer.data[wy][wx]);
583585
}
584586
}
585587
}
586588
}
587589

588-
// DEBUG ONLY - REMOVE
589-
this.layer.dirty = true;
590-
591590
return this._results;
592591

593592
}

0 commit comments

Comments
 (0)