Archived

This topic is now archived and is closed to further replies.

Estauns

Snakes / Nibbles / Asp / Tron Trail...

Recommended Posts

How are the trails in games like Nibbles and Tron generated (such that they create collision). Are they just really small tiles that are left-behind? Some of these games seem like they don''t use tiles at all, but more of some sort of dynamic trail because the movement doesn''t seem restricted to a 16x16 tile or something like that. The only other thing I could think of, is that instead of keeping a 20 x 15 grid of 16 x 16 tiles you keep a 640 x 480 array of dots and just fill in more then 1 dot depending on how wide the object is. Any input here would be great, I''m looking to remake the classic Snafu game if you''ve ever heard of it =)

Share this post


Link to post
Share on other sites
I can think of a couple ways. The first is the simple grid array idea, that fills and empties during movement.
THe second idea is that each time the direction changes, a new line segment is created. THis lines segment follows the player until they change direction again and the line segment ends and a new one is created.
THe third idea is that the player drops off little collision points every however many pixels. These can be checked for bounding circle or bounding box collision.
The fourth idea would be for more advanced games and would involve checking the collision against a bezier curve created as the direction changes.

Share this post


Link to post
Share on other sites
heh heh, i still hum the snafu music sometimes...

in that game it was just tiles... although if you wanted to modernize it i''d say go for the per-pixel-grid (and use more than four colors )...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Estauns,

I would use a std::deque for a tile-based game, like this (p-code):

std::deque<point> tail;
move1tile()
{
newplayerx += playerxdirection==direction::left?-1:1;
newplayery += playerydirection==direction::up?-1:1;
tail.push_front(point(newplayerx, newplayery));
tail.pop_back();
}

rendertail()
{
for(std::deque<point>::iterator i = tail.begin(); i != tail.end(); ++i)
rendertile(tile::tail, *i);
}

Share this post


Link to post
Share on other sites
If you use 90 degree angles the collision detection is pretty easy to do. Just keep a list of the points and go backward and check if the head and the point just before it cross any line created before.

I did quite generic system for a nibbles clone, which used a alpha map, where it pushed the new pixels. But using the alpha map is much harder. You can get nasty bugs, when the snake hits it self in the head.

Share this post


Link to post
Share on other sites
Nibbles was in text mode, and it used the half-block characters to simulate 80*50. It kept a 2D array with a value of what is in each slot and when the tile you''re about to move into isn''t food or empty, you die. It just set the square you''re moving into to a ''snake is here'' value and when it erases the end of the tail it sets that square''s value to ''free space''.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
There are many ways of doing nibbles-style games. None is better than another and it depends on a the case which should be used. I''ll list a few methods.

1) Check the pixel at the snake''s head. This limits you to palettized (read 256 color) modes, but is damn quick. This is best for Tron-like games, where the end of the light path isn''t erased. You don''t have to clear the screen so it''s fast. You don''t need to have an extra array of where the snake has been and where it hasn''t. Just on every update, draw another head to the snake. You are not limited to 90 degree turns with this method.
2) Create an array which holds each pixel/point of the snake. Then check if a snake''s head hits one of the snake''s points. You''ll need at least 1000 points per snake. Kinda slow, but can be made fast. You can erase the end of the snake if you want to make a wormgame instead of a tron-like surrounding game. In some cases linked lists are better than arrays.
3) If you use 90 degree turns only, mark every point where the snake turns. This uses the least memory and is probably the easiest to check collisions.
4) I can''t remember, but there is another method. I''ll post it if I come up with it.

-Richardo

Share this post


Link to post
Share on other sites
Use the line segment route. Then just test for intersecting lines. The tests would be VERY quick so unless your using a scrolling map where the snake could turn 1000+ times it should be very efficient. Although taking into consideration the widths of the snake bodies becomes a bit tougher, it''s still relatively simple.

"I find it immoral to have a battle of wits with an unarmed man"
~Vendayan

Share this post


Link to post
Share on other sites