How to efficiently render different things at different times in a game? - c++

Sorry for the ambiguous title. What I am wondering is what is an efficient way to alternate rendering between lets say a main menu, options menu, and "in the game."
The only two ways I've come up with so far are to have 1 render function, with code for each part (menu, ...) and a variable to control what gets drawn, or to have multiple render functions, and use a function pointer to point to the appropriate one, and then just call the function pointer.
I always wonder how more professional games do it.

Try to use state-machine / strategy OOP pattern. Game application is in different states and renders different things and reacts on keyboard/mouse input differently when you are playing and when you are interacting with menu.

Well this is a bit more complicated if you want to do it right.
First I create a CScreen class that's the base class for all the screens. It's an abstract class( use pure virtual functions) that has 2 functions: Render and Update. Then I derive it in more screens that I need such as CMainMenuScreen, COptionsScreen, CCreditsScreen, CGameScreen etc. Let each of these classes take care of their own stuff. In each of them you have the interface and then when press for instance the options button in the main menu screen then you change the screen to COptionsScreen. For that you have to just keep one variable CScreen screen somewhere and on every frame call screen->Update() and screen->Draw() remeber to adjust if you do not use pointers(tough I'd recommend this)

If your controls are represented as classes then a polymorhic API render would solve the problem. Depending on the object ( menu types) the corresponding rendering happens.
class UIObject
{
public:
virtual bool render() = 0;
~UIObject(){}
};
class MainMenu : pu{
public:
virtual bool render()
{ //rendering for main menu
}
};
class OptuionMenu
{
public:
virtual bool render() { //render for option menu}
};

Games that I've shipped, that have sold lots of copies, have had a state machine and used switch statements to choose the appropriate functionality. While ostensibly less flexible than an "OOP" state machine, it was far easier to work with than the OOP designs I've subsequently been subjected to.
It actually may be appropriate to have only one render function, but that function shouldn't know specifics about what it's doing. It'll have 3D and 2D passes (at least, for a 3D game, since even those often have 2D UI elements), but it doesn't need to know what "mode" the game is in.
The magic happens in the UpdateMainMenu or UpdateGame or UpdateInGameMenu functions, as well as the Start and Stop functions associated with switching states. Choose which with a switch statement on an enum and use it two places, switching states (one switch to stop the old state, one more to start the new one) and updating.
As I write that my alarm bells go off that this is a perfect opportunity to use OOP, but from experience I would advise against that. You don't want to end up in the situation where you have a million little states that are coming and going; you want to constrain it to the major "run modes," and each of those modes should be able to operate on data that tells it what to display. E.g. one state for the entire in-game menu, which "loads" data (usually, "updates its pointer to the data") to indicate what the behavior of the current screen is. There is nothing worse than having a hundred micro classes and not knowing which one triggers when, not to mention the duplicated logic that often arises from such a design (game developers are very bad at reducing duplication through refactoring).

Related

Do people use classes as their "game loop?"

So I've been learning how to program so I can make games, and, therefor, I've been reading and watching many tutorials. Every once in a while, I'll come across code (c++) that uses a class to handle game events, but nobody has explained why they do this.
It also seems like some programming languages, like C#, automatically use a class for the program's "main."
So what I want to know is if I should be using a class for my game. Why and/or why not?
Here's an example of what this might look like:
class GAME
{
public:
void load_resources();
bool input();
void update();
void draw();
};
int main ()
{
GAME game;
while (!quit)
{
quit = game.input();
game.update();
game.draw();
}
return 0;
}
Thanks for reading.
In terms of game engine design we have something called a Scene system.
A scene normally hold all the GameObjects.
When you send the scene an event it should iterate on the gameObjects and update them all with events (update start end render postrender keyboard mouse scroll resize etch).
But in a much much simpler form of the system we at least want a game class so we can reload the level.
For example when the user enters the game it may take us a min to load all the models and textures and scripts from memory so we dont want it on our main loop we may want to load async and show a loading screen in this case we'll construct the game on another thread.
Or when the user wins and go to the next level we can unload the last level so we simply destroy the Game/Scene and create a new one of the new level.
In short: this kind of approach is used to define states of our application and manage them easily

Where to place my function? Into my native Gui or into my presenter?

I have the following scenario: I have Button and PreviewButton in Gui layer they have a common part named BasedButton. Button only knows IButtonPresenter, the interface of ButtonPresenter. The button should have no logic, the presenter could contain some logic. The problem is PreviewButton is so simple class that it hasn't need any presenter. Except one thing: hasLed() function which determines based on the button type (simple switch-case) that the Button and PreviewButton has a led or not. Where should be this common hasLed() function?
My idea:
PreviewButton should also have presenter and the hasLed() function should be in the common part of Button's and PreviewButton's presenter. Problem: it seems overengineering that only for this one function i should introduce the presenter.
Put it this logic: hasLed() into the BasedButton (in common part of Button and PreviewButton). Problem: i tried to avoid putting any logic in my native Gui.
Make some namespace (or use the button type enum namespace!) and put this simple function as inline function into it. Problem: the "logic" is placed in a "strange" and not expected class.
Put hasLed() function into one of my our manager class in my presenter layer. Advantage: the manager interface is reachable for all native Gui class. And the code remains common (no code duplication). Disadvantage: my managers with such a function seems a little bit strange.
Other idea?
Maybe now i would choose the 4th...
I'd go with the option 1. It's not over-engineerig (whereas trying to distinguish the PreviewButton from Button on the interface level does look like over-engineering to me), it's just boilerplate, but you avoid the unnecessary complication of the design that way.

QPainter and paintEvent : what is the use of QPaintEvent *event?

I have a school project involving creating a simple GUI and coloring graphs using a minimal number of colors. I am working with a classmate, and so far, we have laid out different ideas regarding how we will store the graphs in memory, and how to implement different coloration algorithms.
To create the GUI, we are using Qt, as I used it for another project before, it is free, and I generally find the documentation generally well detailed. Besides, I knew it had a drawing module, although I never used it.
After reading and the documentation and some examples, I was able to draw some basic shapes where I wished inside of a set area of a widget, and get them to correctly respond to resizing the widget.
To draw what I wish, I can write the paintEvent method this way, and just never use *event
void DrawArea::paintEvent(QPaintEvent *event)
{
//method body
}
Or I can write it this way, and it works too
void DrawArea::paintEvent(QPaintEvent *)
{
//method body
}
So, i have two questions :
How does the widget knows when to call the paintEvent method ?
If I'm not mistaken, every widget has a paint event, and I am
overwriting it ? If it's wrong please correct me, maybe that is the
reason why I don't really understand the way this pointer work.
What is the QPaintEvent pointer ? (I mean, what does it represent ?)
Thanks for any insight you may give me
So much text and so little questions...
You should learn about events handling in window systems (keywords are event loop, event queue and so on; in terms of Windows OS events are named "messages"). It is simple and useful thing to know.
In short, your program asks OS for new tasks time after time. If they exist, some information about it is provided, and you should handle them. Otherwise OS stops the program until such tasks will appear.
It means that OS notifies you to handle paint events when you are ready to do it.
QPaintEvent provides additional information about the event. At present it can give you a region to redraw. It may be used for painting optimization in some cases. But in simple cases it is not used.

Implementation of glutdisplayFunc()

I've used glutdisplayFun(void(*func)) in several of my program to sets the callback display to the current window.And by the use of it, i've rendered different things on the screen. By looking at the documentation of glut, passing null to it is illegal and we can't deregister it also.
The problem is that as we can't deregister it and i write a set of code to display the mainmenu(i.e as shown in the game). And i like to change to next window on the keypress(i.e play the game by clicking on the option play present in the mainmenu).
How to make the glutdisplayfunc call to the mainmenu inactive and and to set the glutdisplayfunc() for calling the next window.
std::%something%<std::function<void(void)>> displayFns;
void myDisplayFunc() {
for (auto& displayFn : displayFns)
displayFn();
}
Now register myDisplayFunc to GLUT and change the displayFns collection.
As for something, map<int, function<...>> would be a good start. Unordered map if you can guarantee your code doesn't need to be called in order. It starts to resemble good old BASIC times with line numbers, but I said upfront it will be a simple answer.
That's not how I would do it, but should do the trick for a quick'n'easy solution.
Funny thing with this is that you can create sets of those to have one element appear in more than one choice rather easily. So maybe it's not that bad after all.

Making a GUI using Qt for a text-based game

Me and my fellow classmates decided to make a game over the summer. At first we decided to make it a text-based console app, but then I though that it would be possible to create a GUI for the game using Qt. I played around with it a bit, being able to create widgets and what-not, but was unable to do one thing. For an example, our game contains a Player class. I created a dummy player in the main.cpp and afterwards tried to make the players info to display on a label on a press of a button. After numerous attempts, the only way I was able to do it is by making the player in the mainwindow.cpp . Is there a way to display the info of a player made in the main.cpp? How would it be possible to make the data accessible by different windows, such as the battle window, inventory window, etc.
It's a good thing to let the main.cpp as lean as possible, it should not contain much code in your case.
If I understand correctly you have several windows (could be simple QWidgets with no parent or QMainWindows) running on the same QApplication and your want to share data between them ? Why not just share a Player pointer in both your windows ?
Your main.cpp will look like this:
QApplication app(argc,argv);
YourWindows1 mw1;
YourWindows2 mw2;
Player player;
mw1.setPlayer(&player);
mv2.setPlayer(&player);
mw1.show();
mw2.show();
app.exec();
A more fancy way, could be to use a singleton. This singleton could own and hold your Player instance, every windows can access this singleton statically anytime to fetch Player information. It could be something useful for you to learn.
NOTE: I don't see exactly what is the problem here, perhaps you could share more details about what's causing you trouble ...
In a typical Qt app, main.cpp is only there to start the single application UI object and then turn control over to Qt's event handler. It's possible to deviate from that model, but unless you're quite experienced with Qt it's not something that would be recommended.
I agree with the other posters in this thread in that your main function should be kept absolutely as lean as possible. You want it simply to spawn a new instance of your game, and the let the game loop or state control manager take care of the rest. It basically boils down to something like this:
class Game{
Game();
~Game();
int OnExecute();
};
int Game::OnExecute(){
while(running){
// do game stuff
}
return 0; // No errors, game closed correctly.
}
int main(int argc, char* argv[]){
Game myGame;
myGame.OnExecute();
}
All of your initialization methods/code is contained within the OnExecute function, prior to the game entering its main loop. Within that main while(running) loop, you put your calls to your per-frame Update and Rendering functions which control logic calculations like entity position, physics updating, AI updating, etc and then you render everything for that frame. This is obviously an ultra-simplistic strategy, but it definitely helped me grasp exactly how it is that game engines work.
Now, as far as Qt is concerned, I've tried exactly what you are trying and it is not easy. Qt, though it can be rigged to work for in-game interfaces and the like, seems to me to be primarily intended for use in applications more than games. It provides excellent functionality if you need simple forms and buttons in your program, but as far as custom-designed HUDs and such, you're going to want to look somewhere else in order to save yourself a great deal of hassle. There are, however, a huge number of extensible GUI libraries specifically meant for games. I would suggest looking for one based simply on OpenGL since most graphics/game engines are built upon it and would integrate quite nicely.