Skip to content

Commit 052b9a7

Browse files
committed
Separated the Tilemap specific code from World.
1 parent fa7fee9 commit 052b9a7

2 files changed

Lines changed: 307 additions & 284 deletions

File tree

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2014 Photon Storm Ltd.
4+
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
5+
*/
6+
7+
Phaser.Physics.Arcade.TilemapCollision = function () {
8+
9+
};
10+
11+
/**
12+
* The Arcade Physics tilemap collision methods.
13+
*
14+
* @class Phaser.Physics.Arcade.TilemapCollision
15+
* @constructor
16+
* @param {Phaser.Game} game - reference to the current game instance.
17+
*/
18+
Phaser.Physics.Arcade.TilemapCollision.prototype = {
19+
20+
/**
21+
* @property {number} TILE_BIAS - A value added to the delta values during collision with tiles. Adjust this if you get tunneling.
22+
*/
23+
TILE_BIAS: 16,
24+
25+
/**
26+
* The core separation function to separate a physics body and a tile.
27+
*
28+
* @private
29+
* @method Phaser.Physics.Arcade#separateTile
30+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
31+
* @param {Phaser.Tile} tile - The tile to collide against.
32+
* @return {boolean} Returns true if the body was separated, otherwise false.
33+
*/
34+
separateTile: function (i, body, tile) {
35+
36+
// We re-check for collision in case body was separated in a previous step
37+
if (!body.enable || !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
38+
{
39+
// no collision so bail out (separated in a previous step)
40+
return false;
41+
}
42+
43+
// They overlap. Any custom callbacks?
44+
45+
// A local callback always takes priority over a layer level callback
46+
if (tile.collisionCallback && !tile.collisionCallback.call(tile.collisionCallbackContext, body.sprite, tile))
47+
{
48+
// If it returns true then we can carry on, otherwise we should abort.
49+
return false;
50+
}
51+
else if (tile.layer.callbacks[tile.index] && !tile.layer.callbacks[tile.index].callback.call(tile.layer.callbacks[tile.index].callbackContext, body.sprite, tile))
52+
{
53+
// If it returns true then we can carry on, otherwise we should abort.
54+
return false;
55+
}
56+
57+
// We don't need to go any further if this tile doesn't actually separate
58+
if (!tile.faceLeft && !tile.faceRight && !tile.faceTop && !tile.faceBottom)
59+
{
60+
// This could happen if the tile was meant to be collided with re: a callback, but otherwise isn't needed for separation
61+
return false;
62+
}
63+
64+
var ox = 0;
65+
var oy = 0;
66+
var minX = 0;
67+
var minY = 1;
68+
69+
if (body.deltaAbsX() > body.deltaAbsY())
70+
{
71+
// Moving faster horizontally, check X axis first
72+
minX = -1;
73+
}
74+
else if (body.deltaAbsX() < body.deltaAbsY())
75+
{
76+
// Moving faster vertically, check Y axis first
77+
minY = -1;
78+
}
79+
80+
if (body.deltaX() !== 0 && body.deltaY() !== 0 && (tile.faceLeft || tile.faceRight) && (tile.faceTop || tile.faceBottom))
81+
{
82+
// We only need do this if both axis have checking faces AND we're moving in both directions
83+
minX = Math.min(Math.abs(body.position.x - tile.right), Math.abs(body.right - tile.left));
84+
minY = Math.min(Math.abs(body.position.y - tile.bottom), Math.abs(body.bottom - tile.top));
85+
}
86+
87+
if (minX < minY)
88+
{
89+
if (tile.faceLeft || tile.faceRight)
90+
{
91+
ox = this.tileCheckX(body, tile);
92+
93+
// That's horizontal done, check if we still intersects? If not then we can return now
94+
if (ox !== 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
95+
{
96+
return true;
97+
}
98+
}
99+
100+
if (tile.faceTop || tile.faceBottom)
101+
{
102+
oy = this.tileCheckY(body, tile);
103+
}
104+
}
105+
else
106+
{
107+
if (tile.faceTop || tile.faceBottom)
108+
{
109+
oy = this.tileCheckY(body, tile);
110+
111+
// That's vertical done, check if we still intersects? If not then we can return now
112+
if (oy !== 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
113+
{
114+
return true;
115+
}
116+
}
117+
118+
if (tile.faceLeft || tile.faceRight)
119+
{
120+
ox = this.tileCheckX(body, tile);
121+
}
122+
}
123+
124+
return (ox !== 0 || oy !== 0);
125+
126+
},
127+
128+
/**
129+
* Check the body against the given tile on the X axis.
130+
*
131+
* @private
132+
* @method Phaser.Physics.Arcade#tileCheckX
133+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
134+
* @param {Phaser.Tile} tile - The tile to check.
135+
* @return {number} The amount of separation that occurred.
136+
*/
137+
tileCheckX: function (body, tile) {
138+
139+
var ox = 0;
140+
141+
if (body.deltaX() < 0 && !body.blocked.left && tile.collideRight && body.checkCollision.left)
142+
{
143+
// Body is moving LEFT
144+
if (tile.faceRight && body.x < tile.right)
145+
{
146+
ox = body.x - tile.right;
147+
148+
if (ox < -this.TILE_BIAS)
149+
{
150+
ox = 0;
151+
}
152+
}
153+
}
154+
else if (body.deltaX() > 0 && !body.blocked.right && tile.collideLeft && body.checkCollision.right)
155+
{
156+
// Body is moving RIGHT
157+
if (tile.faceLeft && body.right > tile.left)
158+
{
159+
ox = body.right - tile.left;
160+
161+
if (ox > this.TILE_BIAS)
162+
{
163+
ox = 0;
164+
}
165+
}
166+
}
167+
168+
if (ox !== 0)
169+
{
170+
if (body.customSeparateX)
171+
{
172+
body.overlapX = ox;
173+
}
174+
else
175+
{
176+
this.processTileSeparationX(body, ox);
177+
}
178+
}
179+
180+
return ox;
181+
182+
},
183+
184+
/**
185+
* Check the body against the given tile on the Y axis.
186+
*
187+
* @private
188+
* @method Phaser.Physics.Arcade#tileCheckY
189+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
190+
* @param {Phaser.Tile} tile - The tile to check.
191+
* @return {number} The amount of separation that occurred.
192+
*/
193+
tileCheckY: function (body, tile) {
194+
195+
var oy = 0;
196+
197+
if (body.deltaY() < 0 && !body.blocked.up && tile.collideDown && body.checkCollision.up)
198+
{
199+
// Body is moving UP
200+
if (tile.faceBottom && body.y < tile.bottom)
201+
{
202+
oy = body.y - tile.bottom;
203+
204+
if (oy < -this.TILE_BIAS)
205+
{
206+
oy = 0;
207+
}
208+
}
209+
}
210+
else if (body.deltaY() > 0 && !body.blocked.down && tile.collideUp && body.checkCollision.down)
211+
{
212+
// Body is moving DOWN
213+
if (tile.faceTop && body.bottom > tile.top)
214+
{
215+
oy = body.bottom - tile.top;
216+
217+
if (oy > this.TILE_BIAS)
218+
{
219+
oy = 0;
220+
}
221+
}
222+
}
223+
224+
if (oy !== 0)
225+
{
226+
if (body.customSeparateY)
227+
{
228+
body.overlapY = oy;
229+
}
230+
else
231+
{
232+
this.processTileSeparationY(body, oy);
233+
}
234+
}
235+
236+
return oy;
237+
238+
},
239+
240+
/**
241+
* Internal function to process the separation of a physics body from a tile.
242+
*
243+
* @private
244+
* @method Phaser.Physics.Arcade#processTileSeparationX
245+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
246+
* @param {number} x - The x separation amount.
247+
*/
248+
processTileSeparationX: function (body, x) {
249+
250+
if (x < 0)
251+
{
252+
body.blocked.left = true;
253+
}
254+
else if (x > 0)
255+
{
256+
body.blocked.right = true;
257+
}
258+
259+
body.position.x -= x;
260+
261+
if (body.bounce.x === 0)
262+
{
263+
body.velocity.x = 0;
264+
}
265+
else
266+
{
267+
body.velocity.x = -body.velocity.x * body.bounce.x;
268+
}
269+
270+
},
271+
272+
/**
273+
* Internal function to process the separation of a physics body from a tile.
274+
*
275+
* @private
276+
* @method Phaser.Physics.Arcade#processTileSeparationY
277+
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
278+
* @param {number} y - The y separation amount.
279+
*/
280+
processTileSeparationY: function (body, y) {
281+
282+
if (y < 0)
283+
{
284+
body.blocked.up = true;
285+
}
286+
else if (y > 0)
287+
{
288+
body.blocked.down = true;
289+
}
290+
291+
body.position.y -= y;
292+
293+
if (body.bounce.y === 0)
294+
{
295+
body.velocity.y = 0;
296+
}
297+
else
298+
{
299+
body.velocity.y = -body.velocity.y * body.bounce.y;
300+
}
301+
302+
}
303+
304+
};
305+
306+
// Merge this with the Arcade Physics prototype
307+
Phaser.Utils.mixinPrototype(Phaser.Physics.Arcade.prototype, Phaser.Physics.Arcade.TilemapCollision.prototype);

0 commit comments

Comments
 (0)