Snake game using SFML CPP
up vote
6
down vote
favorite
I made using SFML my first game project.
It's a snake game, and I used 2 custom classes:
- snake
- fruit (snake grow by 1 when eat it)
Here's main.cpp code:
#include <SFML/Graphics.hpp>
#include "snake.h"
#include "fruit.h"
int main()
{
sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");
snake snake;
fruit fruit;
snake.fruitptr = &fruit;
snake.window = &app;
while (app.isOpen())
{
// Process events
sf::Event event;
while (app.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
app.close();
}
snake.movement();
snake.checkCollisions();
app.clear();
app.draw(fruit);
app.draw(snake);
app.display();
}
return EXIT_SUCCESS;
}
Fruit and Snake header
#ifndef SNAKE_H
#define SNAKE_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "fruit.h"
class snake : public sf::Drawable
{
public:
snake();
virtual ~snake();
void movement();
void addElement();
void checkCollisions();
fruit* fruitptr;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
sf::RectangleShape oldPosition;
sf::RenderWindow* window;
private:
float a, b;
float x, y;
int length;
sf::Time time;
sf::RectangleShape shape;
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
};
#endif // SNAKE_H
#ifndef FRUIT_H
#define FRUIT_H
#include <SFML/Graphics.hpp>
#include <time.h>
class fruit : public sf::Drawable
{
public:
fruit();
virtual ~fruit();
sf::RectangleShape shape;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
private:
};
#endif // FRUIT_H
And finally the .cpp files:
#include "snake.h"
snake::snake()
{
x = 20.f;
y = 20.f;
length = 0;
time = sf::seconds(0.1f);
shape.setFillColor(sf::Color::Red);
shape.setSize( {20.f,20.f});
shape.setPosition( {20.f,20.f});
}
snake::~snake()
{
//dtor
}
void snake::draw(sf::RenderTarget& target,
sf::RenderStates states) const
{
target.draw(this->shape, states);
if(this->length == 1){
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0] ,states);
}
else if(this->length>1){
for(int i=this->length-1;i>0;i--){
this->snakeBody[i].setPosition(this->snakeBody[i-1].getPosition());
this->snakeBody[i].setFillColor(sf::Color::Red);
this->snakeBody[i].setSize({20.f ,20.f});
target.draw(this->snakeBody[i], states);
}
this->snakeBody[0].setFillColor(sf::Color::Red);
this->snakeBody[0].setSize({20.f , 20.f});
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0], states);
}
}
void snake::movement()
{
this->oldPosition.setPosition(this->shape.getPosition());
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
this->a=0;
this->b=-20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
this->a=-20.f;
this->b=0;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
this->a=0;
this->b=20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
this->a=20.f;
this->b=0;
}
this->shape.move(a,b);
sf::sleep(this->time);
}
void snake::checkCollisions()
{
for(int i=0; i<this->length; i++)
{
if(this->shape.getGlobalBounds().intersects(this->snakeBody[i].getGlobalBounds())){
this->window->close();
std::cout<<"You Lose!"<<std::endl;
}
}
if(this->shape.getGlobalBounds().intersects(this->fruitptr->shape.getGlobalBounds()))
{
this->fruitptr->shape.setPosition( (rand()%40)*20, (rand()%30)*20);
this->addElement();
std::cout<<"+1"<<std::endl;
}
}
void snake::addElement()
{
if(this->length == 0){
this->length++;
snakeBody = new sf::RectangleShape [this->length];
snakeBody[0].setFillColor(sf::Color::Red);
snakeBody[0].setSize({20.f, 20.f});
}
else{
this->snakeBodycopy = new sf::RectangleShape [this->length];
for(int i=0;i<this->length;i++){
this->snakeBodycopy[i].setPosition(this->snakeBody[i].getPosition());
}
this->length++;
delete snakeBody;
this->snakeBody = new sf::RectangleShape [this->length];
for(int i=0;i<this->length-1;i++){
this->snakeBody[i].setPosition(this->snakeBodycopy[i].getPosition());
}
delete snakeBodycopy;
}
}
#include "fruit.h"
fruit::fruit()
{
shape.setFillColor(sf::Color::White);
shape.setSize( {20.f,20.f});
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
}
fruit::~fruit()
{
//dtor
}
void fruit::draw(sf::RenderTarget& target,
sf::RenderStates states) const{
target.draw(this->shape, states);
}
c++ snake-game sfml
New contributor
add a comment |
up vote
6
down vote
favorite
I made using SFML my first game project.
It's a snake game, and I used 2 custom classes:
- snake
- fruit (snake grow by 1 when eat it)
Here's main.cpp code:
#include <SFML/Graphics.hpp>
#include "snake.h"
#include "fruit.h"
int main()
{
sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");
snake snake;
fruit fruit;
snake.fruitptr = &fruit;
snake.window = &app;
while (app.isOpen())
{
// Process events
sf::Event event;
while (app.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
app.close();
}
snake.movement();
snake.checkCollisions();
app.clear();
app.draw(fruit);
app.draw(snake);
app.display();
}
return EXIT_SUCCESS;
}
Fruit and Snake header
#ifndef SNAKE_H
#define SNAKE_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "fruit.h"
class snake : public sf::Drawable
{
public:
snake();
virtual ~snake();
void movement();
void addElement();
void checkCollisions();
fruit* fruitptr;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
sf::RectangleShape oldPosition;
sf::RenderWindow* window;
private:
float a, b;
float x, y;
int length;
sf::Time time;
sf::RectangleShape shape;
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
};
#endif // SNAKE_H
#ifndef FRUIT_H
#define FRUIT_H
#include <SFML/Graphics.hpp>
#include <time.h>
class fruit : public sf::Drawable
{
public:
fruit();
virtual ~fruit();
sf::RectangleShape shape;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
private:
};
#endif // FRUIT_H
And finally the .cpp files:
#include "snake.h"
snake::snake()
{
x = 20.f;
y = 20.f;
length = 0;
time = sf::seconds(0.1f);
shape.setFillColor(sf::Color::Red);
shape.setSize( {20.f,20.f});
shape.setPosition( {20.f,20.f});
}
snake::~snake()
{
//dtor
}
void snake::draw(sf::RenderTarget& target,
sf::RenderStates states) const
{
target.draw(this->shape, states);
if(this->length == 1){
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0] ,states);
}
else if(this->length>1){
for(int i=this->length-1;i>0;i--){
this->snakeBody[i].setPosition(this->snakeBody[i-1].getPosition());
this->snakeBody[i].setFillColor(sf::Color::Red);
this->snakeBody[i].setSize({20.f ,20.f});
target.draw(this->snakeBody[i], states);
}
this->snakeBody[0].setFillColor(sf::Color::Red);
this->snakeBody[0].setSize({20.f , 20.f});
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0], states);
}
}
void snake::movement()
{
this->oldPosition.setPosition(this->shape.getPosition());
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
this->a=0;
this->b=-20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
this->a=-20.f;
this->b=0;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
this->a=0;
this->b=20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
this->a=20.f;
this->b=0;
}
this->shape.move(a,b);
sf::sleep(this->time);
}
void snake::checkCollisions()
{
for(int i=0; i<this->length; i++)
{
if(this->shape.getGlobalBounds().intersects(this->snakeBody[i].getGlobalBounds())){
this->window->close();
std::cout<<"You Lose!"<<std::endl;
}
}
if(this->shape.getGlobalBounds().intersects(this->fruitptr->shape.getGlobalBounds()))
{
this->fruitptr->shape.setPosition( (rand()%40)*20, (rand()%30)*20);
this->addElement();
std::cout<<"+1"<<std::endl;
}
}
void snake::addElement()
{
if(this->length == 0){
this->length++;
snakeBody = new sf::RectangleShape [this->length];
snakeBody[0].setFillColor(sf::Color::Red);
snakeBody[0].setSize({20.f, 20.f});
}
else{
this->snakeBodycopy = new sf::RectangleShape [this->length];
for(int i=0;i<this->length;i++){
this->snakeBodycopy[i].setPosition(this->snakeBody[i].getPosition());
}
this->length++;
delete snakeBody;
this->snakeBody = new sf::RectangleShape [this->length];
for(int i=0;i<this->length-1;i++){
this->snakeBody[i].setPosition(this->snakeBodycopy[i].getPosition());
}
delete snakeBodycopy;
}
}
#include "fruit.h"
fruit::fruit()
{
shape.setFillColor(sf::Color::White);
shape.setSize( {20.f,20.f});
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
}
fruit::~fruit()
{
//dtor
}
void fruit::draw(sf::RenderTarget& target,
sf::RenderStates states) const{
target.draw(this->shape, states);
}
c++ snake-game sfml
New contributor
Some of your indentation is off. Is this a side-effect of posting on stackexchange or is this how it appears in your editor?
– bruglesco
2 days ago
add a comment |
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I made using SFML my first game project.
It's a snake game, and I used 2 custom classes:
- snake
- fruit (snake grow by 1 when eat it)
Here's main.cpp code:
#include <SFML/Graphics.hpp>
#include "snake.h"
#include "fruit.h"
int main()
{
sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");
snake snake;
fruit fruit;
snake.fruitptr = &fruit;
snake.window = &app;
while (app.isOpen())
{
// Process events
sf::Event event;
while (app.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
app.close();
}
snake.movement();
snake.checkCollisions();
app.clear();
app.draw(fruit);
app.draw(snake);
app.display();
}
return EXIT_SUCCESS;
}
Fruit and Snake header
#ifndef SNAKE_H
#define SNAKE_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "fruit.h"
class snake : public sf::Drawable
{
public:
snake();
virtual ~snake();
void movement();
void addElement();
void checkCollisions();
fruit* fruitptr;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
sf::RectangleShape oldPosition;
sf::RenderWindow* window;
private:
float a, b;
float x, y;
int length;
sf::Time time;
sf::RectangleShape shape;
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
};
#endif // SNAKE_H
#ifndef FRUIT_H
#define FRUIT_H
#include <SFML/Graphics.hpp>
#include <time.h>
class fruit : public sf::Drawable
{
public:
fruit();
virtual ~fruit();
sf::RectangleShape shape;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
private:
};
#endif // FRUIT_H
And finally the .cpp files:
#include "snake.h"
snake::snake()
{
x = 20.f;
y = 20.f;
length = 0;
time = sf::seconds(0.1f);
shape.setFillColor(sf::Color::Red);
shape.setSize( {20.f,20.f});
shape.setPosition( {20.f,20.f});
}
snake::~snake()
{
//dtor
}
void snake::draw(sf::RenderTarget& target,
sf::RenderStates states) const
{
target.draw(this->shape, states);
if(this->length == 1){
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0] ,states);
}
else if(this->length>1){
for(int i=this->length-1;i>0;i--){
this->snakeBody[i].setPosition(this->snakeBody[i-1].getPosition());
this->snakeBody[i].setFillColor(sf::Color::Red);
this->snakeBody[i].setSize({20.f ,20.f});
target.draw(this->snakeBody[i], states);
}
this->snakeBody[0].setFillColor(sf::Color::Red);
this->snakeBody[0].setSize({20.f , 20.f});
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0], states);
}
}
void snake::movement()
{
this->oldPosition.setPosition(this->shape.getPosition());
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
this->a=0;
this->b=-20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
this->a=-20.f;
this->b=0;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
this->a=0;
this->b=20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
this->a=20.f;
this->b=0;
}
this->shape.move(a,b);
sf::sleep(this->time);
}
void snake::checkCollisions()
{
for(int i=0; i<this->length; i++)
{
if(this->shape.getGlobalBounds().intersects(this->snakeBody[i].getGlobalBounds())){
this->window->close();
std::cout<<"You Lose!"<<std::endl;
}
}
if(this->shape.getGlobalBounds().intersects(this->fruitptr->shape.getGlobalBounds()))
{
this->fruitptr->shape.setPosition( (rand()%40)*20, (rand()%30)*20);
this->addElement();
std::cout<<"+1"<<std::endl;
}
}
void snake::addElement()
{
if(this->length == 0){
this->length++;
snakeBody = new sf::RectangleShape [this->length];
snakeBody[0].setFillColor(sf::Color::Red);
snakeBody[0].setSize({20.f, 20.f});
}
else{
this->snakeBodycopy = new sf::RectangleShape [this->length];
for(int i=0;i<this->length;i++){
this->snakeBodycopy[i].setPosition(this->snakeBody[i].getPosition());
}
this->length++;
delete snakeBody;
this->snakeBody = new sf::RectangleShape [this->length];
for(int i=0;i<this->length-1;i++){
this->snakeBody[i].setPosition(this->snakeBodycopy[i].getPosition());
}
delete snakeBodycopy;
}
}
#include "fruit.h"
fruit::fruit()
{
shape.setFillColor(sf::Color::White);
shape.setSize( {20.f,20.f});
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
}
fruit::~fruit()
{
//dtor
}
void fruit::draw(sf::RenderTarget& target,
sf::RenderStates states) const{
target.draw(this->shape, states);
}
c++ snake-game sfml
New contributor
I made using SFML my first game project.
It's a snake game, and I used 2 custom classes:
- snake
- fruit (snake grow by 1 when eat it)
Here's main.cpp code:
#include <SFML/Graphics.hpp>
#include "snake.h"
#include "fruit.h"
int main()
{
sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");
snake snake;
fruit fruit;
snake.fruitptr = &fruit;
snake.window = &app;
while (app.isOpen())
{
// Process events
sf::Event event;
while (app.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
app.close();
}
snake.movement();
snake.checkCollisions();
app.clear();
app.draw(fruit);
app.draw(snake);
app.display();
}
return EXIT_SUCCESS;
}
Fruit and Snake header
#ifndef SNAKE_H
#define SNAKE_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "fruit.h"
class snake : public sf::Drawable
{
public:
snake();
virtual ~snake();
void movement();
void addElement();
void checkCollisions();
fruit* fruitptr;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
sf::RectangleShape oldPosition;
sf::RenderWindow* window;
private:
float a, b;
float x, y;
int length;
sf::Time time;
sf::RectangleShape shape;
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
};
#endif // SNAKE_H
#ifndef FRUIT_H
#define FRUIT_H
#include <SFML/Graphics.hpp>
#include <time.h>
class fruit : public sf::Drawable
{
public:
fruit();
virtual ~fruit();
sf::RectangleShape shape;
virtual void draw(sf::RenderTarget& target,
sf::RenderStates states) const;
private:
};
#endif // FRUIT_H
And finally the .cpp files:
#include "snake.h"
snake::snake()
{
x = 20.f;
y = 20.f;
length = 0;
time = sf::seconds(0.1f);
shape.setFillColor(sf::Color::Red);
shape.setSize( {20.f,20.f});
shape.setPosition( {20.f,20.f});
}
snake::~snake()
{
//dtor
}
void snake::draw(sf::RenderTarget& target,
sf::RenderStates states) const
{
target.draw(this->shape, states);
if(this->length == 1){
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0] ,states);
}
else if(this->length>1){
for(int i=this->length-1;i>0;i--){
this->snakeBody[i].setPosition(this->snakeBody[i-1].getPosition());
this->snakeBody[i].setFillColor(sf::Color::Red);
this->snakeBody[i].setSize({20.f ,20.f});
target.draw(this->snakeBody[i], states);
}
this->snakeBody[0].setFillColor(sf::Color::Red);
this->snakeBody[0].setSize({20.f , 20.f});
this->snakeBody[0].setPosition(this->oldPosition.getPosition());
target.draw(this->snakeBody[0], states);
}
}
void snake::movement()
{
this->oldPosition.setPosition(this->shape.getPosition());
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
this->a=0;
this->b=-20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
this->a=-20.f;
this->b=0;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
this->a=0;
this->b=20.f;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
this->a=20.f;
this->b=0;
}
this->shape.move(a,b);
sf::sleep(this->time);
}
void snake::checkCollisions()
{
for(int i=0; i<this->length; i++)
{
if(this->shape.getGlobalBounds().intersects(this->snakeBody[i].getGlobalBounds())){
this->window->close();
std::cout<<"You Lose!"<<std::endl;
}
}
if(this->shape.getGlobalBounds().intersects(this->fruitptr->shape.getGlobalBounds()))
{
this->fruitptr->shape.setPosition( (rand()%40)*20, (rand()%30)*20);
this->addElement();
std::cout<<"+1"<<std::endl;
}
}
void snake::addElement()
{
if(this->length == 0){
this->length++;
snakeBody = new sf::RectangleShape [this->length];
snakeBody[0].setFillColor(sf::Color::Red);
snakeBody[0].setSize({20.f, 20.f});
}
else{
this->snakeBodycopy = new sf::RectangleShape [this->length];
for(int i=0;i<this->length;i++){
this->snakeBodycopy[i].setPosition(this->snakeBody[i].getPosition());
}
this->length++;
delete snakeBody;
this->snakeBody = new sf::RectangleShape [this->length];
for(int i=0;i<this->length-1;i++){
this->snakeBody[i].setPosition(this->snakeBodycopy[i].getPosition());
}
delete snakeBodycopy;
}
}
#include "fruit.h"
fruit::fruit()
{
shape.setFillColor(sf::Color::White);
shape.setSize( {20.f,20.f});
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
}
fruit::~fruit()
{
//dtor
}
void fruit::draw(sf::RenderTarget& target,
sf::RenderStates states) const{
target.draw(this->shape, states);
}
c++ snake-game sfml
c++ snake-game sfml
New contributor
New contributor
edited 2 days ago
200_success
127k15148411
127k15148411
New contributor
asked 2 days ago
qmwnebrv
311
311
New contributor
New contributor
Some of your indentation is off. Is this a side-effect of posting on stackexchange or is this how it appears in your editor?
– bruglesco
2 days ago
add a comment |
Some of your indentation is off. Is this a side-effect of posting on stackexchange or is this how it appears in your editor?
– bruglesco
2 days ago
Some of your indentation is off. Is this a side-effect of posting on stackexchange or is this how it appears in your editor?
– bruglesco
2 days ago
Some of your indentation is off. Is this a side-effect of posting on stackexchange or is this how it appears in your editor?
– bruglesco
2 days ago
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
Here are a list of things that I notice here.
Indentation and Spacing
Throughout your code, your indentation and spacing is inconsistent. I would recommend picking a specific tab width and setting this either to 1 tab or the respective amount of spaces. In addition, placing spaces around all operators and before braces will create clarity.
Useless Destructor
snake::~snake()
{
//dtor
}
If you don't plan on using your destructor, then adding an implementation is unnecessary.
Usage of this
Looking through your classes, I notice that you prefix everything with this->
, even though this is unnecessary in C++. If you really need to separate local variables from members, then I would recommend a good naming convention (I use a trailing underscore).
Random Numbers
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
In C++, using the <random>
header is recommended over plain old rand()
(which you didn't seed with srand()
, AFAICT so the fruit location will always be the same every run of the game).
Use of std::endl
Unless your goal is to specifically flush the console, then you shouldn't be using std::endl
. Prefer plain old n
instead.
A Proper Fixed Timestep
sf::sleep(this->time);
In most games, what you want to aim for is a proper fixed timestep, which helps create deterministic runs with use of delta times in between frames. Good beginner SFML tutorials/books usually cover this and it is a must for a good game loop.
add a comment |
up vote
0
down vote
One thing that jumps off the page immediately is that you are dealing with raw pointer management (via new and delete). In 2018, it should be very rare that a casual programmer need to do this. There are a lot of good reasons not to.
Some of the most compelling reasons involve moving/assigning/copying objects...and you're not doing that yet, since you just have one snake and one fruit. But even still, you have a memory leak, just because your addElement()
routine does allocations of the snakeBody
with new
that it never frees in the destructor.
(Note: You'd do well to go ahead and start running something like Valgrind or Address Sanitizer, or Dr. Memory on Windows, so you get a report of memory leaks and errors. But you should have a lot fewer of them if you learn and follow modern practices.)
learn and use std::vector
Your entire addElement() routine is essentially trying to implement the std::vector container's push_back()
. If you're trying to learn low-level memory management on purpose, I'd encourage you to do it by breaking off that task into writing a my_vector
class.
But if you're doing it because you don't know what a std::vector is, then I'd certainly urge you to look through a tutorial. Here's one and another I can find offhand on the present-day web.
So #include <vector>
in your project, and start by changing:
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
into:
std::vector<sf::RectangleShape> snakeBody;
Tutorials and reference guides should hopefully give you enough examples to adapt your program to that change and keep it working. If not, you can ask for help on StackOverflow. It may not seem easy at first, but it really is easier and less error prone than what you're attempting here.
start remembering the catchphrase: "Rule of Zero"
You don't have to fully absorb what "rule of zero" means yet...but maybe read around on it and start getting the inkling that it's important. It applies to why you don't want raw pointers in your classes.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Here are a list of things that I notice here.
Indentation and Spacing
Throughout your code, your indentation and spacing is inconsistent. I would recommend picking a specific tab width and setting this either to 1 tab or the respective amount of spaces. In addition, placing spaces around all operators and before braces will create clarity.
Useless Destructor
snake::~snake()
{
//dtor
}
If you don't plan on using your destructor, then adding an implementation is unnecessary.
Usage of this
Looking through your classes, I notice that you prefix everything with this->
, even though this is unnecessary in C++. If you really need to separate local variables from members, then I would recommend a good naming convention (I use a trailing underscore).
Random Numbers
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
In C++, using the <random>
header is recommended over plain old rand()
(which you didn't seed with srand()
, AFAICT so the fruit location will always be the same every run of the game).
Use of std::endl
Unless your goal is to specifically flush the console, then you shouldn't be using std::endl
. Prefer plain old n
instead.
A Proper Fixed Timestep
sf::sleep(this->time);
In most games, what you want to aim for is a proper fixed timestep, which helps create deterministic runs with use of delta times in between frames. Good beginner SFML tutorials/books usually cover this and it is a must for a good game loop.
add a comment |
up vote
1
down vote
Here are a list of things that I notice here.
Indentation and Spacing
Throughout your code, your indentation and spacing is inconsistent. I would recommend picking a specific tab width and setting this either to 1 tab or the respective amount of spaces. In addition, placing spaces around all operators and before braces will create clarity.
Useless Destructor
snake::~snake()
{
//dtor
}
If you don't plan on using your destructor, then adding an implementation is unnecessary.
Usage of this
Looking through your classes, I notice that you prefix everything with this->
, even though this is unnecessary in C++. If you really need to separate local variables from members, then I would recommend a good naming convention (I use a trailing underscore).
Random Numbers
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
In C++, using the <random>
header is recommended over plain old rand()
(which you didn't seed with srand()
, AFAICT so the fruit location will always be the same every run of the game).
Use of std::endl
Unless your goal is to specifically flush the console, then you shouldn't be using std::endl
. Prefer plain old n
instead.
A Proper Fixed Timestep
sf::sleep(this->time);
In most games, what you want to aim for is a proper fixed timestep, which helps create deterministic runs with use of delta times in between frames. Good beginner SFML tutorials/books usually cover this and it is a must for a good game loop.
add a comment |
up vote
1
down vote
up vote
1
down vote
Here are a list of things that I notice here.
Indentation and Spacing
Throughout your code, your indentation and spacing is inconsistent. I would recommend picking a specific tab width and setting this either to 1 tab or the respective amount of spaces. In addition, placing spaces around all operators and before braces will create clarity.
Useless Destructor
snake::~snake()
{
//dtor
}
If you don't plan on using your destructor, then adding an implementation is unnecessary.
Usage of this
Looking through your classes, I notice that you prefix everything with this->
, even though this is unnecessary in C++. If you really need to separate local variables from members, then I would recommend a good naming convention (I use a trailing underscore).
Random Numbers
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
In C++, using the <random>
header is recommended over plain old rand()
(which you didn't seed with srand()
, AFAICT so the fruit location will always be the same every run of the game).
Use of std::endl
Unless your goal is to specifically flush the console, then you shouldn't be using std::endl
. Prefer plain old n
instead.
A Proper Fixed Timestep
sf::sleep(this->time);
In most games, what you want to aim for is a proper fixed timestep, which helps create deterministic runs with use of delta times in between frames. Good beginner SFML tutorials/books usually cover this and it is a must for a good game loop.
Here are a list of things that I notice here.
Indentation and Spacing
Throughout your code, your indentation and spacing is inconsistent. I would recommend picking a specific tab width and setting this either to 1 tab or the respective amount of spaces. In addition, placing spaces around all operators and before braces will create clarity.
Useless Destructor
snake::~snake()
{
//dtor
}
If you don't plan on using your destructor, then adding an implementation is unnecessary.
Usage of this
Looking through your classes, I notice that you prefix everything with this->
, even though this is unnecessary in C++. If you really need to separate local variables from members, then I would recommend a good naming convention (I use a trailing underscore).
Random Numbers
shape.setPosition( (rand()%40)*20, (rand()%30)*20);
In C++, using the <random>
header is recommended over plain old rand()
(which you didn't seed with srand()
, AFAICT so the fruit location will always be the same every run of the game).
Use of std::endl
Unless your goal is to specifically flush the console, then you shouldn't be using std::endl
. Prefer plain old n
instead.
A Proper Fixed Timestep
sf::sleep(this->time);
In most games, what you want to aim for is a proper fixed timestep, which helps create deterministic runs with use of delta times in between frames. Good beginner SFML tutorials/books usually cover this and it is a must for a good game loop.
answered 2 days ago
Arnav Borborah
693120
693120
add a comment |
add a comment |
up vote
0
down vote
One thing that jumps off the page immediately is that you are dealing with raw pointer management (via new and delete). In 2018, it should be very rare that a casual programmer need to do this. There are a lot of good reasons not to.
Some of the most compelling reasons involve moving/assigning/copying objects...and you're not doing that yet, since you just have one snake and one fruit. But even still, you have a memory leak, just because your addElement()
routine does allocations of the snakeBody
with new
that it never frees in the destructor.
(Note: You'd do well to go ahead and start running something like Valgrind or Address Sanitizer, or Dr. Memory on Windows, so you get a report of memory leaks and errors. But you should have a lot fewer of them if you learn and follow modern practices.)
learn and use std::vector
Your entire addElement() routine is essentially trying to implement the std::vector container's push_back()
. If you're trying to learn low-level memory management on purpose, I'd encourage you to do it by breaking off that task into writing a my_vector
class.
But if you're doing it because you don't know what a std::vector is, then I'd certainly urge you to look through a tutorial. Here's one and another I can find offhand on the present-day web.
So #include <vector>
in your project, and start by changing:
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
into:
std::vector<sf::RectangleShape> snakeBody;
Tutorials and reference guides should hopefully give you enough examples to adapt your program to that change and keep it working. If not, you can ask for help on StackOverflow. It may not seem easy at first, but it really is easier and less error prone than what you're attempting here.
start remembering the catchphrase: "Rule of Zero"
You don't have to fully absorb what "rule of zero" means yet...but maybe read around on it and start getting the inkling that it's important. It applies to why you don't want raw pointers in your classes.
add a comment |
up vote
0
down vote
One thing that jumps off the page immediately is that you are dealing with raw pointer management (via new and delete). In 2018, it should be very rare that a casual programmer need to do this. There are a lot of good reasons not to.
Some of the most compelling reasons involve moving/assigning/copying objects...and you're not doing that yet, since you just have one snake and one fruit. But even still, you have a memory leak, just because your addElement()
routine does allocations of the snakeBody
with new
that it never frees in the destructor.
(Note: You'd do well to go ahead and start running something like Valgrind or Address Sanitizer, or Dr. Memory on Windows, so you get a report of memory leaks and errors. But you should have a lot fewer of them if you learn and follow modern practices.)
learn and use std::vector
Your entire addElement() routine is essentially trying to implement the std::vector container's push_back()
. If you're trying to learn low-level memory management on purpose, I'd encourage you to do it by breaking off that task into writing a my_vector
class.
But if you're doing it because you don't know what a std::vector is, then I'd certainly urge you to look through a tutorial. Here's one and another I can find offhand on the present-day web.
So #include <vector>
in your project, and start by changing:
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
into:
std::vector<sf::RectangleShape> snakeBody;
Tutorials and reference guides should hopefully give you enough examples to adapt your program to that change and keep it working. If not, you can ask for help on StackOverflow. It may not seem easy at first, but it really is easier and less error prone than what you're attempting here.
start remembering the catchphrase: "Rule of Zero"
You don't have to fully absorb what "rule of zero" means yet...but maybe read around on it and start getting the inkling that it's important. It applies to why you don't want raw pointers in your classes.
add a comment |
up vote
0
down vote
up vote
0
down vote
One thing that jumps off the page immediately is that you are dealing with raw pointer management (via new and delete). In 2018, it should be very rare that a casual programmer need to do this. There are a lot of good reasons not to.
Some of the most compelling reasons involve moving/assigning/copying objects...and you're not doing that yet, since you just have one snake and one fruit. But even still, you have a memory leak, just because your addElement()
routine does allocations of the snakeBody
with new
that it never frees in the destructor.
(Note: You'd do well to go ahead and start running something like Valgrind or Address Sanitizer, or Dr. Memory on Windows, so you get a report of memory leaks and errors. But you should have a lot fewer of them if you learn and follow modern practices.)
learn and use std::vector
Your entire addElement() routine is essentially trying to implement the std::vector container's push_back()
. If you're trying to learn low-level memory management on purpose, I'd encourage you to do it by breaking off that task into writing a my_vector
class.
But if you're doing it because you don't know what a std::vector is, then I'd certainly urge you to look through a tutorial. Here's one and another I can find offhand on the present-day web.
So #include <vector>
in your project, and start by changing:
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
into:
std::vector<sf::RectangleShape> snakeBody;
Tutorials and reference guides should hopefully give you enough examples to adapt your program to that change and keep it working. If not, you can ask for help on StackOverflow. It may not seem easy at first, but it really is easier and less error prone than what you're attempting here.
start remembering the catchphrase: "Rule of Zero"
You don't have to fully absorb what "rule of zero" means yet...but maybe read around on it and start getting the inkling that it's important. It applies to why you don't want raw pointers in your classes.
One thing that jumps off the page immediately is that you are dealing with raw pointer management (via new and delete). In 2018, it should be very rare that a casual programmer need to do this. There are a lot of good reasons not to.
Some of the most compelling reasons involve moving/assigning/copying objects...and you're not doing that yet, since you just have one snake and one fruit. But even still, you have a memory leak, just because your addElement()
routine does allocations of the snakeBody
with new
that it never frees in the destructor.
(Note: You'd do well to go ahead and start running something like Valgrind or Address Sanitizer, or Dr. Memory on Windows, so you get a report of memory leaks and errors. But you should have a lot fewer of them if you learn and follow modern practices.)
learn and use std::vector
Your entire addElement() routine is essentially trying to implement the std::vector container's push_back()
. If you're trying to learn low-level memory management on purpose, I'd encourage you to do it by breaking off that task into writing a my_vector
class.
But if you're doing it because you don't know what a std::vector is, then I'd certainly urge you to look through a tutorial. Here's one and another I can find offhand on the present-day web.
So #include <vector>
in your project, and start by changing:
sf::RectangleShape* snakeBody;
sf::RectangleShape* snakeBodycopy;
into:
std::vector<sf::RectangleShape> snakeBody;
Tutorials and reference guides should hopefully give you enough examples to adapt your program to that change and keep it working. If not, you can ask for help on StackOverflow. It may not seem easy at first, but it really is easier and less error prone than what you're attempting here.
start remembering the catchphrase: "Rule of Zero"
You don't have to fully absorb what "rule of zero" means yet...but maybe read around on it and start getting the inkling that it's important. It applies to why you don't want raw pointers in your classes.
edited yesterday
answered 2 days ago
HostileFork
803521
803521
add a comment |
add a comment |
qmwnebrv is a new contributor. Be nice, and check out our Code of Conduct.
qmwnebrv is a new contributor. Be nice, and check out our Code of Conduct.
qmwnebrv is a new contributor. Be nice, and check out our Code of Conduct.
qmwnebrv is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208378%2fsnake-game-using-sfml-cpp%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Some of your indentation is off. Is this a side-effect of posting on stackexchange or is this how it appears in your editor?
– bruglesco
2 days ago