Sign in to follow this  
Ouhyeah

Snake movement

Recommended Posts

Hi, I'm trying to make a simple snake game with SFML just to practice programming.
And I have a problem making the snake move correctly when it turns down or up if you played snake you know what I'm talking about.
So I looked it up on the net and the solution I found to do the movement is like this:
1.Store snake head position
2.Move the head
3.Give the second block the snakes head old position
4.Loop through the hold body and and do something like snake[i -1].position = snake[i].position;

I'm having trouble implementing this, I have a vector of blocks which is actually the snake, like this:

[code]std::vector<*Block>snake_body;[/code]

This is how I tried implementing it but it just stores all the blocks in the same position

[code]
void Snake::Move()
{
if(down == true)
{
for(int i = 1; i < snake_body.size(); ++i)
{
int posY = snake_body[i - 1]->spr->getSprite()->GetPosition().y;

int posX = snake_body[i - 1]->spr->getSprite()->GetPosition().x;

snake_body[i]->setPosition(posX,posY);

snake_body[i - 1]->setPosition(posX,headY += 0.1);
}
}

}[/code]


I made a couple of different implementations but always i get that all the tiles have the same position, or it just doesn't turn like a snake(it just rotates the body).

So any ides about this, or is there a better way of doing this ?

Share this post


Link to post
Share on other sites
A problem here is that the previous part snake_body[i-1] has always been moved to the position of snake_body[0] so all end up on top of each other. Maybe you should try to iterate in reverse order.

Ok, that is if I ignore this line [code]snake_body[i - 1]->setPosition(posX,headY += 0.1);[/code]I don't know what headY is. posX and posY is integers so I don't know if you use integer positions or not. If headY is an integer headY += 0.1 has no effect.

Share this post


Link to post
Share on other sites
For moving the snake, it's not too difficult. Think about the steps in your loop. As wooh said, you're just setting the next one ot the previous value, which has already changed.
Also, don't get the position of the sprite, that's the position of the sprite on the screen in pixels. you want the snake's position on the map

So, you want to do this:

[code]

int PosX, PosY;
for (int i = snake_body.size()-1; i > 0; i--)
{
// get position of location to move segment next
snake_body[i-1]->getPosition(PosX, PosY);
snake_body[i]->setPosition(PosX, PosY);
}


// set head based on which way we've moving


// get current head location
snake_body[0]->getPosition(PosX, PosY);

if (down && (PosY < MAX_LEVEL_SIZE))
{
PosY++;
}


// do for all directions
.
.
.

snake_body[0]->setPosition(PosX, PosY);
[/code]
[font="CourierNew, monospace"][size="2"] [/size][/font]

Share this post


Link to post
Share on other sites
Thanks for your help,
well I didn't made any kind of map which the snake moves upon i thought I can do it without that.
So i will make a grid based map and try to do it like you said :)


Share this post


Link to post
Share on other sites
[quote name='Nesa' timestamp='1313700461' post='4850925']
Thanks for your help,
well I didn't made any kind of map which the snake moves upon i thought I can do it without that.
So i will make a grid based map and try to do it like you said :)

[/quote]

You're going to want to make a grid-type map. It'll make implementation very easy, especially for collision with walls/objects.
In my snake implementation, I had my "levels" stored in a text file like this:
[code]

[font="'Courier New"]
[/font]
[font="'Courier New"]1[/font]
[font="'Courier New"]################################################[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]################## #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# @ #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# #[/font]
[font="'Courier New"]# # ##################[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]# # #[/font]
[font="'Courier New"]################################################[/font]
[font="'Courier New"]
[/font]
[font="'Courier New"]2[/font]
[font="'Courier New"]
################################################
## ##
## ##
## ##
## ## ## ##
## ## ## ##
## ## ## ##
## ###### ##
## ##
### ###
### ###
### ###
### ###
## ##
## ##
# #
# #
# #
# #
# #
################## #################
## @ ##
## ##
## ##
## ## ## ##
## ## ## ##
## ## ## ##
## ###### ##
## ##
### ###
### ###
### ###
### ###
## ##
## ##
###############[/font]
[/code]

And i would load the levels and generate my maps to be just like them. the "@" is where the snake would start.

So, if my levels were 40x40 and if my window was 800x600, each "block" was 20x15 pixels.

Share this post


Link to post
Share on other sites
My suggestion: Don't loop through the body advancing each segment, but rather add a segment at the head and remove a segment at the end when it advances. With a circular array you can do this without changing the array at all.

Basically, instead of looping from body[0] to body[last], you store the index for the head and the tail, and loop from body[head] to body[tail], with the caveat that when head or tail grow greater than the length of the array or less than 0, you set them to 0 or the length of the array respectively.

So say you start with the head == 0, tail == 1, and all the x and y values for all the body parts == (0,0). So the whole snake is in the middle of the screen. You decrease the value of head and tail by one each tick, so on the second tick head == length_of_Array and tail == 0, and set the proper x and y values for body[length_of_array], which say we're moving towards the right would mean x increases by 1.

Next tick you again decrease the indexes by one (so now tail == length_of_array and head == length_of_array -1), and set the x and y value of the head. Say they turned up, so y increases by 1. The tail would now be where the head was last tick (the snake has two segments) without you needing to modify the information in the array. As the snake grows, you only ever need to modify the indexes of the head and tail, and the value for the segment of the new head.

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