Scene management

Started by
7 comments, last by Goran Milovanovic 10 years, 7 months ago
Hi,
I am working with C++ but this problem is mostly language independant.

So, I am at the beginning of creating a small game to get used to SFML. One thing which has always been hard for me is to write my classes such that they are mostly independant and easy to manage.

For example, my first idea to run the game was:
There are scene classes and visual classes, deriving from SceneBase and VisualBase respectively. They always exist in pairs of two and represent things like the title screen, the main menu or the ingame screen.
The scene classes are responsible for handling data, user inputs and general game logic like collision detection.
The visual classes are responsible for managing sprites, texts and drawing those on the window.

Then there is a main loop which keeps running until the game ends. It has two local pointer variables of type SceneBase* and VisualBase* which, obviously, point to the objects of the current scene and visual.
It would look something like this:

while (window is open)
update scene
update visual
draw visual on window
end while

As I said, the scene controls its own data so I would have to pass that data to the visual somehow. And of course, a VisualTitleScreen object would need a SceneTitleScreen, not just any SceneBase. So the issue with my idea is that I would have to reinterpret_cast the SceneBase pointer. And I have been told: if you have to use reinterpret_cast in your program, you are doing something wrong :)

So, I am not satisfied with this solution and I am looking for another one.


If I made myself not clear or someone is looking for a tl;dr:
I am looking for good ways to manage data, game logic and visuals of different "scenes", meaning things like the title screen, the main menu, a world map or a battle screen.
Advertisement

It sounds like you are trying to create a Model-View architecture. Are you familiar with MVC? http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

I am not familiar with MVC, or rather, I was not until now.

Well, partially that MVC pattern and what I had in mind overlap but they also have differences, as far as I can tell from the article.

Model and controller would be combined and more importantly, all three modules would change frequently.

I am looking for good ways to manage data, game logic and visuals of different "scenes", meaning things like the title screen, the main menu, a world map or a battle screen.

I think you're looking for a state machine, or some derivative.

"SceneBase" is poor naming: You should just have a Scene class (the base is implied), with a virtual run method, to execute whatever logic is actually required for that scene.

Although, in general, most of your logic would be executed on the entities in the given scene (which would have their own virtual run method), so the default implementation of run could just be:


virtual void run(){
    for (int i = 0; i < entities.size(); ++i)
        entities[i]->run();
}

And most of your scenes would just be instances of Scene, with entities created in the constructor, following some XML scene description, like:


for (int i = 0; i < scene_files.size(); ++i){
    Scene* scene = new Scene(scene_files[i]);
    scenes.push_back(scene);
}

Or something along those lines.

*Edit: Sorry for the ugly code blocks - I can't seem to space them out.

+---------------------------------------------------------------------+

| Game Dev video tutorials -> http://www.youtube.com/goranmilovano | +---------------------------------------------------------------------+
Yes, the scene approach I wanted to make and state machines are very similar. State machines are more complex and powerful though which is not something I need for this small project. Let me clarify: I would like to seperate game logic from graphics entirely. The classic approach of a state machine and similar design patterns always uses scenes/states as a combination of both, usually providing an update() and a redraw() method.

Instead of a redraw method, you should have a pointer to visual data, which the Renderer can use to actually draw the object in question, rather than having the object draw itself.


void Renderer::draw(std::vector<GameObject*> objects){
    for (int i=0; i < objects.size(); ++i){
        Visual* v = objects[i]->visual;
        this->setDrawColor(v->color);
        this->drawShapeAt(v->shape, object[i]->position);
    }
}

Fairly simplistic example, but that would be the general set up.

If you're working in 3D, using a graphics library like OpenGL, you'll probably want to have things like Mesh and Material, which the renderer could use to set the proper state, and draw the relevant objects.

+---------------------------------------------------------------------+

| Game Dev video tutorials -> http://www.youtube.com/goranmilovano | +---------------------------------------------------------------------+

Here's what my in-progress engine is working with at the moment:

GameState: (analogous to your "scene")

Input Manager:

Resource Loader

Various logical objects (like a map class, some entities, whatever)

//etc...

Scene:(analogous to your "visual" methinks)

List of Renderable objects, where a renderable is something like:

Vertex information

Material Information

Light Information

Matrix information

//etc...

Basically, the gamestate maintains a list of logical entities, provides them to various physical (renderable) entities that know how to create and/or maintain their own geometry/shader data, and sends a packing of the renderable entities to the renderer.

The renderer takes renderable entities (and associated scene information) and renders.

Game state management always turns into a FSM (or something even more complicated), because thats just the type of problem that has to be solved. However, the concept of divorcing rendering from logic is totally orthogonal.

You can't completely separate rendering from logic, because your rendering has to know about your logic. You can however decouple it the other way around. For example, I have a MapMesh class that knows how to construct a mesh of the game map, along with all relevant material data. The game map knows absolutely nothing about rendering, and the MapMesh simply takes that as a reference.

@ Goran: That would not solve the problem, it would only postpone it. I would still have to pass the data from one object to another somehow. @ SeraphLance: I guess that will be the way I have to do it. It isn't exactly what I was hoping to achieve but it is probably as close as I can get. Thanks.

Modularity doesn't mean "pass no data, ever", it's about barriers, and well defined data that is passed over them.

As SeraphLance said, you can't separate things completely; Those systems have to interact.

+---------------------------------------------------------------------+

| Game Dev video tutorials -> http://www.youtube.com/goranmilovano | +---------------------------------------------------------------------+

This topic is closed to new replies.

Advertisement