Managing many "screens"

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Woozle
Posts: 2
Joined: Sun Jan 07, 2024 6:43 pm

Managing many "screens"

Post by Woozle »

Hi, newbie here

What would be the best way to handle multiple screens (levels, rooms, scenes, states, whatever you call it) in this engine? I don't mean "screens" as in multiple monitors or splitscreen. I mean

ex.
title-screen
level-select screen
option screen
level-1
level-2
...
credits

I went through most of the tutorial but they show only single-screen applications. This is fine for something small like Tetris or FlappyBird, but I want to make a more advanced game. I want to know how to handle multiple screens. How to transition from screen to screen. How to unload a current screen to load the next one. How to handle transition effects like a screen-fade/wipe. The proper way to load/render a list of enemies, terrain, lights, and whatever other objects for that scene.

My best idea is to make a base class called Screen that contains their own list of entities and variables, and virtual methods "OnEntry/OnExit/onFrameTick". This seems like what popular game engines do. OnEntry/OnExit would be called when a screen changes (likely through my own ScreenManager class) and onFrameTick is the logic and render that gets called every frame for that screen only.

I am unsure whether Irrlicht already fulfills this sort of functionality. Particularly I'm confused by the existence of the "ISceneManager". After all it is what I need to basically use what irrlicht has to offer (models, camera, etc, which all inherit ISceneNode and get added to the ISceneManager).

So my question is how/when am I supposed to use ISceneManager? Would it be best to make my own Screen class which contains an ISceneManager pointer? I would load all ISceneNodes into the scenemanager inside "onEntry" (or whenever I initialize the screen). Then inside "onFrameTick" I would simply call scenemanager->drawAll(). Does that seem correct? Is it necessary to clear() whenever I want to change screens ("onExit"), or do I simply stop calling the draw function?
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Managing many "screens"

Post by Noiecity »

Everything can be done with ingenuity in irrlicht, you can change scenes in a time factor while using a series of sprites that occupy the entire screen, such as a transparent image that gains white color and becomes transparent again, etc.

If you want to keep your application with a good FPS rate it is, in most cases, to use the internal properties of the irrlicht engine.
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Woozle
Posts: 2
Joined: Sun Jan 07, 2024 6:43 pm

Re: Managing many "screens"

Post by Woozle »

Yes I could use draw2drectangle and slowly change alpha. That's a good idea for screen transitions.

I was also asking about the structure of my project but I think it's fine. From what I gather, irrlicht is more of a renderer than a game engine. I was confused at first because it contained assist tools like keyboard input, gui, and basic collision. But it is not a framework for game logic (which is totally fine, I still want to use irrlicht). ISceneManager is just a container for Nodes so you can use a single draw call. It's probably fine to have several ISceneManagers (one per screen), but the IVideoDriver is a single object that gets passed between those screens. The driver is the heart of irrlicht.
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Managing many "screens"

Post by Noiecity »

If you need help with something specific, I can do it for you.
It is true that irrlicht by many is considered more of a renderer than a game engine, but for me it is much more of a game engine than others, the real renderer is Directx9 and Opengl, irrlicht is more of a set of libraries that facilitate the use of other things already made, the problem that irrlicht has is that many technologies, the industry discarded them and used new ones for games that require more graphical power, so that many of the new things are not adaptable to irrlicht.

But since irrlicht uses the directx9 renderer, you can program your own libraries using the other functionalities of the sdk, if you include the libraries, it is easy to implement, but difficult to understand, so if you are clever you can create functionalities that irrlicht does not had.

Now, it is advisable to use sprites for all the effects you want, but it takes more work, the advantage that irrlicht has is its performance, so once you do, your application could show a fluidity that current applications do not possess, if you did a hearthstone in irrlicht, you would obtain several times greater performance while consuming fewer resources.

You can create effects in blender and render, and pass the renders to irrlicht, then configure the timing logic and so on, the same for the buttons.

The best menus I have seen have been made in directx9 and using sprites, well, you can give the feeling of "3d" if you use sprites rendered in 3d, even though the sprites are just images, an example:
https://www.youtube.com/watch?v=w9nxzAjy1Bs
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
CuteAlien
Admin
Posts: 9651
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Managing many "screens"

Post by CuteAlien »

Hello Woozle,
best to think about IVideoDriver as common denominator of stuff different lower level graphic API's (D3D, OpenGL, Software) need. Everything likes scenes and gui is a higher-level build upon that one.

About your original questions: First I'd separate UI from game enties. One can have access to the other, but those are usually be independent classes.

I have used different approach es for this, for different projects:
For example in my racer all ui-screen were dervived from a GuiDialog class which looked like this: https://github.com/mzeilfelder/hc1/blob ... i_dialog.h
This one had simple functor and event-handler support (for stuff like adding a function for a button-click).
There's quite a bunch of examles where I use this in the gui_dialogs subfolder: https://github.com/mzeilfelder/hc1/tree ... ui_dialogs
The specific funtions you'll need in your base class can depend a bit on the project. Also I used my own serialization back then, but I'd rewrite that probably if I'd use current Irrlicht svn trunk version as it was mostly because Irrlicht was missing default paramters in serialization previously.
The importart part is that each dialog gets it's own class.
Project specific simplification here was for example that there was always only one dialog active at a time. Which very often is useful in games, especially if you want to allow users to use a gamepad controller. But obviously others need tons of dialogs at same time (thought still only one has the focus usually).

In another project (an editor) I put most of my UI in "mode" classes. So my mode base class had virtual functions like OnEnterMode, OnLeaveMode, OnCancelMode, OnEnterSubMode, OnLeaveSubMode, OnDpiChanged. But nearly all derived classes also had UI specific stuff like:
bool OnGuiEvent(const irr::SEvent::SGUIEvent& guiEvent);
bool OnKeyEvent(const irr::SEvent::SKeyInput& keyEvent);
bool OnMouseMoved(const irr::SEvent::SMouseInput& mouseEvent);
bool OnMouseLeftButtonUp(const irr::SEvent::SMouseInput& mouseEvent, bool fromDoubleClick);
void OnUpdateCursorPosition(const SEventUpdateCursorPos& event) override; // this one only called once per frame, SEventUpdateCursorPos another struct with useful info about mouse-state
void OnUpdate(); // called before environment drawAll
void createUIElements(); // usually called when class was created, but also on dpi changes
void removeUIElements();
+ each mode could obviously have it's own useful functions
Examples for modes where modeDrawingLine, modeContextMenu, modeCloningObject.
I still had a few Dialog classes which were independent of modes. Those didn't even have a common base, just made sure they wrapped all the UI-element used in them. Could be just a single irr::gui::IGUIWindow* Window or even an IGUIStaticText element (my DialogInfoText for example contained a single static text, but tons of tool functions for formatting useful info strings).

As for effects - Irrlicht has IGUIInOutFader which may be useful. Just don't use it too much, gamers tend to like their stuff snappy ;-)

As for SceneManager - it has the 3d nodes which are active. You can fill it on level-start. Or you can create more than one (ISceneManager::createNewSceneManager) and always draw the active one (you can also draw more than one, but that's more for doing some special effects like certain overlays). Your game objects should be your own classes. And then have pointers to the nodes they need (ISceneNode or IMeshSceneNode, etc). Thought it tends to help to have a quick way the other way round (find your game object from a given node).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply