How to override the constructor in the base class? - c++

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.

Related

Object pass itself to class constructor

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.

class not declared in scope but the class is declared

I don't know how to describe this but I declare a class (movableBox) but am not able to use in a specific scope (this scope is in the class player).
Here is some of my code:
player class:
#ifndef PLAYER_H
#define PLAYER_H
#include <SFML/Graphics.hpp>
#include <vector>
#include "movablebox.h"
class player
{
public:
sf::RectangleShape* player;
sf::Texture* playerTexture;
sf::Vector2f speed;
bool touching;
static void create(sf::Vector2f pos_);
static void draw(sf::RenderWindow& window);
static void updatePos(float& dt, float gravity, std::vector<sf::RectangleShape*> solids, std::vector<movableBox::movableBox_*> movableBoxes);
static void checkControls();
static void checkControlsperEvent (sf::Event& event);
};
#endif // PLAYER_H
and the movableBox class:
#ifndef MOVABLEBOX_H
#define MOVABLEBOX_H
#include <SFML/Graphics.hpp>
#include <vector>
#include "player.h"
class player;
class movableBox
{
public:
struct movableBox_ {
sf::RectangleShape* box;
sf::Texture* texture;
sf::Vector2f speed;
bool selected;
player* selectedBy;
bool touching;
};
static void create(sf::Vector2f pos_, sf::Vector2f size_);
static void draw(sf::RenderWindow& window);
static void updatePos(float& dt, float gravity, std::vector<sf::RectangleShape*> solids);
static void grabNearest(player* player);
};
#endif // MOVABLEBOX_H
I'm getting this error:
CodeBlocksProjects/phys/player.h:18:110: error: ‘movableBox’ was not declared in this scope
As you can tell by my lack of explaination I don't know why or how this happens, I hope you understand my problem.
Thanks in advance! :)
This is a circular dependency issue. There's #include "movablebox.h" in player.h, and also #include "player.h" in movablebox.h.
You have forward delcared class player in movablebox.h and it seems to be enough; so just remove #include "player.h" from movablebox.h.

Inherited sprite not draw-able

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

c++ error C2065 : undeclared identifier [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
C++ Undeclared Identifier (but it is declared?)
Im getting the error sprite.h(20): error C2065: 'Component' : undeclared identifier when I try to compile (I got a couple other files as well). Below is the sprite.h file. I cant for the life of me figure out what is causing this problem.
#ifndef SPRITE_H
#define SPRITE_H
#include "Image.h"
#include "Rectangle.h"
#include <string>
#include <SDL.h>
#include <vector>
#include "Component.h"
namespace GE2D {
class Sprite {
public:
Sprite();
Sprite(Image *i);
Sprite(Image *i, int x, int y);
Sprite(char *file, bool transparentBg, int x, int y, int w, int h);
virtual ~Sprite();
virtual void tick(SDL_Surface *screen, std::vector<Sprite*>* sprites, std::vector<Component*>* components);
virtual void handleEvent(SDL_Event eve);
virtual void draw(SDL_Surface *screen);
void setPosition(int x, int y);
const Rectangle& getRect() const;
const Image& getImage() const;
const Sprite& operator=(const Sprite& other);
Sprite(const Sprite& other);
protected:
private:
Image image;
Rectangle rect;
};
}
#endif
In the .cpp file tick() is defined like this:
void Sprite::tick(SDL_Surface *screen, std::vector<Sprite*>* sprites, std::vector<Component*>* components) {}
tick() is supposed to take two vectors like they do now, but maybe there's a better way to do that which might solve this problem?
EDIT
As requested, here is Component.h as well:
#ifndef COMPONENT_H
#define COMPONENT_H
#include "Rectangle.h"
#include "Component.h"
#include "Sprite.h"
#include <vector>
#include <SDL.h>
namespace GE2D {
class Component {
public:
Component();
virtual ~Component();
virtual void draw(SDL_Surface *screen) = 0;
virtual void tick(SDL_Surface *screen, std::vector<Sprite*>* sprites, std::vector<Component*>* components) = 0;
virtual void handleEvent(SDL_Event eve) = 0;
const Rectangle& getRect() const;
protected:
Component(int x, int y, int w, int h);
private:
Rectangle rect;
};
}
#endif
Sprite.h includes Component.h which includes Sprite.h, giving a circular dependency which can't be resolved.
Luckily, you don't need to include the headers at all. Each class only refers to a pointer to the other class, and for that a simple declaration is enough:
class Component;

C++ illegal operation on bound member function

I had a problem with an illegal access error and I have removed the default constructor from Player.h as I deduced that the problem was due to it. The problem I am having now is that the Level.cpp wanted a default constructor so I edited the Level.h file as shown. That problem was resolved but now I am not being able to return a pointer to the player. The error 'illegal operation on bound member function' is being shown. Any ideas please? I'm a beginner in C++ and any help would be appreciated.
Player.h:
#ifndef _TAG_PLAYER
#define _TAG_PLAYER
#pragma once
#include "Tile.h"
#include "Point.h"
class CGame;
class CPlayer : public CTile
{
public:
CPlayer(Point pos, CGame* game);
~CPlayer();
char getDisplay() ;
virtual bool canMove(const Direction direction, Point p) ;
virtual void move(const Direction direction, Point p);
bool CheckForHome() ;
};
#endif _TAG_PLAYER
Player.cpp:
#include "Box.h"
#include "Level.h"
#include "Tile.h"
CPlayer::CPlayer(Point pos, CGame* game)
{
this->game=game;
Point p;
p.x=0;
p.y=0;
setPosition(p);
}
CPlayer::~CPlayer()
{
}
bool CPlayer::CheckForHome() {
Point p = getPosition();
bool OnHomeTile;
if(game->getLevel()->getTiles()[p.y][ p.x] == GOAL)
{
OnHomeTile = true;
} else {
OnHomeTile = false;
}
return OnHomeTile;
}
char CPlayer::getDisplay()
{
if (CheckForHome())
{
return SOKOBANONGOAL_CHAR;
}
else
{
return PLAYER_CHAR;
}
}
Level.h:
#pragma once
#include "Point.h"
#include "Tile.h"
#include "Player.h"
#include "Box.h"
#include <list>
#include <string>
class CGame;
class CLevel
{
private:
list<CBox> boxes;
TileType tiles[GRID_HEIGHT][GRID_WIDTH];
CPlayer player(Point p, CGame* game); -> new declaration
//CPlayer player; -> old declaration
protected:
CGame* game;
public:
CLevel();
~CLevel();
CPlayer* getPlayer();
list<CBox>* getBoxes();
TileType (*getTiles())[GRID_WIDTH];
};
Constructor of Level.cpp
CLevel::CLevel()
{
this->game=game;
Point p;
p.x=0;
p.y=0;
player(p,game);
memset(tiles, GROUND, sizeof(TileType)*GRID_HEIGHT*GRID_WIDTH);
}
The function with the error in Level.cpp:
CPlayer* CLevel::getPlayer()
{
return &player;
}
Currently you've declared player as a member function not a member variable, which is why you're getting the weird error message. You can't mix the declaration and the initialisation of member variables like this.
You declaration should just be
CPlayer player;
But your CLevel constructor needs to initialise it, for example like:
CLevel() : player(Point(0, 0), game) { }
The problem with that though is that currently CLevel doesn't have a game to initialise the player with. Perhaps you could pass the game to the constructor of CLevel?
I think you need to read up on constructors and initialisation of members a bit more.