我从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()函数起作用时使用。 与尾巴矢量的大小有关的所有提示都相同,但是仅渲染头部尾巴。 看起来像这样:
控件和速度也在起作用。这可能是愚蠢的,但我无法适应。窗口仅在开始时清除,因此这不成问题。感谢您的所有帮助!
编辑 我想用extend()函数扩展尾巴向量,所以要在尾巴之前的地方渲染尾巴,然后像蛇游戏一样正常工作
答案 0 :(得分:0)
这是一个愚蠢的错误,感谢@texus向我展示。 用这个替换负责传递坐标的循环:
for(int i = snake.length-1; i > 0; i--)
工作
编辑:
我用@texus表示的双端队列重写了代码