Snake game

Started by
18 comments, last by walle 19 years, 4 months ago
Hello. I planned to do a simple snake clone, but I got stuck when I tried to think out a way to show the tail of the snake. And make the tail follow the head. I thought about a array or a vector (almost the same thing, but then again-not) to hold the tail. But I still don't know how to make the tail follow the head. There must be a point where the tail should turn of, but I don't know. Are there anyone out there who wants to help with my noob question? I don't want any code please. I would rather write the code by my self, but I would like a tip of how to think. //walle
Advertisement
A queue is the best structure for a snake game.

The head(first in) is pushed onto the queue and the tail(first out) is pushed out.

Here's the basic structure

1. Set queue size
2. Put new head into queue from a the direction your going
3. if the queue is too big, pop a value off.
4. Transverse queue to draw you snake & check for collisions
5. goto 2

If the snake eats a dot, increase the queue size, which will increase your snake's size.
I am not sure I am understanding your question correctly... But I would think of the tail as a part of the path the snake head has traveled before. So you'd need to store a certain number (depending on the length of the snake) of the last known positions of the snake's head. Well, and maybe the direction the head was looking at at that position.

Does this help at all?
--Perfection, my messenger from hell.
Ok. thanks for the quick replies.

Binomine

What is a queue ( I use c++, but I've never herd of it) is it c++?

If it's like an array, why do you pop one of if it's too big?

And (a little embarising) could you explane "Transverse" a little more, don't know the swedish word for it.

Kassandra

Now I don't really understand what you aim at. What relevance does the old direction matter? The new I can understand, but if you could explane it I would be greatful.

//walle
Just an idea... and maybe not a good one but....

Maybe you could keep a movement "queue", so when the head moves one forward then you store that movement in the queue and when the given delay (length of tail) has passed, then the tail starts "playing" back the heads movements. So, the queue would be a FIFO (First In First Out) type of queue.

Example:
Head movement (1 move = 1 tick) delay = 6 ticks
Left
Left
Up
Right
Up
Up

Tail Movement (After delay)
Left
Left
Up
Right
Up
Up

Again, just an idea... let me know what you think.

<EDIT>
Too late, someone already suggested this as I was writing my post :(
-akusei
To simplify what Binomine said, you basically need to keep a list of where the snake has been. As the snake moves foward, you use the list of old positions to erase the positions that are too far back. If the snake was 3 units long for example, you would erase the 3rd unit (old tail position), move the positions down so #2 becomes #3 and #1 becomes #2, then make #1 be where the head has just moved to.

A queue is a data structure that would make such operations easy. I believe C++ has one but I'm not sure on the details.

Traverse means to go through all the elements of the list in this case.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

Akusei

I do really like the idea. I asume by the edit you made this is what Binomine ment?

Ok. Then my question is: how do you use queues?

//walle
Quote:Original post by walle
Now I don't really understand what you aim at. What relevance does the old direction matter? The new I can understand, but if you could explane it I would be greatful.


I can try, I am having difficulties finding the right words to explain what I mean.

Assuming that the image you are using to display the snake's tail has a certain direction - like the head has a certain direction it needs to be displayed in to make sense, meaning the eyes and the snout/muzzle (whatever the mouth of a snake is called in English) always have to point in the direction the snake is going in - you would need to know what direction the head was looking at when it was at that position (where you are now displaying a piece of the snake's tail) to display the tail's image correctly. To not accidently turn it around, like having it appear sideways.

So if this is the snake's head: ->
And this would be used for displaying its tail: -

You would want it to look like this:
-->
|
|
----

And not like this:

-->
-
-
-----

Do you understand me now? I don't even know if this is relevant for you or if you already knew or didn't even want to know anything going in this direction - since I am not sure if I understood your question correctly. And I apologize for my bad explanation...
--Perfection, my messenger from hell.
Another way to do this (I remember doing this myself many a year ago) is to store the direction of each "piece" of snake on the map, and also store the location of the head and tail. (The map being the array or whatever that you use to store the structure of the level). For this method you do not need a queue.

When you want the tail to move:
1) Look up the direction the tail is pointing, by reading the map data that occupies the location of the tail.
2) Write over the map at the location of the tail with "empty".
3) Move the tail in the direction obtained in 1.

To move the head, write the direction that you want to move the snake to onto the map at the position of the head, then move the head, then write "snake-x" onto the new position of the head.



Advantages over the queue method:
1) IMHO this is way simpler.
2) Uses less dynamic memory.
3) Easier to draw if you draw the pieces of snake when they are seen on the map.
4) Makes collisions easy.

Disadvantages:
1) Makes the map "tile" structure more complex.
2) Slightly harder to find the 'nth' piece of snake.
3) Harder to draw if you want to draw the whole snake at once.

A basic tile structure. (Tile = single element of the map).
struct tile {    byte type; // wall, snake-1, snake-2, empty etc.    byte direction;}


Kassandra

Ok. (how do you spell out ok? have totaly slipped my mind. And I'm getting tired of saying ok)

Now I totaly get what you mean, good explanation with the images =)

I had'nt really thougt about it, I planed to use a plain circle at first (I'm not really good att drawing) and mayby later make it look a little nicer. So that is the reason I didn't understand you compleatly.

//walle

This topic is closed to new replies.

Advertisement