Sign in to follow this  
mapster

First game: Need help

Recommended Posts

I'm now in the process of creating my first game in c++. It's my own version of Snake(example). I'm mostly done with it, but have now run into a problem, namely how to keep track of the snake body. How to keep track of where the snake turns and which way it turns from and to. The area you can move the snake is divided into 29*19 squares (29 vertical and 19 horizontal), each square is 20x20 pixels. The snake/player is this code:
struct	snake
{
	int		x, y;			// Player position
	int		sx, sy;		// Player square position - X[0-28] & Y:[0-18]
	int		difficulty;		
	int		length;		// Food collected
	int		lives;		// Player lives
	int		direction;		// 1= left, 2= up, 3= right, 4= down
};
Anybody got an idea of how to keep track of this?

Share this post


Link to post
Share on other sites
Here are two ideas:

1. Grid

Since the playing area isn't too large, you could store an array with an entry for each grid cell. Each cell would hold a single value indicating whether it contained the snake's body, something to eat, or a wall (or whatever else). There would actually be four body codes, one for each direction.

In addition to tracking the head (as you're doing now), you'd have to track the tail also. The head moves in response to user input; the tail moves in the direction encoded in the cell in which it resides. By storing the appropriate directions in the cells as the head moves, the tail will follow the same path.

2. Vector or linked list

Store the snakes body as a list of 'segments', each of which stores the cell coordinates and the direction of motion. Updating the snake proceeds similarly to above, except you cycle through the list as you update rather than working with a preset grid of values.

Share this post


Link to post
Share on other sites
One way is to have a std::list of the coordinates of the segments of your snake.

When the snake moves, you calculate the new head coordinates based on what key the user has pressed, and the current coordinates of the head. Then you insert this new segment at the beginning of the list (i.e. you kind of insert a new head), and remove the last item.

This will create the ilussion of the worm moving when it is in fact only losing its tail and getting a new head.

When you want to render the snake, you simply loop through the list and render a the segment for each segment in the list.
// To render the snake
for each segment in list
{
render segment
}

Share this post


Link to post
Share on other sites
I dont understand what is the problem with the turns but regards the snake body :

I think it will be good to keep each part of the body in a linked list.

every move : remove the first item inserted in the list and add the new body item of the new position to the list.

when grow : add new body item to the head position.

to validate if you are going into the snake body (collision detection), just verify that your head position does equal to one of your items in the link list. if it does , game over.

dont forget to check collisions with the walls of the game.

maybe there is a better way , but that just what came up within the first moments and it pretty easy to implement.

good luck,
Nuno1

Share this post


Link to post
Share on other sites
you see,to hold the snake body,you need to save the parts of the body somewhere.In Snake it is made up of lines,horizontal,vertical,if you like you can make them any angle. Also they are connected. That means you need to store all the "control" points in an array;it has 2 rows-one for X and one for Y.
The size of the array limits the count of body parts.you need one variable to know how much body parts you have.At the beginning,for example you'll have only one,when you make a turn they'll be two,and so on.as time passes you move the head and the tail part of the snake,the other parts are the same.when the tail part "runs out" you just move every variable in the array backwards.
It isnt necessary to use lines as body parts,you can use blocks instead .It depends on you.

Share this post


Link to post
Share on other sites
that was fast ;)
I have just writen my reply and suddenly 3 others posted at the same time.

you can optimize the idea (of basiclly all of the ideas are allmost the same) by combining a linked list with a grid array (jyk recommended).

the linked list will just do what we talked about and the array will be in the size of the screen squares (29*19). basiclly what you need to do with the array is update it to provide the walls and the snake positions.

this way you can do a fast collision detect which basiclly you will only need to check the next position you are going to update the snake head and verify if wall/snakebody is allready there instead of running all over the linked list.

antoher 2 cents.
Nuno1

Share this post


Link to post
Share on other sites
Thx. for the input :D
I think I will continue experimenting with the grid solution, also mentioned by Jyk.
(The reason why I've put in square position for the head struct.)

struct square
{
bool active; // if active draw body
int from; // the direction snake head has when it turns
int to; // the direction snake turns to.
bool food;
};
struct square squares[29][19];


edit:
I'll use the heads pixel coord. (x,y) combined with some math, to find out where the body parts are located in the squares.

Share this post


Link to post
Share on other sites
If someone wonders, I solved it... I'm not finish with it yet, but I'v made a beta release: SnakeOzoid beta.

If you bother downloading it and testing it, you will soon notice that it is a beta... The two worst "bugs" is the black areas that appears when head and tail turns, and the fact that the turns ruin the illusion of movement.
The first problem is easy to solve, I'll use blending for that. But the second problem I really can't see a solution to.

Share this post


Link to post
Share on other sites
It should be, I've tested it on two other computers, including mine, and all three have about 100fps.

btw: there is a while-loop in the code that runs in calculated ms, to slow the main loop.

Share this post


Link to post
Share on other sites
It runs perfectly on my machine :-).

The only two downfalls are that when the snake changes direction his body is literally split into two with a black line of where the horizontal and the vertical textures meet. The other downfall is that when pressing keys they seem to take a while to be processed. If I was to simply tap a key it wouldn't work. The key has to be held in for 0.5-1 second.

AMD Athlon 64 3000+
nVidia 6600GT 256MB

Share this post


Link to post
Share on other sites
yep, I know, I mentioned the graphical error earlier.
The key-pressing issue is because the game won't let you turn untill the x,y coordinate equals one of the 29*19 squares, each square is 20*20 pixels. I'm implementing a key queue though, so that the last key pressed is stored and used when the snakes head reaches a squares x,y coord.

edit: I've updated the rar file now with the key queue changes.
SnakeOzoid

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this