Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Following up on my earlier question about finding the slope of a 2D bitmap terrain I now need to know the best way of finding the point on the 2D terrain that the missile hit. Obviously, I can see if any pixels under the missile intersect terrain, but say it has moved quite deep into the terrain.

What is the best way to step back to find where it initially collided? I could move back X pixels at a time towards the missile's previous position, but what would be a good value of X? And is there a smarter way? Maybe moving half the distance, then a quarter etc?

share|improve this question
    
The phenomenon you're describing is commonly called "tunneling", and the best way to deal with it is to introduce a sweep test - as TetraD and JasonD have both mentioned below. –  jpaver Aug 18 '10 at 21:19
    
just saying "sweep test" doesn't actually help me though. How do I do it with a bitmap terrain? –  Iain Aug 19 '10 at 10:20
    
Jason's suggestion seems to be best to me: one pixel at a time. –  jpaver Aug 19 '10 at 15:51
add comment

4 Answers 4

For collision testing you shouldn't do tick-by-tick static testing, you should be doing traces/sweep tests.

There's an exhaustive list of various formulas for different kinds of primitives here: http://www.realtimerendering.com/intersections.html

That is, of course, assuming you can break down your terrain into some kind of set of primitives you can test against (i.e. line segments). There are various ways of doing that.

See also this question (only slightly related): http://gamedev.stackexchange.com/questions/313/what-is-a-good-algorithm-to-detect-collision-between-moving-spheres

share|improve this answer
    
I was thinking about a destructible bitmaps terrain like in Worms. Could you dynamically generate primitives from a bitmap or would that be too crazy? –  Iain Aug 19 '10 at 8:30
1  
I'm sure you could, but it might be easier/faster just to do pixel by pixel testing for an arbitrary bitmap. –  Tetrad Aug 19 '10 at 16:37
    
WITH A QUADTREE!! (so it doesn't take forever) –  bobobobo Nov 27 '11 at 1:02
add comment

Binary search wont help if you have thin bits of scenery and fast moving projectiles - you might miss them.

I think your best option is to sweep a line across the front of the projectile along the path it takes, pixel at a time. You could do a bounding check first on the whole volume to avoid doing it every step.

share|improve this answer
    
What's binary search? –  Iain Aug 18 '10 at 21:16
1  
Sorry - binary search is more or less what you were talking about in the question. You start in the middle, and divide the search space by two until you converge on the answer. It's optimal in many cases, but in your case it would not work (you might skip the correct answer entirely). –  JasonD Aug 18 '10 at 21:35
add comment

Since the missile is unlikely to move a huge amount of pixels each frame (it wouldn't be smooth on screen) I see no reason to not just check every pixel on the path. Bressenham line algorithm is your friend, and making sure you got a local copy of your bitmap too as you generally don't want to access video memory for every pixel. This is assuming your bitmap terrain is fully random (as per destructable worms terrain). If your world is tile based you could skip every tile that you know is empty to begin with, but as mentioned before, unless you have a huge amount of missiles to check I couldn't think of a platform that would need that is too slow to just test pixel by pixel, and you won't need to have your world defined in primitives (a worms clone would make that tricky)

share|improve this answer
    
yeah I was thinking a Worms-like terrain. Could you divide it in to tiles dynamically, then just mark empty tiles to not be checked? If there were a lot of missiles at once maybe that would speed things up a bit? –  Iain Aug 19 '10 at 8:28
    
So do you think I shoudld move forward pixel by pixel, checking intersection, rather than stepping backwards? –  Iain Aug 19 '10 at 8:49
    
I think all three answers have suggested a forward search. Checking backwards isn't going to work if the forward step makes it skip over some scenery. –  JasonD Aug 19 '10 at 9:07
    
Yes, definitely forwards. –  Kaj Aug 19 '10 at 15:03
add comment

In addition to the other answers, there are some things you can do to speed this up if you want to do a little bookkeeping with regards to "collecting" a bunch of pixels into blocks of "known similar state." E.g. you could store the height of the highest terrain piece, so you can take for granted that the missile won't hit anything as long as it's above that. You could also store the height of the lowest "air" space, so you'll know that if the missile gets to that altitude that it must have hit something (although this might be best used as a sanity check). Going further than this, you could store rectangles representing areas that are all terrain and other rectangles that are all air, but that might be more work than value.

Ultimately, the best method is probably going to be "store off the height of each terrain column" and then just compute the missile height at each step of its path. I can't speak to more modern games, but I believe that when you made a "cave" in Scorched Earth, that the terrain above that cave fell straight down, leaving no overhangs. If you want overhangs the work will be a little greater, but it will be an extension of this basic idea. (Hint: get the basic idea working first!)

Since your terrain is presumably completely arbitrary, there are no shortcuts. Even if you forced your terrain to be a spline or something, that'll get upset once you start destroying it and line-spline intersection tests are iterative and non-perfect or exhaustive and pointlessly slow for your type of problem.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.