I am just starting out trying to make games in C++. I have some experience with the language but I have never made games or used SDL too much. As a start I took a motion tutorial from http://lazyfoo.net/SDL_tutorials/ and made it into a two player game where random red dots appear and the players race to collect 10. It has collision detection and such which I figure out how to do. After doing this I'm trying to expand it into snakes now not just dots. However I am having problems get the snakes to move correctly. I was able to hack it together somewhat but when changing direction from say right to up the whole snake flips at once instead of moving a section at a time. I think I am missing something conceptually about this. I could do it on a matrix but I dont want to restrict motion to a square matrix

snake.cpp

Snake::Snake() { pieces.push_back(Dot()); headX = pieces.at(0).getX(); headY = pieces.at(0).getY(); length = 1; }; void Snake::show() { int curX; int curY; for( int i =0; i < length; i++) { curX = pieces.at(i).getX(); curY = pieces.at(i).getY(); apply_surface( curX, curY, dot, screen ); } }; void Snake::handle_input() { pieces.at(0).handle_input(0); for( int i =1; i < length; i++) { int xVel = pieces.at(i-1).getXVelocity(); int yVel = pieces.at(i-1).getYVelocity(); if(yVel < 0 && xVel ==0) pieces.at(i-1).setDirection(0); if(yVel > 0 && xVel ==0) pieces.at(i-1).setDirection(1); if(yVel == 0 && xVel < 0) pieces.at(i-1).setDirection(2); if(yVel == 0 && xVel >0) pieces.at(i-1).setDirection(3); } }; void Snake::move() { pieces.at(0).move(); int previous_x; int previous_y; int previous_xVel; int previous_yVel; for( int i=1; i < length; i++) { previous_x = pieces.at(i-1).getX(); previous_y = pieces.at(i-1).getY(); previous_xVel = pieces.at(i-1).getXVelocity(); previous_yVel = pieces.at(i-1).getYVelocity(); if(previous_xVel != 0 || previous_yVel != 0) { pieces.at(i).setX(previous_x-(2*previous_xVel)); pieces.at(i).setY(previous_y-(2*previous_yVel)); } else { if(pieces.at(i-1).getDirection() == 0) { pieces.at(i).setX(previous_x); pieces.at(i).setY(previous_y+(DOT_HEIGHT)); } else if(pieces.at(i-1).getDirection() ==1) { pieces.at(i).setX(previous_x); pieces.at(i).setY(previous_y-(DOT_HEIGHT)); } else if(pieces.at(i-1).getDirection() ==2) { pieces.at(i).setX(previous_x+DOT_WIDTH); pieces.at(i).setY(previous_y); } else if(pieces.at(i-1).getDirection() ==3) { pieces.at(i).setX(previous_x-DOT_WIDTH); pieces.at(i).setY(previous_y); } else { pieces.at(i).setX(previous_x-(DOT_WIDTH)); pieces.at(i).setY(previous_y-(DOT_HEIGHT)); } } pieces.at(i).setXVelocity(previous_xVel); pieces.at(i).setYVelocity(previous_yVel); } }; Dot Snake::getHead() { return pieces.at(0); }; void Snake::addToSnake() { int x = pieces.at(length-1).getX(); int y = pieces.at(length-1).getY(); int xv = pieces.at(length-1).getXVelocity(); int yv = pieces.at(length-1).getYVelocity(); pieces.push_back(Dot(x-DOT_WIDTH,y,xv,yv)); length++; };

dot.cpp

Dot::Dot() { //Initialize the offsets x = 0; y = 0; //Initialize the velocity xVel = 0; yVel = 0; radius = DOT_WIDTH/2; } Dot::Dot(int xStart, int yStart) { //Initialize the offsets x = xStart; y = yStart; //Initialize the velocity xVel = 0; yVel = 0; radius = DOT_WIDTH/2; } Dot::Dot(int xStart, int yStart, int xvel, int yvel) { //Initialize the offsets x = xStart; y = yStart; //Initialize the velocity xVel = xvel; yVel = yvel; radius = DOT_WIDTH/2; } void Dot::handle_input(int player) { if(player == 0) { //If a key was pressed if( event.type == SDL_KEYDOWN ) { //Adjust the velocity switch( event.key.keysym.sym ) { case SDLK_UP: yVel -= DOT_HEIGHT / 2; break; case SDLK_DOWN: yVel += DOT_HEIGHT / 2; break; case SDLK_LEFT: xVel -= DOT_WIDTH / 2; break; case SDLK_RIGHT: xVel += DOT_WIDTH / 2; break; } } //If a key was released else if( event.type == SDL_KEYUP ) { //Adjust the velocity switch( event.key.keysym.sym ) { case SDLK_UP: yVel += DOT_HEIGHT / 2; break; case SDLK_DOWN: yVel -= DOT_HEIGHT / 2; break; case SDLK_LEFT: xVel += DOT_WIDTH / 2; break; case SDLK_RIGHT: xVel -= DOT_WIDTH / 2; break; } } } //other color stuff ommitted } void Dot::move() { //Move the dot left or right x+=xVel; //If the dot went too far to the left or right if(x + DOT_WIDTH > SCREEN_WIDTH) x = 0; if(x < 0) x = SCREEN_WIDTH-DOT_WIDTH; //Move the dot up or down y += yVel; //If the dot went too far up or down if(y + DOT_HEIGHT > SCREEN_HEIGHT) y = 0; if(y < 0) y = SCREEN_HEIGHT-DOT_HEIGHT; } void Dot::move(int x_velocity, int y_velocity) { //Move the dot left or right xVel = x_velocity; x+=x_velocity; //If the dot went too far to the left or right if(x + DOT_WIDTH > SCREEN_WIDTH) x = 0; if(x < 0) x = SCREEN_WIDTH-DOT_WIDTH; //Move the dot up or down yVel = y_velocity; y += y_velocity; //If the dot went too far up or down if(y + DOT_HEIGHT > SCREEN_HEIGHT) y = 0; if(y < 0) y = SCREEN_HEIGHT-DOT_HEIGHT; } void Dot::show(int color) { //Show the dot if(color == 0) apply_surface( x, y, dot, screen ); else apply_surface( x, y, blueDot, screen ); }

main.cpp

int main( int argc, char* args[] ) { //declarations are ommited //While the user hasn't quit while( quit == false ) { if(gameState == 0) { //Start the frame timer fps.start(); //While there's events to handle while( SDL_PollEvent( &event ) ) { //Handle events for the dot snake1.handle_input(); dotTwo.handle_input(1); //If the user has Xed out the window if( event.type == SDL_QUIT ) { //Quit the program quit = true; } } //collison vector<smallDot> temp = pointDots; for(unsigned int i = 0; i < temp.size();i++) { if(temp.at(i).checkCollision(snake1.getHead())) { temp.erase(temp.begin()+i); snake1.addToSnake(); player1score += DOT_VALUE; } } pointDots = temp; temp.clear(); temp = pointDots; for(unsigned int i = 0; i < temp.size();i++) { if(temp.at(i).checkCollision(dotTwo)) { temp.erase(temp.begin()+i); player2score += DOT_VALUE; } } pointDots = temp; temp.clear(); //status //Move the dot snake1.move(); dotTwo.move(); //Add point dot dotsTimer.update(); if(dotsTimer.check()) { pointDots.push_back(smallDot()); } //Fill the screen white SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); displayScores(player1score,player2score); //Show the dot on the screen for (unsigned int i = 0; i < pointDots.size(); i++) { //if (pointDots.at(i) == NULL) // continue; // skip NULL objects pointDots.at(i).show(); } snake1.show(); dotTwo.show(1); //Update the screen if( SDL_Flip( screen ) == -1 ) return 1; if( gameOver(player1score,player2score)) gameState = 1; //Cap the frame rate } else if (gameState == 1) { //stuff for winner omitted for length SDL_Flip(screen); } } //Clean up clean_up(); return 0; }

I had to omit stuff for length but the full code and everything if you would like to look at it all is at https://github.com/b...st/Snake%20Game along with all the other file and the visual studio solution

Any help or advice will be greatly appreciated