I'm having some trouble making my snake move :D I can move one point in any direction but the whole body of the snake is where I'm confused ,

if(a == (char) 119 || a == (char) 87 || a == 72)
        {
            y=y--;
            gotoxy(x,y);
            PrintVector(v);
            }

thats works just fine if my vector consists of only one point , but other than that it doesnt work , I know if I Want its body to move right I gotta use puch_back and pop_back but I just need a little help or a hint :D another thing i'm making my loop while(input=getch()) and that makes the user presses the key " w or W or even the arrow " each time he wants to go up , I know I have to make it while(true) but it doesnt work even when I add the Sleep() , some help or hints would be very much appreciated :) thx in advance :)

Recommended Answers

All 16 Replies

Hi there!

I need to see more code than this to be able to help you. To solve this problem I would use an array of coordinates like this:
[ (5, 5) (4, 5) (3, 5) (3, 6) ]
for example.

Then, when I move up for example, I take the first coordinate (5, 5) and decrease y by 1 and push it first in the queue so I get this:
[ (5, 4) (5, 5) (4, 5) (3, 5) (3, 6) ]

I then pop the last coordinate (3, 6) from the queue leaving this:
[ (5, 4) (5, 5) (4, 5) (3, 5) ].

This is your new snake.

Also, a proper game loop using old standards can look something like this:

1. While Not EndCondition = True do:
    2. If KeyPressed do:
        3. (char) c <= GetKey
        4. Handle movement
    5. End if
    6. Calculate stuff
    7. Draw stuff
    8. Sleep some
9. End while

I used this structure quite alot when I took my Pascal courses back in highschool. You should be able to find a similar way to implement this in your C++ code.

I hope this helps!

Regards,
Emil Olofsson

commented: thank you so much i'm trying to that right now :) +0

You need a FOR loop to move each piece of your snake.

commented: i'm trying to make one but out of ideas ! :( +0

that what I got so far , I can move a point on the screen but if its multiple points i cant really do much about it !

    while(input=getch())
        {

            if(x_f==x_s && y_f==y_s)  // eat the fooooooooooooooooooood
        {

            snake.push_back('*');
            food(x_f,y_f);
            count_food++;
            points+=5;
            PrintVector(snake);

        }// end of the if stat. of food

        //up
        if(input == (char) 119 || input == (char) 87 || input == 72)
        {
            y_s=y_s-i;
            gotoxy(x_s,y_s);
            PrintVector(snake);
            gotoxy(x_s,y_s+i);
                cout<<" ";
        }
    //  down
        if(input == (char) 115 || input == (char) 83 || input == 80)
        {
            y_s=y_s+i;
            gotoxy(x_s,y_s);
            PrintVector(snake);
        }
    //  right
        if(input == (char) 100 || input == (char) 68 || input == 77)
        {

            x_s=x_s+i;
            gotoxy(x_s,y_s);
            PrintVector(snake);
            gotoxy(x_s-i,y_s);
            cout<<" ";
        }
    //  left
        if(input == (char) 65 || input == (char) 97 || input == 75)
        {
            x_s=x_s-i;
            gotoxy(x_s,y_s);
            PrintVector(snake);
            gotoxy(x_s+snake.size(),y_s);
            cout<<" ";
        }

any advice would be very appreciated

You've been given 2 possible solutions. Try one.

commented: I tried different solution but hasnt worked for me :D and now i'll try the first solution :) +0

i've moved the snake but now i've some trouble with cls , cls makes the food function generates random points everytime it goes into the loop but it solves the issue with the snake that it doesnt leave any points behind , some help plz :D i need some way to print spaces after the snake so it doesnt leave any points behind or a way to make the food function not to generate random points everytime

food(x_f,y_f);
 while(true)
 {
     input=getch();
     Sleep(10);
    system("CLS");


 // loop to repalce each part in the snake body
 for(int i=snake.size()-1;i>0;i--)
 {
     snake[i].x=snake[i-1].x;
     snake[i].y=snake[i-1].y;
 }
 // move up when press  "W" Or 'up'
 if(input == (char) 119 || input == (char) 87 || input == 72)
 {
   snake[0].y--;  
 }

 // move down when press "S" Or 'down'
 if(input == (char) 115 || input == (char) 83 || input == 80)
 {
  snake[0].y++;
 }
 // move right when press "D" Or 'right'
 if(input == (char) 100 || input == (char) 68 || input == 77)
 {
  snake[0].x++;
 }
 // move left when press "A" Or 'left'
 if(input == (char) 65 || input == (char) 97 || input == 75)
 {
  snake[0].x--;
 }
 if(x_f==snake[0].x && y_f==snake[0].y)  // eating the fooooooooooooooooooood
        {

            snake.push_back(eat);
            food(x_f,y_f);
            count_food++;
            points+=5;

        }// end of the if stat. of food

 for(int i=0; i<snake.size();i++)
 {

  gotoxy(snake[i].x,snake[i].y);
  cout<<snake[i].shape ;
 }

 }// while loop

some help here plz

i need some way to print spaces after the snake so it doesnt leave any points behind or a way to make the food function not to generate random points everytime

You know what the last position of the snake was, so just output your spaces after you output the snake.

commented: I've done that , but now i need a way for the snake to keep moving without having to press a key a key each time +0
if(input == (char) 119 || input == (char) 87 || input == 72)
            {
                snake[0].y--;  
            }

            // move down when press "S" Or 'down'
            if(input == (char) 115 || input == (char) 83 || input == 80)
            {
                snake[0].y++;
            }
            // move right when press "D" Or 'right'
            if(input == (char) 100 || input == (char) 68 || input == 77)
            {
                snake[0].x++;
            }
            // move left when press "A" Or 'left'
            if(input == (char) 65 || input == (char) 97 || input == 75)
            {
                snake[0].x--;
            }
            if(x_f==snake[0].x && y_f==snake[0].y)  // eat the fooooooooooooooooooood
            {
                snake.push_back(eat);
                food(x_f,y_f);
                count_food++;
                points+=5 ;
                if(count_food==7)
                {
                    sfood(x_sf,y_sf);
                    if(x_sf==snake[0].x && y_sf==snake[0].y)
                    {
                        points+=10;
                        count_food=0;
                    }
                }
            }// end of the if stat. of food


            for(int i=0; i<snake.size();i++)
            {
                gotoxy(snake[i].x,snake[i].y);
                cout<<snake[i].shape ;
            }

            int a=snake.size()-1;
            gotoxy(snake[a].x,snake[a].y);
            cout<<" ";

help

With what? Code with no question does not require a response.

I asked u in my comment that i need a way for the snake to keep moving without having to press a key a key each time

OK, your paradigm needs a little work.
Three things I see.

  1. What you're doing is you're getch()-ing every time you loop. Getch() is a show-stopper. The program won't continue until it has that key press. This won't work for an action game. You need to preface the getch with an if(kbhit()).

  2. Your snake is basing its movement on user input. What it should be doing is basing its DIRECTION on user input. If its direction is up, it will keep going up. If its direction is left, it will keep going left. And on. And on. Each loop should progress the snake further in that direction. Only when a key is pressed, does the direction change.

  3. Slow it down. This is where it gets tricky. As soon as you implement the preceding two steps, you will find yourself starting the game and having it end before you've finished letting go of ENTER. It looks like you're using Turbo C++. I'd recommend dropping that and getting something more modern (and perfectly legally free). For Turbo C++. you'll need to use the delay(unsigned int milliseconds) function. I'd recommend a value of maybe 250 - 400. If you've upgraded to a modern compiler, you can use the windows sleep(unsigned int milliseconds) function. Turbo C++ has a sleep function, but it counts in whole seconds.

commented: sorry but I dont understand ur 2nd point what do you mean by my snake is basing its movement on user input. What it should be doing is basing its DIRECTION on user input ? can u show me an example , also my snake is leaving some points behind I tried to +0

sorry but I dont understand ur 2nd point what do you mean by my snake is basing its movement on user input. What it should be doing is basing its DIRECTION on user input ? can u show me an example , also my snake is leaving some points behind I tried to trace it but got nowhere near solving it

OK. You set up a direction variable that your snake bases its movement off of.
Let's call it direction. (Put this early in the beginning, before the loop).

enum direction { UP, DOWN, RIGHT, LEFT};
direction=UP; //Start snake facing up.

Now, direction does not change UNLESS the user presses a key.

    if(kbhit()){
        input=getch();
        // go in up direction when press "W" Or 'up'
        if(input == (char) 119 || input == (char) 87 || input == 72)
        {
            direction=UP;
        }

        // go in down direction when press "S" Or 'down'
        if(input == (char) 115 || input == (char) 83 || input == 80)
        {
            direction=DOWN;
        }
        // go in right direction when press "D" Or 'right'
        if(input == (char) 100 || input == (char) 68 || input == 77)
        {
            direction=RIGHT;
        }
        // go in left direction when press "A" Or 'left'
        if(input == (char) 65 || input == (char) 97 || input == 75)
        {
            direction=LEFT;
        }
    }

And in every loop, we update the snake's location, based on direction REGARDLESS of whether a key was pressed.

        switch(direction){
            case UP:
                snake[0].y--;
                break;
            case DOWN:
                snake[0].y++;
                break;
            case RIGHT:
                snake[0].x++;
                break;
            case LEFT:
                snake[0].x--;
                break;
            default: //In the event that something weird happens.
                direction=UP;
                snake[0].y--;
                break;
        }

@DeanMSands3 , done and thank you very much :) u helped me alot :D any idea where to start if i want my snake to go through walls :D " no maze maze " xD

thx anyway :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.