@@ -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