c++ - How to make the snake bite? -


i'm trying make snake game in c++ sfml. here code below. problem don't know how possibly make snake bite himself : each snake block takes position of last one, resulting in straight snake. it's more of algorithm problem. advices :) btw didn't put hashtages , < in include because editor takes them away :/ btw2: looked similar responses none of them approach or in language. here go:

#include <sfml/window.hpp> #include <sfml/graphics.hpp> #include <sfml/system.hpp> #include <sfml/audio.hpp> #include <deque>  void selfincrement();  sf::event event; sf::clock clocksnake; sf::time elapse;  enum direction { up, down, left, right};  int dir = up;  int n = 1;  class snakeblock { public:  snakeblock * next; sf::texture texture; sf::sprite snakeblock; int lastx, lasty; };  std::deque<snakeblock> snake;  int main() { elapse = clocksnake.getelapsedtime();  sf::music epicmusic; epicmusic.openfromfile("epicmusic.wav"); epicmusic.play();  snakeblock snakehead; snakehead.texture.loadfromfile("spritesheetsnake.png", sf::intrect(0,0,20,22)); snakehead.snakeblock.settexture(snakehead.texture); snakeblock snakebody1; snakebody1.snakeblock.settexture(*(snakehead.snakeblock.gettexture())); snakeblock snakebody2; snakebody2.snakeblock.settexture(*(snakehead.snakeblock.gettexture()));  snake.push_front(snakehead); snake.push_front(snakebody1); snake.push_front(snakebody2); snake[2].snakeblock.setposition(500,350); snake[1].snakeblock.setposition(475, 338); snake[0].snakeblock.setposition(450, 316);  sf::renderwindow window(sf::videomode(1028,768), "sfml snake"); window.setframeratelimit(60); while(window.isopen()) {     while(window.pollevent(event))     {         switch(event.type)         {             case sf::event::closed:             epicmusic.stop();             window.close();             break;              default:             break;         }      }      if(sf::keyboard::iskeypressed(sf::keyboard::left))     {             dir = left;     }     if(sf::keyboard::iskeypressed(sf::keyboard::right))     {             dir = right;     }     if(sf::keyboard::iskeypressed(sf::keyboard::down))     {             dir = down;     }     if(sf::keyboard::iskeypressed(sf::keyboard::up))     {             dir = up;     }     if(dir == up)     {          snake[0].snakeblock.move(0,-2);         snake[n].snakeblock.setposition(snake[n-1].snakeblock.getposition().x, snake[n-1].snakeblock.getposition().y+20);     }     if(dir == down)     {         snake[0].snakeblock.move(0,2);         snake[n].snakeblock.setposition(snake[n-1].snakeblock.getposition().x, snake[n-1].snakeblock.getposition().y-20);     }     if(dir == left)     {         snake[0].snakeblock.move(-2,0);         snake[n].snakeblock.setposition(snake[n-1].snakeblock.getposition().x+20, snake[n-1].snakeblock.getposition().y);     }     if(dir == right)     {         snake[0].snakeblock.move(2,0);         snake[n].snakeblock.setposition(snake[n-1].snakeblock.getposition().x-20, snake[n-1].snakeblock.getposition().y);     }     window.clear(sf::color::red);     n++;     if( n > 2)     {         n = 1;     }     //selfincrement();     for(unsigned int m = 0; m < snake.size(); m++)     {         window.draw(snake[m].snakeblock);     }      window.display(); } return 0;  }  /*void selfincrement() { elapse = clocksnake.getelapsedtime(); if(elapse.asseconds() > 0.10) {     n++;     clocksnake.restart(); } if(n > snake.size()) {     n = 1; } } */ 

new code using new principle::

#include <sfml/window.hpp> #include <sfml/graphics.hpp> #include <sfml/system.hpp> #include <sfml/audio.hpp> #include <deque>  void advancestep();  sf::event event; sf::clock clocksnake; sf::time elapse;  enum direction { up, down, left, right};  sf::vector2i direction; int dir = up;  int n = 1;  class snakeblock { public:  sf::texture texture; sf::sprite snakeblock; int dir = 0; int lastx, lasty; };  snakeblock element; std::deque<snakeblock> snake;  int main() { elapse = clocksnake.getelapsedtime();  sf::music epicmusic; epicmusic.openfromfile("epicmusic.wav"); epicmusic.play();  snakeblock snakehead; snakehead.texture.loadfromfile("spritesheetsnake.png", sf::intrect(0,0,20,22)); snakehead.snakeblock.settexture(snakehead.texture); snakeblock snakebody1; snakebody1.snakeblock.settexture(*(snakehead.snakeblock.gettexture())); snakeblock snakebody2; snakebody2.snakeblock.settexture(*(snakehead.snakeblock.gettexture()));  snake.push_front(snakehead); snake.push_front(snakebody1); snake.push_front(snakebody2); snake[2].snakeblock.setposition(500,350); snake[1].snakeblock.setposition(475, 338); snake[0].snakeblock.setposition(450, 316);  sf::renderwindow window(sf::videomode(1028,768), "sfml snake"); window.setframeratelimit(10); while(window.isopen()) {     while(window.pollevent(event))     {         switch(event.type)         {             case sf::event::closed:             epicmusic.stop();             window.close();             break;              default:             break;         }      }      if(sf::keyboard::iskeypressed(sf::keyboard::left))     {             dir = left;             direction.x = -1;             direction.y = 0;     }     if(sf::keyboard::iskeypressed(sf::keyboard::right))     {             dir = right;             direction.x = 1;             direction.y = 0;     }     if(sf::keyboard::iskeypressed(sf::keyboard::down))     {             dir = down;             direction.x = 0;             direction.y = -1;     }     if(sf::keyboard::iskeypressed(sf::keyboard::up))     {             dir = up;             direction.x = 0;             direction.y = 1;     }     if(dir == up)     {          snake[0].snakeblock.move(0,-2);         snake[1].snakeblock.setposition(snake[0].snakeblock.getposition().x, snake[0].snakeblock.getposition().y+20);         snake[2].snakeblock.setposition(snake[1].snakeblock.getposition().x, snake[1].snakeblock.getposition().y+20);     }     if(dir == down)     {         snake[0].snakeblock.move(0,2);         snake[1].snakeblock.setposition(snake[0].snakeblock.getposition().x, snake[0].snakeblock.getposition().y-20);         snake[2].snakeblock.setposition(snake[1].snakeblock.getposition().x, snake[1].snakeblock.getposition().y-20);     }     if(dir == left)     {         snake[0].snakeblock.move(-2,0);         snake[1].snakeblock.setposition(snake[0].snakeblock.getposition().x+20, snake[0].snakeblock.getposition().y);         snake[2].snakeblock.setposition(snake[1].snakeblock.getposition().x+20, snake[1].snakeblock.getposition().y);     }     if(dir == right)     {         snake[0].snakeblock.move(2,0);         snake[1].snakeblock.setposition(snake[0].snakeblock.getposition().x-20, snake[0].snakeblock.getposition().y);         snake[2].snakeblock.setposition(snake[1].snakeblock.getposition().x-20, snake[1].snakeblock.getposition().y);     }     window.clear(sf::color::red);     advancestep();     for(unsigned int m = 0; m < snake.size(); m++)     {         window.draw(snake[m].snakeblock);     }     window.display(); } return 0;  }  void advancestep() { sf::vector2f headpos(snake[0].snakeblock.getposition());  headpos.x += 22 * direction.x; headpos.y += 22 * direction.y;  snake[0].snakeblock.setposition(headpos);  snake.pop_back(); snake.push_front(snake[0]); } 

new code taking in account said, snake disappear, because of pop_back..

#include <sfml/window.hpp> #include <sfml/graphics.hpp> #include <sfml/system.hpp> #include <sfml/audio.hpp> #include <deque>  void advancestep();  sf::event event; sf::clock clocksnake; sf::time elapse;  enum direction { up, down, left, right};  sf::vector2i direction(0, 0); int dir = up;   class snakeblock { public:  sf::texture texture; sf::sprite snakeblock; int dir; };  std::deque<snakeblock> snake;  int main() { elapse = clocksnake.getelapsedtime();  sf::music epicmusic; epicmusic.openfromfile("epicmusic.wav"); epicmusic.play();  snakeblock snakehead; snakehead.texture.loadfromfile("spritesheetsnake.png", sf::intrect(0,0,20,22)); snakehead.snakeblock.settexture(snakehead.texture); snakeblock snakebody1; snakebody1.snakeblock.settexture(*(snakehead.snakeblock.gettexture())); snakeblock snakebody2; snakebody2.snakeblock.settexture(*(snakehead.snakeblock.gettexture()));  snake.push_back(snakehead); snake.push_back(snakebody1); snake.push_back(snakebody2);  snake[2].snakeblock.setposition(500,350); snake[1].snakeblock.setposition(475, 338); snake[0].snakeblock.setposition(450, 316);  sf::renderwindow window(sf::videomode(1028,768), "sfml snake"); window.setframeratelimit(1); while(window.isopen()) {     while(window.pollevent(event))     {         switch(event.type)         {             case sf::event::closed:             epicmusic.stop();             window.close();             break;              default:             break;         }      }      if(sf::keyboard::iskeypressed(sf::keyboard::left))     {             direction.x = -1;             for(int = 1; < snake.size(); i++)             {                 snake[i].snakeblock.setposition(snake[i+1].snakeblock.getposition().x-20, snake[i+1].snakeblock.getposition().y);             }     }     if(sf::keyboard::iskeypressed(sf::keyboard::right))     {             direction.x = 1;             for(int j = 1; j < snake.size(); j++)             {                 snake[j].snakeblock.setposition(snake[j+1].snakeblock.getposition().x+20, snake[j+1].snakeblock.getposition().y);             }     }     if(sf::keyboard::iskeypressed(sf::keyboard::down))     {             direction.y = -1;             for(int l = 1; l < snake.size(); l++)             {                 snake[l].snakeblock.setposition(snake[l+1].snakeblock.getposition().x, snake[l+1].snakeblock.getposition().y-22);             }     }     if(sf::keyboard::iskeypressed(sf::keyboard::up))     {             direction.y = 1;             for(int o = 1; o < snake.size(); o++)             {                 snake[o].snakeblock.setposition(snake[o+1].snakeblock.getposition().x, snake[o+1].snakeblock.getposition().y+22);             }     }     window.clear(sf::color::red);     advancestep();     for(unsigned int m = 1; m < snake.size(); m++)     {         window.draw(snake[m].snakeblock);     }     window.display(); } return 0;  }  void advancestep() { sf::vector2f headpos; headpos.x = snake[0].snakeblock.getposition().x; headpos.y = snake[0].snakeblock.getposition().y;  headpos.x += 22 * direction.x; headpos.y += 22 * direction.y;  snakeblock element; element.snakeblock.setposition(headpos);  snake.pop_back(); snake.push_front(element); } 

your implementation has lot of problems. rather pointing out each , every issue, here's rough outline. let's snake list of segments, maximum length:

  • on each update step:
    1. next position = head position + current direction.
    2. add segment @ head of queue, in next position.
    3. while queue length greater maximum length, remove segment @ tail of queue.
  • on keyboard input, change current direction.
  • if ever need change length of snake, change maximum length -- update step adjust length of snake.

a collision, semantically, when snakes head runs other part of body.

to detect collisions, implement on each update step. check head against rest of body segments. if there's intersection, collision occurred.

btw if want smoother "shrinking" effect when maximum snake length decreases, e.g. remove 2 segments max per update (while queue length > max length , while segments removed < shrink rate).

edit: addressing comment below wondering how change direction based on integer (or enum, see use -- same concept); here's more pseudocode:

vec2 direction(0, 0);  if (currentdirection == up)     direction.y = -1; else if (currentdirection == down)     direction.y = 1; else if (currentdirection == left)     direction.x = -1; else if (currentdirection == right)     direction.x = 1;  // direction vector containing x , y offset, can // apply current position of snake head find next // position. 

Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -