Path: chuka.playstation.co.uk!tjs From: tjs@cs.monash.edu.au (Toby Sargeant) Newsgroups: scee.yaroze.programming.2d_graphics Subject: Re: What to do after a collision has been detected (related to previous post) Date: 7 Sep 1998 23:28:18 GMT Organization: PlayStation Net Yaroze (SCEE) Lines: 60 Message-ID: References: <35F3E1A4.8A7BB2E6@easynet.co.uk> NNTP-Posting-Host: longford.cs.monash.edu.au X-Newsreader: slrn (0.9.4.3 UNIX) On Mon, 07 Sep 1998 14:37:40 +0100, Phil Gooch wrote: >OK, so I've detected a collision of a sprite with the terrain of my >'road'. What I have done is put all the allowable 'squares' you can be >on into one texture page (identified as ROAD) and everything else >(trees, grass, roadside edge etc) into another texture page (identified >as ROADSIDE). My array data contains info for which texture page the >square is read from so I can do (pseudo-code) > >if ( (mapData[car.mapY][car.mapX] & TPAGE_ID) == ROADSIDE) > // the car is on a square from the ROADSIDE texture page, so you >have collided with something > // bounce car off it > car.veloc.x = -car.veloc.x; > car.veloc.y = -car.veloc.y; > What about doing the colision speculatively? Here's what I'd do: * calculate new car position from velocity vector * if new car position causes a colision: * use reflection rule (angle of incidence = angle of reflection) to calculate a new velocity vector. * apply new velocity vector to position of car to get new position * if new position also causes a colision: * must be stuck in a corner. because the position we came from to get to the curent position must be valid, it must be valid to use the inverse velocity vector to get back to the position we were in the frame before last. so: new velocity vector = -old velocity vector * update car position from the velocity vector (guaranteed not to cause a collision) It's better not to just reverse the velocity vector on any collision. There was a buglet in W'O" 2097 which meant that at some positions on the (first) track, running into the wall would calculate the new velocity vector based on an incorrect surface normal, and the result would be that instead of scraping along the edge like you should have (because the incidence vector was so close to 90 degrees to the normal that the reflection vector was essentially the same), you were brought to a complete standstill. Also, remember that if you're doing a real(ish) physical model, some of the kinetic energy that the car posesses is liberated as sound, heat, etc. in a collision, so the speed upon rebound is cut by quite a bit (depending on the materials of the colliding objects). This can be modelled reasonably accurately just by reducing the speed by a constant factor upon collision. An arbitrary angle of reflection can be calculated really easily by: r=i-2(i.n)n Where i and n are incidence and normal unit vectors, and r is the reflection unit vector (. is the dot product). In case you can't remember the dot product formula (and I have to derive it or look it up, far too often), it's: A.B = Ax*Bx + Ay*By Toby.