Skip to content

Commit 498725c

Browse files
committed
Moved the collision out into separateX and separateY
1 parent ce15235 commit 498725c

8 files changed

Lines changed: 503 additions & 234 deletions

File tree

Phaser/core/Vec2.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,20 @@ module Phaser {
203203

204204
}
205205

206+
/**
207+
* Multiply this vector by the given scalar.
208+
*
209+
* @param {number} scalar
210+
* @return {Vec2} This for chaining.
211+
*/
212+
public multiplyByScalar(scalar: number): Vec2 {
213+
214+
this.x *= scalar;
215+
this.y *= scalar;
216+
return this;
217+
218+
}
219+
206220
/**
207221
* Divide this vector by the given scalar.
208222
*

Phaser/physics/PhysicsManager.ts

Lines changed: 165 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ module Phaser.Physics {
2323

2424
this.bounds = new Rectangle(0, 0, width, height);
2525

26+
this._distance = new Vec2;
27+
this._tangent = new Vec2;
28+
2629
this._objects = [];
2730

2831
}
@@ -39,6 +42,8 @@ module Phaser.Physics {
3942
private _delta: number;
4043
private _velocityDelta: number;
4144
private _length: number = 0;
45+
private _distance: Vec2;
46+
private _tangent: Vec2;
4247

4348
public bounds: Rectangle;
4449

@@ -158,126 +163,215 @@ module Phaser.Physics {
158163

159164
}
160165

161-
private collideWorld(obj:IPhysicsShape) {
166+
private collideWorld(shape:IPhysicsShape) {
162167

163168
// Collide on the x-axis
164-
var dx: number = obj.world.bounds.x - (obj.position.x - obj.bounds.halfWidth);
169+
this._distance.x = shape.world.bounds.x - (shape.position.x - shape.bounds.halfWidth);
165170

166-
if (0 < dx)
171+
if (0 < this._distance.x)
167172
{
168173
// Hit Left
169-
obj.oH = 1;
170-
obj.position.x += dx;
174+
this._tangent.setTo(1, 0);
175+
this.separateX(shape, this._distance, this._tangent);
176+
}
177+
else
178+
{
179+
this._distance.x = (shape.position.x + shape.bounds.halfWidth) - shape.world.bounds.right;
171180

172-
if (obj.sprite.physics.bounce.x > 0)
181+
if (0 < this._distance.x)
173182
{
174-
obj.sprite.physics.velocity.x *= -(obj.sprite.physics.bounce.x);
183+
// Hit Right
184+
this._tangent.setTo(-1, 0);
185+
this._distance.reverse();
186+
this.separateX(shape, this._distance, this._tangent);
175187
}
176-
else
188+
}
189+
190+
// Collide on the y-axis
191+
this._distance.y = shape.world.bounds.y - (shape.position.y - shape.bounds.halfHeight);
192+
193+
if (0 < this._distance.y)
194+
{
195+
// Hit Top
196+
this._tangent.setTo(0, 1);
197+
this.separateY(shape, this._distance, this._tangent);
198+
}
199+
else
200+
{
201+
this._distance.y = (shape.position.y + shape.bounds.halfHeight) - shape.world.bounds.bottom;
202+
203+
if (0 < this._distance.y)
177204
{
178-
obj.sprite.physics.velocity.x = 0;
205+
// Hit Bottom
206+
this._tangent.setTo(0, -1);
207+
this._distance.reverse();
208+
this.separateY(shape, this._distance, this._tangent);
179209
}
180210
}
211+
212+
}
213+
214+
/*
215+
private OLDButWorkingcollideWorld(obj:IPhysicsShape) {
216+
217+
this._distance.setTo(0, 0);
218+
219+
// Collide on the x-axis
220+
this._distance.x = obj.world.bounds.x - (obj.position.x - obj.bounds.halfWidth);
221+
222+
if (0 < this._distance.x)
223+
{
224+
// Hit Left
225+
// Parameter order: px, py (distance), dx, dy (tangent)
226+
this._tangent.setTo(1, 0);
227+
this.separate(obj, this._distance, this._tangent);
228+
}
181229
else
182230
{
183-
dx = (obj.position.x + obj.bounds.halfWidth) - obj.world.bounds.right;
231+
this._distance.x = (obj.position.x + obj.bounds.halfWidth) - obj.world.bounds.right;
184232
185-
if (0 < dx)
233+
if (0 < this._distance.x)
186234
{
187235
// Hit Right
188-
obj.oH = -1;
189-
obj.position.x -= dx;
190-
191-
if (obj.sprite.physics.bounce.x > 0)
192-
{
193-
obj.sprite.physics.velocity.x *= -(obj.sprite.physics.bounce.x);
194-
}
195-
else
196-
{
197-
obj.sprite.physics.velocity.x = 0;
198-
}
236+
// Parameter order: px, py (distance), dx, dy (tangent)
237+
this._tangent.setTo(-1, 0);
238+
this._distance.x = -this._distance.x;
239+
this.separate(obj, this._distance, this._tangent);
199240
}
200241
}
201242
202243
// Collide on the y-axis
203-
var dy: number = obj.world.bounds.y - (obj.position.y - obj.bounds.halfHeight);
244+
this._distance.x = 0;
245+
this._distance.y = obj.world.bounds.y - (obj.position.y - obj.bounds.halfHeight);
204246
205-
if (0 < dy)
247+
if (0 < this._distance.y)
206248
{
207249
// Hit Top
208-
obj.oV = 1;
209-
obj.position.y += dy;
250+
this._tangent.setTo(0, 1);
251+
this.separate(obj, this._distance, this._tangent);
252+
}
253+
else
254+
{
255+
this._distance.y = (obj.position.y + obj.bounds.halfHeight) - obj.world.bounds.bottom;
210256
211-
if (obj.sprite.physics.bounce.y > 0)
257+
if (0 < this._distance.y)
212258
{
213-
obj.sprite.physics.velocity.y *= -(obj.sprite.physics.bounce.y);
259+
// Hit Bottom
260+
this._tangent.setTo(0, -1);
261+
this._distance.y = -this._distance.y;
262+
this.separate(obj, this._distance, this._tangent);
263+
}
264+
}
265+
266+
}
267+
*/
268+
269+
private separateX(shape: IPhysicsShape, distance: Vec2, tangent: Vec2) {
270+
271+
// collision edges
272+
shape.oH = tangent.x;
273+
274+
// only apply collision response forces if the object is travelling into, and not out of, the collision
275+
if (Vec2Utils.dot(shape.physics.velocity, tangent) < 0)
276+
{
277+
// Apply horizontal bounce
278+
if (shape.physics.bounce.x > 0)
279+
{
280+
shape.physics.velocity.x *= -(shape.physics.bounce.x);
214281
}
215282
else
216283
{
217-
obj.sprite.physics.velocity.y = 0;
284+
shape.physics.velocity.x = 0;
218285
}
219286
}
220-
else
221-
{
222-
dy = (obj.position.y + obj.bounds.halfHeight) - obj.world.bounds.bottom;
223287

224-
if (0 < dy)
225-
{
226-
// Hit Bottom
227-
obj.oV = -1;
228-
obj.position.y -= dy;
288+
shape.position.x += distance.x;
229289

230-
if (obj.sprite.physics.bounce.y > 0)
231-
{
232-
obj.sprite.physics.velocity.y *= -(obj.sprite.physics.bounce.y);
233-
}
234-
else
235-
{
236-
obj.sprite.physics.velocity.y = 0;
237-
}
290+
}
291+
292+
private separateY(shape: IPhysicsShape, distance: Vec2, tangent: Vec2) {
293+
294+
// collision edges
295+
shape.oV = tangent.y;
296+
297+
// only apply collision response forces if the object is travelling into, and not out of, the collision
298+
if (Vec2Utils.dot(shape.physics.velocity, tangent) < 0)
299+
{
300+
// Apply horizontal bounce
301+
if (shape.physics.bounce.y > 0)
302+
{
303+
shape.physics.velocity.y *= -(shape.physics.bounce.y);
304+
}
305+
else
306+
{
307+
shape.physics.velocity.y = 0;
238308
}
239309
}
240310

311+
shape.position.y += distance.y;
312+
241313
}
242314

243-
/*
244-
private processWorld(px, py, dx, dy, tile) {
315+
private separate(shape:IPhysicsShape, distance: Vec2, tangent: Vec2) {
316+
317+
// collision edges
318+
shape.oH = tangent.x;
319+
shape.oV = tangent.y;
320+
321+
// Velocity (move to temp vars)
245322

246-
// Velocity
247-
//this.sprite.physics.velocity.x = this.position.x - this.oldPosition.x;
248-
//this.sprite.physics.velocity.y = this.position.y - this.oldPosition.y;
323+
// was vx/vy
324+
var velocity: Vec2 = Vec2Utils.subtract(shape.position, shape.oldPosition);
249325

250-
// Optimise!!!
251-
var dp: number = (this.sprite.physics.velocity.x * dx + this.sprite.physics.velocity.y * dy);
252-
var nx: number = dp * dx;
253-
var ny: number = dp * dy;
254-
var tx: number = this.sprite.physics.velocity.x - nx;
255-
var ty: number = this.sprite.physics.velocity.y - ny;
326+
// was dp
327+
var dot: number = Vec2Utils.dot(shape.physics.velocity, tangent);
256328

257-
var bx, by, fx, fy;
329+
// project velocity onto the collision normal
330+
// was nx/ny
331+
tangent.multiplyByScalar(dot);
258332

259-
if (dp < 0)
333+
// was tx/ty (tangent velocity?)
334+
var tangentVelocity: Vec2 = Vec2Utils.subtract(velocity, tangent);
335+
336+
// only apply collision response forces if the object is travelling into, and not out of, the collision
337+
if (dot < 0)
260338
{
261-
fx = tx * this.sprite.physics.friction.x;
262-
fy = ty * this.sprite.physics.friction.y;
263-
bx = (nx * (1 + this.sprite.physics.bounce.x));
264-
by = (ny * (1 + this.sprite.physics.bounce.y));
265-
//this.sprite.physics.velocity.x = bx;
266-
//this.sprite.physics.velocity.y = by;
339+
// Apply horizontal bounce
340+
if (distance.x != 0)
341+
{
342+
if (shape.physics.bounce.x > 0)
343+
{
344+
shape.physics.velocity.x *= -(shape.physics.bounce.x);
345+
}
346+
else
347+
{
348+
shape.physics.velocity.x = 0;
349+
}
350+
}
351+
352+
// Apply vertical bounce
353+
if (distance.y != 0)
354+
{
355+
if (shape.physics.bounce.y > 0)
356+
{
357+
shape.physics.velocity.y *= -(shape.physics.bounce.y);
358+
}
359+
else
360+
{
361+
shape.physics.velocity.y = 0;
362+
}
363+
}
267364
}
268365
else
269366
{
270-
bx = by = fx = fy = 0;
367+
// moving out of collision
271368
}
272369

273-
this.position.x += px;
274-
this.position.y += py;
275-
276-
this.oldPosition.x += px + bx + fx;
277-
this.oldPosition.y += py + by + fy;
370+
// project object out of collision
371+
//console.log('proj out', distance.x, distance.y,'dot',dot);
372+
shape.position.add(distance);
278373

279374
}
280-
*/
281375

282376
}
283377

0 commit comments

Comments
 (0)