Hey there everyone. As it stands I am making an asteroids game in which there are multiple classes. So I decided to do the approach as OOP as I can. So each class has its own play(), draw() and reset() function. The only problem is that when I am trying to pass a reference to the window in which I am drawing to, I am using a piece of code which I do not fully understand (given by lecturer). As a result of using this, I am unable to change certain properties of my class.
game.h
1 2 3 4 5 6 7 8 9 10
class Game
{
public:
Game(bool, sf::RenderWindow& win); //Constructor with reference to window
...
private:
sf::RenderWindow& myApp;//the window in which we play the game
};
game.cpp
1 2 3
// Constructor setting approriate window int w, int h, : myApp(win)
Game::Game(bool, sf::RenderWindow& win) : myApp(win) //Constructor with reference to window (same problem with it not allowing me to simply pass one parameter in)
{...}
What exactly does the underlined part do?
And how can I do the exact same thing within the function itself?
The thing with : is called an initializer list. It is a way to call non-default constructors of your members. myApp is a reference and references can't be without a value, it needs to be constructed immediately, thus there is no way to assign it in the constructor's body.
If at some point you want to change the value of myApp, you'll have to make it a pointer.
And how can I do the exact same thing within the function itself?
That's the initialization list. It initializes myApp, which becomes a sort of alias for win, which is a sort of alias for the argument passed to the constructor. References must be initialized immediately, they cannot be unbound for any length of time (not even before assignment in the constructor). There is no alternative.
I am doing something similar except I'm using a pointer.
Each drawable object needs a pointer to myApp for it's draw() to use, but since there is only one sf::RenderWindow object for the game I declare a static pointer in the base class. Then all instances have access to this one common pointer.
Example:
1 2 3 4 5 6
class ship
{
public:
static sf::RenderWindow* pWndw;
// other members
}
Then in the main() or the WinMain() as soon as the window is created I initialize the static pointer:
You're probably not going to have several RenderWindows (and even if you were, fun2code's solution wouldn't help) there is no reason not to make myApp global. Put it in a class for cleanness.
1 2 3 4 5 6 7 8 9 10 11
struct Game{
static sf::RenderWindow app;//no need for pointers or references
//any other global data or functions you need, like game state of init()
};
sf::RenderWindow Game::app;
struct ship{
void draw(){
Game::app.something();
}
};
I would love to put it as a global but making anything global at all seems to be extremely frowned upon in C++ lol. I already have bools for whether buttons are being pressed down as globals variables. Don't want to push it to far and be completely disregarded :p
In fun2code's solution every class has a pointer to a window. This pointer is not a property of an object, but of the class, thus if you have an EnemyShip::pWndw point to window A, all EnemyShip objects will be drawn on window A. There is no way to put one on window B. Of course you could have one window for the game and the other for the menus, but that wasn't my point. The idea of classes is to allow multiple instances of the same object. In fun2code's solution it is not possible to create several identical windows. In yours it is, but then, why would you want that.
Globals are frowned upon for several reasons. One is that if you have several files you'll have to put lot's of externs all over the place. Static members don't have that problem though. Another is that it with globals your code looses flexibility. Should you ever realize that you, in fact, do need two identical windows, you'd have rewrite a lot of code. But as long as you know what you're doing, there is nothing wrong with globals.
Then within all the .cpp's that need access to these globals I simply use a
#include "globals.h"
This works very nice but I was a little sceptical about putting something like the main game window as a global for fear of it being accessed and modified by any other programmers that may want to develop upon the code.