I am starting with SFML, and wanted to do a Snake game. I am on linux(Kali 2018), using the prebuild gnu g++ compiler. Using commands:
g++ -c snake.cpp
g++ snake.o -o snake -lsfml-graphics -lsfml-window -lsfml-system
It compiles just fine, runs without An error. Heres the 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;
}
Note that the Apple class isnt used, yet, but is planed to be used when the extend() function from the Snake class will work.
All the cout's relating to the size of the Tails vector are the same, But it render only the head Tail.
Looks like this:
The controls and speed is working too. It's probably something stupid but I could't get up with something. The window clears only at the begining so that shouldn't be a problem. Thanks to all your help!
EDIT I want the extend() function to extend the tails vector, so taht the Tail is rendered there where the tail before it was and then behave normally like in a snake game
It was a dumb mistake, thanks for @texus for showing me. replacing the loop responsible for giving over the coordinates with this:
for(int i = snake.length-1; i > 0; i--)
worked
EDIT:
I rewrote the code with a deque as sugested by @texus