In SFML I wanted to have a sprite but with other functions and variables so i decided to create a class that inherits the sprite class like this:
1. Player.hpp
#pragma once
#include <stdio.h>
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
class Player : sf::Sprite{
public:
void setup();
void input();
private:
int direction;
void moveRight();
void moveLeft();
sf::Texture textures[8];
};
2(WIP). Player.cpp
void Player::setup(){
direction = 0;
textures[0].loadFromFile("images/player_right_still.png");
textures[1].loadFromFile("images/player_right_jump.png");
textures[2].loadFromFile("images/player_right_walk1.png");
textures[3].loadFromFile("images/player_right_walk2.png");
textures[4].loadFromFile("images/player_left_still.png");
textures[5].loadFromFile("images/player_left_jump.png");
textures[6].loadFromFile("images/player_left_walk1.png");
setTexture(textures[0]);
}
void Player::input(){
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) || sf::Keyboard::isKeyPressed(sf::Keyboard::D)){
moveRight();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Keyboard::isKeyPressed(sf::Keyboard::A)){
moveLeft();
}
}
void Player::moveRight(){
}
void Player::moveLeft(){
}
game.cpp (picture because SO is being weird on me)
But when I compile it I get this error:
game.cpp: In function ‘int main()’:
game.cpp:23:27: error: ‘sf::Drawable’ is an inaccessible base of ‘Player’
window.draw(player);
class Player : sf::Sprite means that inheritance is private, that is code using instances of Player class won't be able to cast it to Sprite or access methods inherited from Sprite class. You should change inheritance to public:
class Player: public sf::Sprite
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 am trying to create by own game engine where each basic is a GameObject which will consist of an update function and other notifiers.
Here is my code so far:
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "AssetManager.hpp"
class GameObject : public sf::Drawable, public sf::Transformable
{
public:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const{
target.draw(*this, states);
};
};
class Sprite : public GameObject, public sf::Sprite {
public:
Sprite(AssetManager assetManager, std::string assetName) : sf::Sprite(){
setTexture(assetManager.getTextureNamed(assetName));
}
};
int main(int argc, char const** argv)
{
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
AssetManager assetManager = AssetManager("/Users/iProgram/Desktop/My Game Engine/My Game Engine");
assetManager.loadTextureWithName("tank", "tank.png", sf::Vector2f(16,16));
Sprite tank = Sprite(assetManager, "tank");
while(window.isOpen()){
window.clear();
window.draw(tank);
window.display();
}
return EXIT_SUCCESS;
}
Please note, the asset manager simply stores textures in memory and returns it when needed with a given size.
The problem is on the line: window.draw(tank);, I am getting the error
Ambiguous conversion from derived class 'const Sprite' to base class 'const sf::Drawable':
Why is this as I have implemented the draw function in the GameObject class and how can I fix it?
Your Sprite class inherits from GameObject which inherits from sf::Drawable. Your class also inherits from sf::Sprite which also inherits from sf::Drawable. Now your Sprite class has 2 inherited sf::Drawable subobjects and the compiler can't choose.
To fix this, either rethink your design or inherit virtually.
To solve this issue, I dod not have to use private inheritance as some suggested, I just needed my base class (GameObject) to inherit nothing. My Sprite class would then inherit sf::Sprite like so:
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "AssetManager.hpp"
class GameObject{
public:
virtual void update(){}
};
class Sprite : public GameObject, public sf::Sprite {
public:
Sprite(AssetManager* assetManager, std::string assetName) : sf::Sprite(assetManager->getTextureNamed(assetName)){
}
};
class Tank: public Sprite{
public:
Tank(AssetManager* assetManager) : Sprite(assetManager, "tank"){
setScale(3, 3);
};
virtual void update(){
move(1,0);
}
};
int main(int argc, char const** argv)
{
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
AssetManager* assetManager = new AssetManager("/Users/iProgram/Desktop/My Game Engine/My Game Engine");
assetManager->loadTextureWithName("tank", "tank.png", sf::Vector2f(16,16));
Tank tank = Tank(assetManager);
while(window.isOpen()){
sf::Event event;
while(window.pollEvent(event)){
if(event.type == sf::Event::Closed){
window.close();
}
}
tank.update();
window.clear();
window.draw(tank);
window.display();
}
return EXIT_SUCCESS;
}
I just started writing a simple game in SFML 2.0.
I created class AABB with inheritance two class from SFML to write in class draw() method.
But i get all the time this error:
\main.cpp|14|error: cannot declare variable 'block' to be of abstract type 'AABB'|
code:
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
#include "headers/system.h"
#include "headers/AABB.h"
using namespace std;
int main()
{
sf::RectangleShape shape(sf::Vector2f(50,50));
AABB block (shape);
System sys;
if(!sys.create())
{
cout << "Critical error! Did you modified ini files?";
return EXIT_FAILURE;
}
sf::RenderWindow * WindowApp = sys.getHandle();
while (WindowApp->isOpen())
{
sf::Event event;
while (WindowApp->pollEvent(event))
{
if (event.type == sf::Event::Closed)
WindowApp->close();
if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
WindowApp->close();
}
WindowApp->draw(block);
WindowApp->clear();
WindowApp->display();
}
return EXIT_SUCCESS;
}
AABB.h:
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#include <SFML\Audio.hpp>
#include <SFML\Network.hpp>
using namespace std;
class AABB : public sf::Drawable, public sf::Transformable
{
public:
AABB(sf::Vector2f pos, sf::Vector2f size) :
m_pos(pos),
m_size(size) {}
AABB(sf::RectangleShape shape) :
m_sprite(shape)
{}
private:
virtual void draw(sf::RenderTarget& target) const ;
private:
sf::Vector2f m_size;
sf::Vector2f m_pos;
sf::RectangleShape m_sprite;
};
AABB.cpp
#include "../headers/AABB.h"
using namespace std;
void AABB::draw(sf::RenderTarget& target) const
{
target.draw(m_sprite);
}
system class is not important here i think :D
BTW when I remove inheritance from class app compile without errors. What i suppose to do ? Please help me :)
Your class AABB inherits sf::Drawable, which is an abstract class, and AABB does not override all pure virtual functions of it -- which would be necessary to make AABB a concrete class and to have objects of it. I suspect that this is the result of a typo. Where you write
virtual void draw(sf::RenderTarget& target) const ;
in AABB.h, it should be
virtual void draw(sf::RenderTarget& target, sf::RenderStates) const ;
because the latter is the signature of sf::Drawable's pure virtual function, as is described in the SFML documentation. You will have to change the definition of this function in AABB.cpp as well, naturally.
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.
I have a class called "Game", with prototypes functions "Update" and "Draw" but they're not defined. It's up to the object inheriting the "Game" object to override them. Is this possible?
Contents of "Game.h"
class Game // does it have to abstract/virtual?
{
public:
//General stuff for all games here
}
void Update(Game *game) = 0; // or make it virtual in someway
Contents of "MyGame.h"
#include "Game.h"
class MyGame : public Game
{
public:
// General stuff for my game
}
void Update(MyGame *game);
// Contents of "MyGame.cpp"
#include "MyGame.h"
void Update(MyGame *game) // does it have to be overriden/overloaded?
{
}
// Contents of "GameManager.h"
#include "Game.h"
class GameManager
{
public:
Game *game;
}
void Update(GameManager *manager);
// Contents of "GameManager.cpp"
#include "Game.h"
void Update(GameManager *manager)
{
Update(manager->game);
}
The key is the last method:
Why can't GameManager call MyGame Update() method when GameManager's Game object = MyGame and not Game?
Define Draw and Update as virtual methods in the base class Game.
class Game
{
public:
virtual void Draw() {};
};
class MyGame : public Game
{
public:
virtual void Draw() {}
};
void callDraw(Game* game)
{
game->Draw();
}
//...
Game* game = new MyGame;
callDraw(game);
The last call will call the method in MyGame although it's called on a Game pointer.