Global Objects

Started by
11 comments, last by Burnt_Fyr 14 years, 5 months ago
I'm having design issues with how to get to specific objects. Right now in main I create an object for each subsystem, for example: System game; Video video; UserInterface hud; Text text; Input input; The problem is, I'm passing these objects back and forth all over the place and can't seem to get to them. What would be the best way to setup objects so I can access them where ever I want? For example, in my game loop, if a key is pressed I pass an event containing the key data to input.handleInput() which then renders something using video.render(). Thanks.
Advertisement
The problem with using global variables is precisely that you can access them from everywhere. You don't want to have that possibility. Your design would be much better if you only gave certain parts of the program access to certain objects, and you didn't allow violations all over the place.

The game loop probably should know about all or most of these things, though. I would probably have a class Game that knows everything, of which the main loop is a member. However, I would not pass a pointer to the Game around to everybody, precisely because I don't want every part of the program having access to every other part.
Can you provide me with an example?
Of what? Why globals are bad or the system he mentioned in his second paragraph?
The system mentioned in the second paragraph. I understand why globals are bad.
I believe he's talking about something like (in C++):
struct Game {  void run();  /* ... */  private:    Renderer* renderer;    PhysicsSimulation* physics;    /* ... */};int main() {  Game game;  game.run();}

Here, the run() method encapsulates the main loop, probably by creating the window and other subsystems and then dropping into a typical "pump messages until you're ready to quit" loop. That way the Game class, which has access to all the various subsystems in the game, can facilitate their communication, but each subsystem can be made aware of only what it needs to function.
Quote:Original post by jpetrie
I believe he's talking about something like (in C++):
[...]


Yup, that's what I meant.

I usually go for a main method which does all the creating directx and window stuff and includes the main loop

my main loop simply contains

game.tick();

where game is my main game class. and tick() is like that

*get new time
*check key events
*make all changes in scene depending on time difference, network events and key presses
*render the world
*send the scene to the server if necessary

I also have some other thread that listens the messages from the server and do the necessary changes in game classes. it has a lock so it does not run at the same time with step 3 of game.tick()
taytay
Quote:Original post by Runicode
What would be the best way to setup objects so I can access them where ever I want?


Mu. The problem is that you want to access the objects in places where it is inappropriate to do so.

Quote:For example, in my game loop, if a key is pressed I pass an event containing the key data to input.handleInput() which then renders something using video.render().


For example, you should separate input, physics (logic) and rendering (output) steps. In the main loop, you check for key input, tell all objects to "update", and tell visible objects to "render". You don't necessarily do each of these once for every time through the loop; you can do whatever's appropriate for your game. (For example, you might only call the physics update every X milliseconds, while checking for keys every time through, and interpolating between graphics frames according to the exact time elapsed. Or you might deliberately introduce a delay between frames. It Depends(TM).) But by keeping these things separate, you gain the flexibility to figure out this part later.

When you check for key input, you send an event to objects in the world that are interested in that key. They update their internal state to reflect the fact that the key has been pressed, but not to actually "move" or whatever. For example, in a racing game, you might set a 'bool throttle;' in the user's Car, but you would not change its 'velocity'.

In the update code we make the actual "physics" changes. That means that, for example, we go ahead and calculate the current acceleration (based on the car's current velocity, gear and whether the throttle or brake is pressed), and then the current velocity (from previous velocity, plus (time elapsed) * (current acceleration)), and finally current position (similarly using velocity to update the old position). (Actually, we can smooth that out a little and use acceleration/velocity from the "middle" of the 'timestep' instead of the beginning, but you get the idea.) What we do is check the time elapsed, and send a message to all objects that do physics-y stuff telling them "X amount of time has elapsed; update accordingly".

Finally, in the rendering code, we go through every object that's drawable and figure out where it will appear on screen. We can have the objects give us a bunch of rendering data that we then pass to video.render(); or we might pass them a reference to video and let them make the calls.

Anyway, if you're making objects to represent "subsystems", you're probably doing OO wrong. Objects represent - well, objects. Things. "A ball" is a thing. "Every ball in existence" is not really a thing. Neither is "the ability to bounce balls". So we don't make a class to "hold" functionality for drawing text; instead we have a class to represent bits of text that will be drawn. (Except we don't need to make that; there is already a string class in the standard library.) And then a class, similarly, to represent a font that will be used for rendering text. And then we can do something like boldFont.render(myString, somePositionOrOther).
Thank you all for the advice. I think I understand most of it. As far as doing OO wrong, I'm confused. What would be the best way to develop the individual subsystems without them being objects? I understand that objects should be just that, objects: a character, a weapon, a tree, etc... How do I create none class subsystems? Also, what would be the best way to setup some sort of event/error logging? I assume everything would need access to this?

Thanks for your help!

This topic is closed to new replies.

Advertisement