SFML游戏中的逻辑错误,如何修复渲染机制?

时间:2018-12-28 15:11:53

标签: c++ sfml

我从SFML开始,想做一个Snake游戏。 我在Linux(Kali 2018)上,使用prebuild gnu g ++编译器。 使用命令:

  

g ++ -c snake.cpp

     

g ++ snake.o -o蛇-lsfml-graphics -lsfml-window -lsfml-system

它编译得很好,运行没有错误。 这是snake.cpp:

#include <SFML/Graphics.hpp>
#include <vector>
#include <cstdio>
#include <iostream>
#define SIZE 12
#define WIDTH 600/SIZE
#define HEIGHT 600/SIZE
#define LEFT 0
#define UP 1
#define RIGHT 2
#define DOWN 3

class Tail
{
  public:
    int x;
    int y;
    int dir;
    Tail()
    {

    }
    Tail(int x,int y,int dir)
    {
      this->x = x;
      this->y = y;
      this->dir = dir;
    }
};
//container for the snake
class Snake
{
  public:
    int length = 1;
    std::vector<Tail> v;//vector of the tailes
    Tail head;
    int dir;
    void extend()
    {
      this->v.resize(++this->length);
      this->v.at(this->length - 1) = Tail(this->v.at(this->length - 2).x,this->v.at(this->length - 2).y,this->v.at(this->length - 2).dir);
      std::cout << this->length << std::endl;//For  testing purposes
    }

} snake;
class Apple : Tail
{
  public:
    Apple generate()
    {
      Apple a;
      a.x = rand()%(WIDTH+1);
      a.y = rand()%(WIDTH+1);
      for(int i = 0;i < snake.length;i++)
      {
        if(snake.v.at(i).x == a.x && snake.v.at(i).y == a.y)
        {
          return generate();
        }
      }
      return a;
    }
    bool check()
    {
      if(snake.v.at(0).x == this->x && snake.v.at(0).y == this->y)
      {
        return true;
      }
      return false;
    }
} apple;

int main()
{
    sf::Clock c;//For speed adjusment
    int i = 3;//3 block per second
    sf::RenderWindow window(sf::VideoMode(600, 600), "Snake",sf::Style::Close);
    //initialize the head tail
    snake.v.resize(1);
    snake.v.at(0).x = 30;
    snake.v.at(0).y = 30;
    snake.v.at(0).dir = RIGHT;
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            if (event.type == sf::Event::KeyPressed)
            {
              switch(event.key.code)
              {
                case sf::Keyboard::Up:   snake.dir = UP;
                                         break;
                case sf::Keyboard::Down: snake.dir = DOWN;
                                         break;
                case sf::Keyboard::Left: snake.dir = LEFT;
                                         break;
                case sf::Keyboard::Right:snake.dir = RIGHT;
                                         break;
              }
            }
        }
        if(c.getElapsedTime().asSeconds() >= 10)
        {
          std::cout << c.restart().asSeconds() << std::endl;
          i++;
        } //changes speed after 10 seconds
        window.setFramerateLimit(i);//same
        //RENDERING
        window.clear();
        snake.v.resize(snake.length);//will be significant when the snake is being extended
        //Increment the Coordinates acording to the direction
        switch(snake.dir)
        {
          case UP:    snake.v.at(0).y--;
                      snake.v.at(0).dir = UP;
                      break;
          case DOWN:  snake.v.at(0).y++;
                      snake.v.at(0).dir = DOWN;
                      break;
          case LEFT:  snake.v.at(0).x--;
                      snake.v.at(0).dir = LEFT;
                      break;
          case RIGHT: snake.v.at(0).x++;
                      snake.v.at(0).dir = RIGHT;
                      break;
        }
        snake.extend();//Userd for Testing THIS IS THE Part which doesnt work
        //give the position and directions  of the tail before it to the current tail in the loop
        for(int i = 1; i < snake.length;i++)
        {
          snake.v.at(i).x = snake.v.at(i-1).x;
          snake.v.at(i).y = snake.v.at(i-1).y;
          snake.v.at(i).dir  = snake.v.at(i-1).dir;
        }
        sf::RectangleShape r[snake.v.size()];//Array of shapes for rendering
        //NOTE: Using a single shape which is changing doesnt work either
        for(int i = 0; i < snake.v.size();i++)//render loop
        {
          r[i].setSize(sf::Vector2f(SIZE,SIZE));
          r[i].setPosition(snake.v.at(i).x*SIZE,snake.v.at(i).y*SIZE);
          r[i].setFillColor(sf::Color::White);
          window.draw(r[i]);
        }
        //used for checking sizes, all values including the one in the Snake::extend() function, all are the same
        std::cout << snake.v.size() << std::endl;
        std::cout << snake.length   << std::endl;
        window.display();
    }

    return 0;
}

请注意,尚未使用Apple类,但计划在Snake类的extend()函数起作用时使用。 与尾巴矢量的大小有关的所有提示都相同,但是仅渲染头部尾巴。 看起来像这样: Snake game picture

控件和速度也在起作用。这可能是愚蠢的,但我无法适应。窗口仅在开始时清除,因此这不成问题。感谢您的所有帮助!

编辑 我想用extend()函数扩展尾巴向量,所以要在尾巴之前的地方渲染尾巴,然后像蛇游戏一样正常工作

1 个答案:

答案 0 :(得分:0)

这是一个愚蠢的错误,感谢@texus向我展示。 用这个替换负责传递坐标的循环:

for(int i = snake.length-1; i > 0; i--)

工作

编辑:

我用@texus表示的双端队列重写了代码