First game: Need help

Started by
10 comments, last by mapster 18 years ago
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?
Advertisement
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.
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 snakefor each segment in list{    render segment}
[s]--------------------------------------------------------[/s]chromecode.com - software with source code
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
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.
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
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.
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.
The game runs extremely fast on my machine. Have you made the speed machine independent?

Steven Yau
[Blog] [Portfolio]

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.

This topic is closed to new replies.

Advertisement