I'm quite new to c++ and I started looking at the SDL2 library to make a simple platformer game. I'm running into a problem with class inheritance. I have a parent class (GameObj) and a child class (Player). When I try to inherit the the GameObj from Player the compiler tells me the base class is undefined. I am trying to override the update function in the Player class, however since I get a "Base class undefined" error it also tells me that the overrode function did not override anything.
GameObj.h
#pragma once
#include "Game.h"
class GameObj
{
public:
GameObj(const char* path);
~GameObj();
virtual void update() = 0;
void render();
protected:
SDL_Texture* tex{ nullptr };
SDL_Rect srcR;
SDL_Rect dstR;
};
GameObj.cpp
#include "GameObj.h"
GameObj::GameObj(const char* path)
{
tex = TextureManager::LoadImage(path);
srcR.x = srcR.y = 0;
srcR.w = srcR.h = 32 * 2;
dstR.x = dstR.y = 0;
dstR.w = dstR.h = srcR.w;
}
GameObj::~GameObj() {}
void GameObj::render() {
TextureManager::DrawTexture(tex, srcR, dstR);
}
Player.h
#pragma once
#include "Game.h"
#include "GameObj.h"
class Player : public GameObj
{
public:
Player(const char* path, int x, int y);
~Player();
void update() override;
private:
int x{ 0 };
int y{ 0 };
int speed{ 0 };
int velocity{ 0 };
};
Player.cpp
#include "Player.h"
Player::Player(const char* path, int x, int y) : GameObj(path){};
Player::~Player() {};
void Player::update ()
{
x++;
dstR.x = x;
dstR.y = y;
}
As Retired Ninja commented there is a circular include issue in the code. GameObj.h included Game.h and Game.h included Player.h. To fix this issue I removed the Game.h include in GameObj.h.
GameObj.h
#pragma once
#include <SDL.h>
class GameObj
{
public:
GameObj(const char* path);
virtual ~GameObj() = default;
virtual void update() = 0;
void render();
protected:
SDL_Texture* tex{ nullptr };
SDL_Rect srcR;
SDL_Rect dstR;
};
GameObj.cpp
#include "GameObj.h"
#include "TextureManager.h"
GameObj::GameObj(const char* path)
{
tex = TextureManager::LoadImage(path);
srcR.x = srcR.y = 0;
srcR.w = srcR.h = 32 * 2;
dstR.x = dstR.y = 0;
dstR.w = dstR.h = srcR.w;
}
GameObj::~GameObj() {}
void GameObj::render() {
TextureManager::DrawTexture(tex, srcR, dstR);
}
Related
I'm trying to create a game using C++ and SDL (I'm still new and learning).
I've been stuck on this for some time, and I'm not sure how to solve this.
This is Game.h where I'm trying to create the actual game:
#pragma once
#include <iostream>
#include "SDL.h"
#include "SDL_image.h"
#include "TextureManager.h"
#include "GameObject.h"
#include "Input.h"
struct Objects
{
GameObject player;
Input input;
};
class Game
{
public:
Game() {};
~Game() {};
void init(int width, int height, bool fullscreen);
void handleEvents();
void update();
void render();
void clean();
bool inline running()
{
return _isRunning;
}
static SDL_Renderer* renderer;
static SDL_Event event;
private:
bool _isRunning = true;
SDL_Window* _window = nullptr;
SDL_Texture* texture = nullptr;
GameObjectsRef data = std::make_shared<Objects>();
};
And this is GameObjects.h where I'm doing things related to objects of the game:
#pragma once
#include <string>
#include "TextureManager.h"
class GameObject
{
public:
GameObject() {};
~GameObject() {};
void init();
void render();
void update();
int xpos = 0;
int ypos = 0;
int dx = 0;
int dy = 0;
private:
SDL_Texture* texture = nullptr;
//GameObjectsRef data;
};
I found some answers where it says there might be issues with multiple includes, but shouldnt #pragma once take care of that?
Error messages in the Game.h lines 12 and 13
Error C3646 'player': unknown override specifier
Error C4430 missing type specifier - int assumed. Note: C++ does not support
Error C3646 'input': unknown override specifier
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int
I'm a beginner to C++ following this tutorial. I'm working on the section dealing with Classes and running into the following error.
not a class or struct name C/C++(262)
I am attempting to inherit the properties of a Shape parent class into a Circle class, but my editor claims that the Shape class is not defined. The error is raised on line 4 in Circle.h: class Circle: public Shape. I've included my code below.
I've double checked my code against the code in the tutorial and ensured that all the files I've written are in the same directory, etc.
Any pointers would be much appreciated.
The code editor I'm using is VSCode 1.55.2.
Code
Shape.h
#ifndef SHAPE_H
#define SHAPE_H
class Shape {
protected:
double height;
double width;
static int numOfShapes;
public:
// Constructors
Shape(double length);
Shape(double height, double width);
Shape();
virtual ~Shape();
void SetHeight(double height);
double GetHeight();
void SetWidth(double width);
double GetWidth();
static int GetNumOfShapes();
virtual double Area();
};
#endif /* SHAPE_H */
Shape.cpp
#include "Shape.h"
// This file is known as the "class implementation" file.
Shape::Shape(double length) {
// '->' is known as the pointer operator (used to access objects fields and methods).
this->height = length;
this->width = length;
}
Shape::Shape(double height, double width) {
this->height = height;
this->width = width;
}
Shape::~Shape() = default; // Sets the deconstructor to the default.
void Shape::SetHeight(double height) {
// You should really use isDigit() on each character to validate the input
this->height = height;
}
double Shape::GetHeight() {return height;}
void Shape::SetWidth(double width)
{
// You should really use isDigit() on each character to validate the input
this->width= width;
}
double Shape::GetWidth() {return width;}
int Shape::GetNumOfShapes() {return numOfShapes;}
double Shape::Area(){
return height * width;
}
int Shape::numOfShapes = 0; // Sets the default value for 'numOfShapes'
Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle: public Shape {
public:
// Constructors
Circle();
Circle(const Circle& orig);
Circle(double width);
virtual ~Circle();
double Area();
};
#endif /* CIRCLE_H */
Circle.cpp
#include "Circle.h"
#include "Shape.h"
#include <cmath>
Circle::Circle(double width): Shape(width) {}
Circle::~Circle() = default;
double Circle::Area() {
return 3.14159 * pow((width/2), 2);
}
main.cpp
#include <cstdlib>
#include <iostream>
#include "Shape.h"
#include "Circle.h"
using namespace std;
void ShowArea(Shape& shape);
int main(int argc, char **argv) {
Shape square(10, 5);
Circle circle(10);
ShowArea(square);
ShowArea(circle);
return 0;
}
void ShowArea(Shape& shape) {
cout << "Area : " << shape.Area() << endl;
}
You are including "Shape.h" after "Circle.h". Hence Circle class is defined before Shape class. The compiler when it reaches line "class Circle: public Shape", it cannot identify "Shape" as any user-defined class or struct, thus it is raising the error. To correct it include "Shape.h" before "Circle.h" or include "Shape.h" in "Circle.h"
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 have Player class defined like this:
"Player.h"
#ifndef PLAYER_h
#define PLAYER_h
#include "cocos2d.h"
USING_NS_CC;
class Player: public Sprite {
public:
Player();
~Player();
private:
Sprite *playerSprite;
__String name;
int maxHP;
int currHP;
int maxMP;
int currMP;
int maxEXP;
int currEXP;
};
#endif
and "Player.cpp":
#include "Player.h"
I want to initialize int maxHP, int maxMP .. etc upon
Player* myPlayer = Player::create();
What would be the proper way to override ::create() function with parameters such that
// create(int maxHP, int currHP, int maxMP, int currMP, int maxEXP, int currEXP)
Player* myPlayer = Player::create(100, 100, 100, 100, 100, 100);
can be used?
You can overload create (have multiple functions with the same name but different signature).
class Player : public Sprite {
public:
static Player* create(int maxHP, int currHP, int maxMP, int currMP, int maxEXP, int currEXP) {
Player* p = Player::create();
p->maxHP = maxHP;
// etc ...
return p;
}
}
I have a C++ class and I keep getting this error although I have another class written with similar syntax that compiles without a fuss.
Here is my .h:
#ifndef FISHPLAYER_H
#define FISHPLAYER_H
#include "Player.h"
class FishPlayer : public Player
{
public:
float xThrust;
float yThrust;
static FishPlayer* getInstance();
protected:
private:
FishPlayer();
~FishPlayer();
static FishPlayer* instance;
};
#endif
And Here is my .cpp :
#include "..\include\FishPlayer.h"
FishPlayer* FishPlayer::instance=0; // <== I Get The Error Here
FishPlayer::FishPlayer()
{
//ctor
xThrust = 15.0f;
yThrust = 6.0f;
}
FishPlayer::~FishPlayer()
{
//dtor
}
FishPlayer* FishPlayer::getInstance() { // <== I Get The Error Here
if(!instance) {
instance = new FishPlayer();
}
return instance;
}
I've been searching for a while now and it must be something so big I don't see it.
Here is the inheritance:
#ifndef PLAYER_H
#define PLAYER_H
#include "Ennemy.h"
class Player : public Ennemy
{
public:
protected:
Player();
~Player();
private:
};
#endif // PLAYER_H
And the higher one:
#ifndef ENNEMY_H
#define ENNEMY_H
#include "Doodad.h"
class Ennemy : public Doodad
{
public:
float speedX;
float maxSpeedX;
float speedY;
float maxSpeedY;
float accelerationX;
float accelerationY;
Ennemy();
~Ennemy();
protected:
private:
};
And the superclass
#include <vector>
#include <string>
enum DoodadType{FishPlayer,Player,AstroPlayer,Ennemy,DoodadT = 999};
enum DoodadRange{Close, Medium , Far};
enum EvolutionStage{Tiny, Small, Average, Large};
class Doodad
{
public:
float score;
void die();
EvolutionStage evolutionStage;
DoodadRange range;
Doodad();
virtual ~Doodad();
Doodad(Doodad const& source);
std::vector<Animation> animations;
double posX;
double posY;
std::string name;
std::string currentAnimation;
int currentFrame;
DoodadType type();
SDL_Surface getSpriteSheet();
bool moving;
void update();
protected:
private:
SDL_Surface spriteSheet;
};
Looks like you use FishPlayer as a enum value in Doodad.h
It is the same name as the class you're trying to declare. That might be the source of the problem.
Generally it's a good idea to use FISH_PLAYER, or Type_FishPlayer sort of naming scheme for enum values to avoid clashes like this.