+5  A: 

As I recall, in Worms they used two images; The "pretty" terrain with colour, and a mask terrain that is pure black and white. Hit detection is always done on the mask.

If you actually want the terrain to collapse like it did in Tank Wars, you'll need to iterate over each column of your image and have it search for gaps between the terrain and the bottom of the playing field. If any gaps are detected, shift the terrain above the gap down to the lowest point possible in your column.

A simple example of this could be done with an array where 1 represents solid terrain and 0 represents empty space. In this case, I've set up the left side of the array as ground level, to element [0] would be on the ground:

[1,1,1,1,1,1,0,0,0,0]

Lets assume the terrain is struck from the side and a hole is made:

[1,1,0,0,1,1,0,0,0,0]

You're now left with a floating piece of terrain above another piece of terrain. To make the floating terrain collapse, iterate over the array, keeping track of the first position you find a 0 (empty space). Then, as you continue to iterate, upon discovering a 1 (terrain) simply shift the 1 to where the 0 was. Repeat the process by iterating from that the old 0 position + 1.

[1,1,1,0,0,1,0,0,0,0]

[1,1,1,1,0,0,0,0,0,0]

This is the basic approach, not the most efficient one. It would be much faster to move all indexes of terrain above the gap down at the same time, for example.

EDIT:

As the first comment states, a sort on the list is even easier. I'm keeping my original response intact since it helps explains the actual principle behind the collapsing terrain.

Soviut
If in the collapsing terrain the mask only contains terrain (1) and non-terrain (0) bits then he can just use a sort to "do the collapsing" (in this case, a constant time algorithm).
fishlips
+1  A: 

Soviut's answer is great! I use a similar algorithm in the destructive terrain feature in Scorched Earth for iPhone. I decided to stay true to the original and have the terrain settle instantly, but while I was considering having animated terrain settling, I ran into some performance problems. You can see evidence of this in iShoot as well, since iShoot uses a slowly settling animated terrain. There are situations where the ground is still settling from one player's turn when the next player fires a weapon. This can interfere with the shot, and the interference can change depending on how quickly the next player fires. Since Scorched Earth is a turn-based game, it seems like a good idea to have the game wait until the ground is settled until switching to the next player.

To render the terrain, I used OpenGL to draw a polygon with one pair of vertices at each horizontal screen location, like this:

1 3 5 7 9
0 2 4 6 8

Points with even numbers represent the line of pixels at the bottom of the screen. Points with odd numbers represent the vertical pixel location of the terrain. This information is copied into a point array, which is rendered with glVertexPointer, glColorPointer, and glDrawArrays, as a triangle strip, like this:

// prepare vertex buffer
for (int i=0,j,k=0,K=480;k<=K;k++) {
    j = (k-(int)offsetX+480)%480;
    vGroundLevel[i++] = k;
    vGroundLevel[i++] = offsetY>0 ? 0 : offsetY;
    vGroundLevel[i++] = k;
    vGroundLevel[i++] = [env groundLevelAtIndex:j]+offsetY;
}
....
// render vertex buffer
glVertexPointer(2, GL_FLOAT, 0, vGroundLevel);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, cGround);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*480);

The offsetX and offsetY parameters allow the terrain to be repositioned relative to the screen, allowing the player to move around the environment interactively, while maintaining the game environment as a wrap-around continuum.

Aubrey Goodman