I'm having troubles with C++.
I am making an Engine class for my game that handles graphic using SDL.
The Engine class is (hopefully correctly implemented) Singleton.
engine.h:
#ifndef H_ENGINE
#define H_ENGINE
#ifndef H_SDL
#include "SDL/SDL.h"
#endif
class Engine {
public:
static Engine *getInstance(); //This returns the singleton object of class
int init(int screenWidth, int screenHeight); //must initialize before use
~Engine(); //destructor
private:
Engine(); //private constructor
static Engine *instance; //stores the single instance of the class
SDL_Surface *screen; //Struct for SDL
};
#endif
engine.cpp:
#include "engine.h"
Engine *Engine::instance = NULL;
Engine::Engine() {
screen = NULL;
}
Engine *Engine::getInstance() {
if(instance == NULL)
instance = new Engine();
return instance;
}
int init(int screenWidth, int screenHeight) {
SDL_Init(SDL_INIT_EVERYTHING);
//This line has the error: error: ‘screen’ was not declared in this scope
screen = SDL_SetVideoMode(screenWidth, screenHeight, 32, SDL_SWSURFACE);
return 1;
}
Engine::~Engine() {
SDL_Quit();
}
main.cpp: contains the line
Engine::getInstance()->init(600, 400);
Any help would be appreciated
You forgot to put the class qualifier on init:
int Engine::init(int screenWidth, int screenHeight)
Happens all the time.
You define init as:
int init(int screenWidth, int screenHeight) {
However, this defines a function in global scope (there there is no screen variable).
Instead, if you write:
int Engine::init(int screenWidth, int screenHeight) {
You will define the function of your class.
Related
I'm trying to create a game window for a cave story clone in C++, so first, I create the header file below, after that, I went to create the class file. When I finish the class I kept receiving the error that the argument type is incomplete with a parameter of type sdl_window and sdl_render. If anyone could help me figure out what I'm doing wrong.
Graphics.h
#ifndef GRAPHICS.h
#define GRAPHICS.h
struct SDL_window;
struct SDL_render;
class Graphics {
public:
Graphics();
~Graphics();
private:
SDL_window* window = NULL;
SDL_render* render = NULL;
};
#endif
Graphics.cpp
#include <SDL.h>
#include "graphics.h"
/* Graphics class
* Holds all information dealing with graphics for the game
*/
Graphics::Graphics() {
SDL_CreateWindowAndRenderer(640, 480, 0, &window, &render);
SDL_SetWindowTitle(window, "Cavestory");
}
Graphics::~Graphics() {
SDL_DestroyWindow(window);
}
The problem is that you are declaring your own types unrelated to SDL types. Rewrite class to use appropriate types:
#include <SDL.h>
class Graphics {
public:
Graphics();
~Graphics();
private:
SDL_Window * window = nullptr;
SDL_Renderer * render = nullptr;
};
I have two namespaces with each a pointer to a class Window inside of one of the namespaces.
Graphic.h
namespace Graphic {
//...
class Window;
//...
void init();
static Window* window;
}
App.h
namespace App{
//...
static Graphic::Window* mainWindow = nullptr;
//...
void init();
void setupGraphic();
//...
}
I am trying to initialize the static Window* App::mainWindow with the static Window* Graphic::window
Window.h
#include "Graphic.h"
#include <SDL\SDL.h>
class Graphic::Window
{
public:
Window(const char* pName = "OpenGL Window",
unsigned int pWidth = 1000, unsigned int pHeight = 700);
~Window();
const char* name;
unsigned int width;
unsigned int height;
SDL_Window* window;
};
The Graphic::window is being initialized like so
Graphic.cpp
#include "Graphic.h"
void Graphic::init(){
window = new Window("Engine");
}
And after this initialization i try to initialize the (static Window*)App::mainWindow with Graphic::window
App.cpp
#include "App.h"
#include <Graphic\Graphic.h>
#include <Graphic\Window.h>
void App::setupGraphic()
{
Graphic::init();
App::mainWindow = Graphic::window;
}
But App::mainWindow stays nullptr, even though Graphic::window has successfully been initialized and has already been worked with in Graphic::init(). There are no compilation warnings/errors, all i get is an exception "App::mainWindow was nullptr."
In "Graphic.h", you have
static Window* window;
This statement is included in every translation unit (.cpp) that will #include Graphic.h. Therefore each unit will have its own variable window. What happens then is that Graphic.cpp assigns its own window, but main.cpp find its own variable window unchanged.
What you should do is the following:
In Graphic.h, declare window but don't define it:
extern Window* window;
And define it only once, in Graphic.cpp:
Window* Graphic::window = nullptr;
This way all the translation units will refer to the same global variable window.
You should do the same for the variable Graphic::Window* mainWindow defined in App.h.
extern Graphic::Window* mainWindow; // <-- in App.h
And
Graphic::Window* App::mainWindow = nullptr; // <-- in App.cpp
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'm trying to make a framework for an SFML game I'm making and I'm having trouble with inheritance. I thought I knew how to do it but it doesn't seem right. I want my main to just call GameLoop basically and thats it. In my GameLoop class I have methods for making the window and running the game. Then I want my GamePlayScreen class to actually handle the game logic but for some reason I can't figure out how to inherit from GameLoop. I was watching a video and the guy was using C# which is why I'm having trouble converting it. The video is https://www.youtube.com/watch?v=WhbeqOOSDEo&index=2&list=PLfTDIoEcaNroztBVGPA0aU3NbOauRVIe3.
GameLoop.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <string>
class GameLoop
{
public:
GameLoop(int width, int height, std::string title);
virtual void Run();
virtual void LoadContent();
virtual void Initialize();
virtual void Update();
virtual void Render();
sf::RenderWindow window;
};
GameLoop.cpp
#include "GameLoop.h"
GameLoop::GameLoop(int width, int height, std::string title)
{
window = sf::RenderWindow(sf::VideoMode(width, height), title, sf::Style::Default);
}
void GameLoop::Run()
{
LoadContent();
Initialize();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
Update();
window.clear();
Render();
window.display();
}
}
void GameLoop::LoadContent()
{
}
void GameLoop::Initialize()
{
}
void GameLoop::Update()
{
}
void GameLoop::Render()
{
}
GamePlayScreen.h
#pragma once
#include "GameLoop.h"
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
class GamePlayScreen : public GameLoop
{
public:
GamePlayScreen();
void Initialize();
};
GamePlayScreen.cpp
#include "GamePlayScreen.h"
GamePlayScreen::GameLoop(800, 600, "Game");
{
}
void GamePlayScreen::Initialize()
{
GameLoop game(800, 600, "Game");
}
The constructor will be called automatically when you 'new' the class. Just make a matching constructor in GamePlayScreen and the system will call the derived constructor first - but the signature must match.
class GamePlayScreen : public GameLoop
{
public:
GamePlayScreen();
GamePlayScreen(int width, int height, std::string title);
void Initialize();
};
Maybe this is not a real answer but I can not comment.
As I can see main subject is about "Handling Multiple Screens".
So you may look at this tutorial: https://github.com/SFML/SFML/wiki/Tutorial:-Manage-different-Screens
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