I have begun learning SFML at the same time as C++ and do not understand the rules of using & and * in RenderWindow case. Could you help me?
Main class:
#include <SFML/Graphics.hpp>
#include "Square.h"
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
Square sq(5,5);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
sq.draw(&window);
window.display();
}
return 0;
}
Square header:
#ifndef SQUARE_H
#define SQUARE_H
class Square
{
private:
sf::RenderWindow* window;
sf::RectangleShape rectangle;
int y;
int x;
public:
Square(int coordX, int coordY);
Square();
void draw(const sf::RenderWindow* target);
};
#endif
Square class:
#include <SFML/Graphics.hpp>
class Square{
sf::RectangleShape rectangle;
int y;
int x;
public:
Square(int coordX, int coordY)
: rectangle(), y(coordY),x(coordX)
{
rectangle.setSize(sf::Vector2f(10,100));
rectangle.setOrigin(5,50);
}
Square()
: rectangle(), y(5),x(5)
{
rectangle.setSize(sf::Vector2f(10,100));
rectangle.setOrigin(5,50);
}
void draw(sf::RenderWindow* target)
{
target->draw(rectangle);
}
I can't draw a square on RenderWindow:
main.cpp:(.text+0x17d): undefined reference to `Square::Square(int, int)'
main.cpp:(.text+0x211): undefined reference to `Square::draw(sf::RenderWindow const*)'
How can I make this work?
In C++, you have function declaration and function definition:
// declaration, typically in X.h
#pragma once // don't include this twice, my dear compiler
class X {
public:
void foo();
};
Implementation:
// X.cpp
#include "X.h"
void X::foo() { ...code .... }
// here you wrote
// class X { void foo(){} };
// which is a _declaration_ of class X
// with an _inline definition_ of foo.
Usage:
// main.cpp
#include "X.h"
Applying this pattern to your code should ensure that
every symbol is defined
no symbol is defined more than once
Remove square.cpp and change your square.h file to the following. Make sure you take back-up before changing your files.
#ifndef SQUARE_H
#define SQUARE_H
class Square
{
private:
sf::RenderWindow* window;
sf::RectangleShape rectangle;
int y;
int x;
public:
Square(int coordX, int coordY)
: rectangle(), y(coordY),x(coordX)
{
rectangle.setSize(sf::Vector2f(10,100));
rectangle.setOrigin(5,50);
}
Square()
: rectangle(), y(5),x(5)
{
rectangle.setSize(sf::Vector2f(10,100));
rectangle.setOrigin(5,50);
}
void draw(sf::RenderWindow* target)
{
target->draw(rectangle);
}
};
#endif
Related
I'm trying to code a simple game, where the main.cpp file instantiates the Game class, and the Game class instantiates the Player class. I want the Player class to have access to the Game class' variables, so I guess the best way to do that is to have the Game class pass itself to the Player class:
game.h
#pragma once
#include <raylib.h>
#include "player.h"
class Game
{
public:
Game();
void run();
private:
void update();
void draw();
Player player;
};
game.cpp
#include "game.h"
Game::Game() : player(this, { 0, 0, 0 })
{
}
void Game::run()
{
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "teste");
SetTargetFPS(60);
while (!WindowShouldClose())
{
update();
draw();
}
CloseWindow();
}
void Game::update()
{
player.update();
}
void Game::draw()
{
BeginDrawing();
ClearBackground(RAYWHITE);
EndDrawing();
}
player.h
#pragma once
#include <raylib.h>
#include "game.h"
class Player
{
public:
Player(Game* game, Vector3 pos);
void update();
void draw();
Game* game;
Vector3 pos;
};
player.cpp
#include "player.h"
Player::Player(Game* game, Vector3 pos)
{
this->game = game;
this->pos = pos;
speed = .1;
}
void Player::update()
{
if (IsKeyDown(KEY_D)) pos.x += 1;
if (IsKeyDown(KEY_A)) pos.x += -1;
if (IsKeyDown(KEY_S)) pos.z += 1;
if (IsKeyDown(KEY_W)) pos.z += -1;
}
void Player::draw()
{
}
The code seems fine to Intellisense, but the compiler just throws a bunch of errors.
I tried passing this as an argument to the Player class constructor, but it didn't work out, as the compiler doesn't accept it.
You have a circular dependency between your header files.
game.h depends on player.h, because the Game::player member is a Player instance, not a Player* pointer or Player& reference, so the complete Player class declaration is needed. This is fine.
However, player.h depends on game.h, but Game hasn't been declared yet (because of the header guard in game.h) when the Player class declaration is compiled.
Since the Player::game member is just a Game* pointer, you can use a forward declaration to break that header dependency, eg:
game.h
#pragma once
//#include <raylib.h> // <-- game.h doesn't use anything from this, so move it to game.cpp
#include "player.h" // <-- needed here because of Game::player
class Game
{
public:
Game();
void run();
private:
void update();
void draw();
Player player;
};
game.cpp
#include "game.h"
#include <raylib.h> // <-- move here
Game::Game() : player(this, { 0, 0, 0 })
{
}
...
player.h
#pragma once
#include <raylib.h> // <-- leave here if it declares Vector3
//#include "game.h" // <-- move to player.cpp
class Game; // <-- use this forward declaration instead
class Player
{
public:
Player(Game* game, Vector3 pos);
void update();
void draw();
Game* game;
Vector3 pos;
};
player.cpp
#include "player.h"
#include "game.h" // <-- move here
Player::Player(Game* game, Vector3 pos)
{
this->game = game;
...
}
...
In short, a header file should #include only the things it actually uses directly. Anything else should be #include'd in the .cpp file instead. But, anything in a header file that is just a pointer or reference can be forward-declared without using an #include. Keep your #includes to a minimum in header files. The compilation process will be cleaner and more efficient because of it.
I have only just started learning C++ yesterday, so im completely new, although I came over from Java.
I am making a game as my first small project.
I want to have my player class separate from the main file.
I have my header file and cpp file made up like this:
Header:
#pragma once
#include <SFML/Graphics.hpp>
#include <iostream>
class Entity {
public:
Entity(int x, int y, sf::RenderWindow& win) : window(win) {}
void tick();
void render();
private:
int x;
int y;
float velX;
float velY;
sf::RenderWindow& window;
bool keys[264] = {};
};
C++:
#include <SFML/Graphics.hpp>
#include <iostream>
#include "headers/Entity.h"
using namespace sf;
Texture texture;
Sprite sprite;
Entity::Entity(int x, int y, RenderWindow& win) : window(win) {
this->x = x;
this->y = y;
this->velX = 0;
this->velY = 0;
this->window = win;
texture.loadFromFile("../res/img/test.png");
sprite(texture);
}
void Entity::tick() {
// movement
}
void Entity::render() {
this->window.draw(sprite);
}
But in the cpp file the constructor keeps saying:
redefinition of 'Entity::Entity(int, int, sf::RenderWindow&)'
I have searched up many times how to fix this but I can't find anything that works, because this issue carries on no matter what I try. I would prefer the theory aswell as I am brand new with any answer.
Thank You.
Your header is providing a implementation / definition of your constructor:
Entity(int x, int y, sf::RenderWindow& win) : window(win) {}
And so is your source file.
Change the header to just contain the declaration:
Entity(int x, int y, sf::RenderWindow& win);
Remove trailings {} and the link to the super class ctor in the declaration file for the constructor, ie :
class Entity {
public:
Entity(int x, int y, sf::RenderWindow& win);
void tick();
With {} and : window(win) it is no more a declaration but a definition, thus you will have two definitions: one in the header and one in the source...
Remove one of them.
I'm receiving error "Allocating an object of abstract class type 'MainGame" even though all virtual functions have been implemented. Below are the relevant code snippets:
main.cpp
#include "Gamestate_MainGame.h"
int main() {
Game game;
if (game.init(new MainGame))
game.loop();
return 0;
}
Gamestate.h
#ifndef Gamestate_h
#define Gamestate_h
#include <SDL2/SDL.h>
#include "Game.h"
class GameState {
public:
virtual bool init(Graphics* graphics, Game* game) = 0;
virtual void quit() = 0;
virtual void handleEvents(SDL_Event* e) = 0;
virtual void logic() = 0;
virtual void render() = 0;
protected:
Game* game = NULL;
Graphics* graphics = NULL;
};
#endif
Gamestate_MainGame.h
#ifndef Gamestate_MainGame_h
#define Gamestate_MainGame_h
#include <vector>
#include <SDL2_mixer/SDL_mixer.h>
#include "Gamestate.h"
#include "Graphics.h"
#include "Tile.h"
class MainGame : public GameState {
// Gamestate Functions
bool init(Graphics* graphics, Game* game);
void quit();
void handleEvents(SDL_Event& e);
void logic();
void render();
// MainGame functions - make private?
void makeTiles();
void loadPositions(const int & n);
void scrambleTiles(std::vector<Tile> t);
void restart();
bool isSolved();
bool isNeighbor(const Tile& a, const Tile& b);
int getClickedTile(const int& x, const int& y);
private:
Game* game = NULL;
Graphics* graphics = NULL;
int clickedTile { -1 };
int clicks { 0 };
bool gameExit { false };
bool gameWin { true };
bool catMode { true };
std::vector<Tile> tiles;
std::vector<SDL_Rect> positions;
Mix_Chunk* click = NULL;
};
#endif
Game.h
#ifndef Game_h
#define Game_h
#include <vector>
#include <SDL2/SDL.h>
#include "Graphics.h"
class GameState;
class Game {
public:
Game();
bool init(GameState* state);
void loop();
void pushState(GameState* state);
void popState();
void setQuit();
private:
bool quit { false };
Graphics graphics;
SDL_Event event;
std::vector<GameState*> states;
Uint32 new_time;
Uint32 old_time;
//internal loop functions
void update();
void render();
void quitGame(); //will free SDL resources and perform cleanup of states
};
#endif
All MainGame functions are defined in Gamestate_MainGame.cpp. Thank you for your help!
virtual void handleEvents(SDL_Event* e) = 0;
^
is a different prototype than
void handleEvents(SDL_Event& e);
^
You should mark all your overridden functions with override then the compiler will do the heavy lifting for you and tell you whether you messed up or not.
I'm making a game in C++. I have a player and enemy class that inherit my mob class. I would like my constructor in the enemy class to have a different constructor than my mob class, but it doesn't seem to work.
Mob.h
#pragma once
#include <SFML/Graphics.hpp>
class Mob
{
public:
Mob();
~Mob();
void update();
void render();
protected:
static sf::Sprite mSprite;
static float mSpeed;
};
Mob.cpp
#include <SFML/Graphics.hpp>
#include "Enemy.h"
#include "Player.h"
Mob::Mob()
{
}
Mob::~Mob() {
}
Enemy.h
#pragma once
#include <SFML/Graphics.hpp>
#include "Mob.h"
class Enemy : public Mob
{
public:
Enemy(sf::Sprite sprite);
~Enemy();
void update(float delta, Player player);
void render(sf::RenderWindow& window);
};
Enemy.cpp
#include <SFML/Graphics.hpp>
#include "Enemy.h"
#include "Player.h"
Enemy::Enemy(sf::Sprite sprite)
{
mSprite = sprite;
mSpeed = 150.0f;
}
Enemy::~Enemy() {
}
void Enemy::update(float delta, Player player) {
}
void Enemy::render(sf::RenderWindow& window) {
window.draw(mSprite);
}
Player.h
#pragma once
#include <SFML/Graphics.hpp>
#include "Mob.h"
class Player : public Mob
{
public:
Player(sf::Sprite sprite);
~Player();
void update(float delta);
void render(sf::RenderWindow& window);
};
Player.cpp
#include <SFML/Graphics.hpp>
#include "Player.h"
Player::Player(sf::Sprite sprite)
{
mSprite = sprite;
mSpeed = 150.0f;
}
Player::~Player() {
}
void Player::update(float delta) {
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
mSprite.move(0, -mSpeed * delta);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
mSprite.move(-mSpeed * delta, 0);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
mSprite.move(0, mSpeed * delta);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
mSprite.move(mSpeed * delta, 0);
}
}
void Player::render(sf::RenderWindow& window) {
window.draw(mSprite);
}
Forgot to add my errors:
Error 3 error C2511: 'void Enemy::update(float,Player)' : overloaded member function not found in 'Enemy' c:\dev\c++\sven\sven\enemy.cpp 16 1 Sven
Error 1 error C2061: syntax error : identifier 'Player' c:\dev\c++\sven\sven\enemy.h 12 1 Sven
Error 2 error C2061: syntax error : identifier 'Player' c:\dev\c++\sven\sven\enemy.h 12 1 Sven
In Enemy.h you have void update(float delta, Player player);. How does the compiler know what a play is? It cant since you never included the player.h file in enemy.h. You have to options to fix this you can either include player.h or you could forward declare player and change the function to take a pointer to a player.
So I am trying to implement a pong game using sdl but with classes and inheritance.
So I plan to have a base Puck class which defines my paddle. PlayerPuck and EnemyPuck will inherit this base class. The base Puck class handles all the initializations and drawing of the base paddle. From this I am trying to derive a subclass to add extra things on my playerPaddle like checking collisions and bounds etc. But when I try to create objects polymorphically in my main class, it throws me tons of errors.
Here is my Base Puck Header file
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
class Puck{
private:
SDL_Rect puckPaddle;
public:
Puck();
Puck(int x,int y,int width,int height);
int getX();
int getY();
int getHeight();
int getWidth();
SDL_Rect* getPaddleRect();
void setX(int x);
void setY(int y);
void setHeight(int height);
void setWidth(int width);
void Render(); // should be virtual, leave it for now
void Update(); // should be virtual, leave it for now
};
This is just my header file. I have done the implementation in the cpp file already and it works fine.
Now the problem is in my PlayerPuck which I have derived from Puck as follows
#include "Puck.h"
class PlayerPuck : public Puck {
public:
PlayerPuck();
PlayerPuck(int x, int y, int width,int height);
void UpdatePosition();
void CheckBounds();
};
In my main function when I do the following it gives me error like
C2504: 'Puck' base class undefined
error C2440: '=' : cannot convert from 'PlayerPuck *' to 'Puck *'
#include "Ball.h"
#include "Puck.h"
#include "PlayerPuck.h"
Puck* p;
void Initialize(){
if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
running = false;
TTF_Init();
p = new PlayerPuck(50,150,200,100);
}
What is my mistake?
I solved the problem by just adding "PlayerPuck.h" header file and removing the "Puck.h" as there were two same headers in my main function
Now, I am getting linker errors if I try calling virtual functions
in my base Puck class I have defined a virtual function Test()
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
class Puck{
private:
SDL_Rect puckPaddle;
public:
Puck();
Puck(int x,int y,int width,int height);
int getX();
int getY();
int getHeight();
int getWidth();
SDL_Rect* getPaddleRect();
void setX(int x);
void setY(int y);
void setHeight(int height);
void setWidth(int width);
**virtual void Test();** --> here
};
And I have called it in my derived playerPuck class
#include "Puck.h"
class PlayerPuck : public Puck {
public:
PlayerPuck();
PlayerPuck(int x, int y, int width,int height);
void UpdatePosition();
void CheckBounds();
**void Test();** --> here
};
When I create my playerPuck obj in main and try calling that function as below it throws me
LNK2001 - unresolved external symbol error
#include "Ball.h"
#include "PlayerPuck.h"
PlayerPuck* playerPuck;
playerPuck = new PlayerPuck(50,200,20,100);
void Update(){
//playerPuck->UpdatePosition();
playerPuck->Test();
}