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
Related
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);
}
I get the following error message after compiling my code:
Error C4430 missing type specifier - int assumed. Note: C++ does not
support default-int on line 21
I dont really know why the AssetManager retrieves that error, since I included everything needed...
My code:
game.hpp
#pragma once
#include "SDL.h"
#include "SDL_image.h"
#include <iostream>
#include <vector>
#include "AssetManager.hpp"
class Game {
public:
Game();
~Game();
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
void handleEvents();
void update();
bool running() { return isRunning; };
void render();
void clean();
static AssetManager* assets;
////////
}
AssetManager.hpp
#pragma once
#include <map>
#include <string>
#include "TextureManager.hpp"
#include "Vector2D.hpp"
#include "ECS.hpp"
class AssetManager {
public:
AssetManager(Manager* man);
~AssetManager();
void AddTexture(std::string id, const char* path);
SDL_Texture* GetTexture(std::string id);
private:
Manager* manager;
std::map<std::string, SDL_Texture*> textures;
};
I think this is a problem of circular dependency. Try forward declaration for AssetManager something like this:-
Class AssetManager; instead of #include "AssetManager.hpp" in game.hpp
I'm getting these two errors:
sdlsetup.h(15): error C2143: syntax error : missing ';' before '*'
sdlsetup.h(15): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
This is sdlsetup.h line 15:
CText* ctext;
The class is definitely set up properly and included in sdlsetup.h
Why is this?
EDIT: This is sdlsetup.h
#pragma once
#include "stdafx.h"
class SDLsetup
{
public:
SDLsetup();
~SDLsetup();
void Begin();
void End();
SDL_Renderer* GetRenderer();
void EnterGameLoop();
CText* ctext;
private:
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Event* mainEvent;
int screenWidth;
int screenHeight;
};
This is Text.h
#pragma once
#include "stdafx.h"
class CText
{
public:
CText();
~CText();
void draw(SDL_Renderer* renderer, std::string str);
SDL_Texture* aGetMessage();
SDL_Rect* aGetMessageRect();
private:
TTF_Font* Sans;
SDL_Color White;
SDL_Surface* surfaceMessage;
SDL_Texture* Message;
SDL_Rect Message_rect;
};
Here the problem is a weird error message from the compiler, because it doesn't know what CText is.
You need to declare CText before you use it:
#pragma once
// Declare the CText class, so the compiler knows it exists
class CText;
class SDLsetup
{
public:
...
CText* ctext;
...
};
You need to add includes for Text.h in sdlsetup.h and also for the relevant SDL headers in both files.
Text.h needs to have SDL.hand SDL_ttf.hincluded and sdlsetup.h needs SDL.hand Text.h
I tried to make MyWindowSplitter class and I made the other new class derived from CView class as runtime class in MySplitter class. But when I tried to compile that I got these errors in MyProjectView.h in GetDocument function:
Error 1
error C2143: syntax error : missing ';' before '*'
Error 2
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Where is the problem and How can I fix them?
//MySplitter.cpp
#include "StdAfx.h"
#include "MySplitter.h"
#include "SplitDemoSixView.h"
#include "TestView.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CMySplitter::CMySplitter(void)
{
}
CMySplitter::~CMySplitter(void)
{
}
void CMySplitter::ChangeViewClass(CRuntimeClass* pNewView)
{
m_pDynamicViewClass = pNewView;
}
void CMySplitter::DeleteView(int row, int col)
{
CView* pView = (CView*)GetDlgItem(IdFromRowCol(row, col));
if(pView->IsKindOf(RUNTIME_CLASS(CSplitDemoSixView)))
{
ChangeViewClass(RUNTIME_CLASS(CSplitDemoSixView));
}
else
{
if(pView->IsKindOf(RUNTIME_CLASS(CTestView)))
{
ChangeViewClass(RUNTIME_CLASS(CTestView));
}
}
CSplitterWnd::DeleteView(row, col);
}
//TestView.cpp drived from CView
#include "stdafx.h"
#include "SplitDemoSix.h"
#include "TestView.h"
#include "SplitDemoSixDoc.h"
#include "SplitDemoSixView.h"
// CTestView
IMPLEMENT_DYNCREATE(CTestView, CView)
CTestView::CTestView()
{
}
CTestView::~CTestView()
{
}
BEGIN_MESSAGE_MAP(CTestView, CView)
END_MESSAGE_MAP()
// CTestView drawing
void CTestView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
// CTestView diagnostics
#ifdef _DEBUG
void CTestView::AssertValid() const
{
CView::AssertValid();
}
#ifndef _WIN32_WCE
void CTestView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif
#endif //_DEBUG
// CTestView message handlers
And the problem is here:
//MyProjectView.h
#pragma once
#include "resource.h"
#include "MySplitter.h"
class CSplitDemoSixView : public CFormView
{
protected: // create from serialization only
CSplitDemoSixView();
DECLARE_DYNCREATE(CSplitDemoSixView)
public:
enum{ IDD = IDD_SPLITDEMOSIX_FORM };
// Attributes
public:
//ERROR PERFORMS IN THIS FUNCTION:
CSplitDemoSixDoc* GetDocument();
// Operations
public:
// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnInitialUpdate();
...
You need a forward declaration for your CDocument-derived class:
// Attributes
public:
//ERROR PERFORMS IN THIS FUNCTION:
class CSplitDemoSixDoc;
CSplitDemoSixDoc* GetDocument();
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;