Thread: Object oriented game design

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    399

    Object oriented game design

    I'm doing a simple 2D engine in SDL, and I'm having a hard time figuring out how to design the class hierarchy.

    I want an interface that is completely seperated from the underlying engine, so that I may change from SDL to OpenGL in the future for the video rendering for example.

    My first stumbling point was when I was designing an Event class that handles keypresses and similar input. If the users quits the program, the code should call a global quit function that all classes should use, but I can't figure out how to design this part without using global variables (which I want to avoid). The quit function can't be static since it will have to cleanup non-static data. I also want to try to avoid multiple inheritance since everyone say to avoid it if possible.

  2. #2
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472

    Cleanup()


  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by rogster001 View Post
    I looked through it quickly and I agree that the design looks good (I've used the stack-based game-states before and they're very useful). But c'mon..:
    Code:
    // the stack of states
    vector<CGameState*> states;
    Hooray for std::stack...
    I think the comment/line combination is a bit of a WTF.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    That's a useful resource, but that design still has the same problem that I mentioned above. How should the HandleEvents() function in the CGameState class handle an event that requires calling a public member function in CGameEngine (e.q. a quit function)? You could use exceptions for this, but that's hardly what I would call a solid class design.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    I think there are several methods. The best is probably; you could have a virtual method named "running" in all classes. Now, if a certain game state is running, the logic would be like this:
    Code:
    while(state.running()) {
      // Render, do events
    }
    The game state can now keep a local flag to indicate to the state manager that that game mode should be killed. You could even inherit that functionality similar to this:
    Code:
    class GameStateBaseClass {
    public:
      GameStateBaseClass() { _quit = false; }
      virtual bool running() { return _quit; }
    
    protected:
      void doQuit() { _quit = true; }
    
    private:
      bool _quit;
    };
    Now any game state can simply call doQuit() to quit that game state and go to the previous one. You should never want to quit multiple states at the same time, as it's up to the state itself whether it should terminate. Eg. the game should never quit the entire program, it should go back to the main menu.

    Otherwise you could have the popGameMode defined publically. The state manager probably shouldn't be a singleton, but you could pass it to the GameStateBaseClass class. Then from there you could just call _manager->popGameMode();

  6. #6
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    Okay here's another example. What if the event received is to save the game? It would be nice to have a public member function in the main Game class that handles it, i.e. Game::Save(). The problem is then, how is the Event class going to call that function? The save function can't be static. I can think of a couple of similar situations ...

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by Memloop View Post
    Okay here's another example. What if the event received is to save the game? It would be nice to have a public member function in the main Game class that handles it, i.e. Game::Save(). The problem is then, how is the Event class going to call that function? The save function can't be static. I can think of a couple of similar situations ...
    I wouldn't think of that as an event. And event is a mouse move, a click, a key press or release, an exit request, etc.
    If there is one GameMenuState game state, which has a save button, the mouse click is the actual event. The GameMenuState finds out the user clicked save. Now, indeed, it has to call the save method on the MainGameState (for instance).

    What I'd do is pass that MainGameState (inheritted, at least, by SaveableGameState with a virtual safe() function) to the GameMenuState. Maybe to its constructor, maybe to another function.
    That's the best solution I can think of now.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Call me crazy or something, but I like the idea of a full-out event-driven system. The biggest benefit I see is that you do not need a loop that keeps polling states.
    Instead, make it event-driven. Sleep (perhaps a mutex) until event is received, then process the event.
    You could also create an event that accepts a functor to call and then create a functor using lambas directly in the code where you create the event.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by Elysia View Post
    Call me crazy or something, but I like the idea of a full-out event-driven system. The biggest benefit I see is that you do not need a loop that keeps polling states.
    Instead, make it event-driven. Sleep (perhaps a mutex) until event is received, then process the event.
    You could also create an event that accepts a functor to call and then create a functor using lambas directly in the code where you create the event.
    I think that depends on the application. On most games, at least 3D, a lot of things happen and re-rendering has to be done all the time. In fact, the 3D applications I made so far all polled for events and rendered whenever there were no events available to process. For a normal application I agree that an event-driven design is better. For a 2D game engine I'm not sure, but I reckon it's the same as 3D. Unless of course for relatively static games like tic-tac-toe.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Of course, I am not a game developer, so I cannot say for sure, but it would seem that event driven is always the best. By streamlining the process of making events, it should be fast.
    Today's games waste a lot of cpu power simply by doing idle looping.
    It is an interesting concept, though, even if it would not work.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Event driven game engines give higher performance, as well as allowing greater flexibility. You don't need to rewrite the entire engine just to add a new type of attack for example, you simply create a new event, and then write the code into the object classes to handle that new event.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Sleep (perhaps a mutex) until event is received, then process the event.
    By streamlining the process of making events,...
    A mutex is not exactly streamlining the event process.

    Today's games waste a lot of cpu power simply by doing idle looping.
    No they are maxmizing the use of the CPU. Just b/c the CPU usage reads 40% in your game does not mean it is being used optimally. All that means is you are playing nice with the Windows scheduler.
    Too many threads will degrade performance and threading the wrong things will also degrade performance. Today's games overall are maximizing the CPU but moreso the GPU. Who cares about the CPU when the bottleneck is really the bus and getting data to the GPU? In the future most calculations will be all done on the GPU so it really doesn't matter what the CPU is doing. The CPU will probably be doing audio mixing, input processing, etc., which can all be threaded. Everything else will be done on the GPU to even include real-time tesselation of primitives and the tesselation will be done by the GPU. This can already be done in geometry shaders and newer cards are advertising real time tesselation of terrain grids in pure hardware in DX10 and DX11. No one cares about the CPU anymore b/c it usually isn't doing anything. If the CPU takes 100% to do audio and input while the GPU does everything else....does it really matter? The real powerhouse of graphics lies on the video card not on the motherboard.

    Event driven systems are standard fare and most probably use it. Most of the books I've purchased recommend using event driven systems. If you want to learn more about how to do an event driven system I suggest purchasing Game Code Complete, 2nd ed..
    Last edited by VirtualAce; 11-01-2009 at 05:00 PM.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Bubba View Post
    A mutex is not exactly streamlining the event process.
    Maybe not. It was just a suggestion of something that might work, although not the best things to use use.

    The only thing I really care about otherwise is that cpu cycles are not wasted on nothing
    If they are being used to process necessary data, then it is all fine. But polling like the above code is definitely not a good thing. That would be a waste of cpu resources.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by Elysia View Post
    Maybe not. It was just a suggestion of something that might work, although not the best things to use use.

    The only thing I really care about otherwise is that cpu cycles are not wasted on nothing
    If they are being used to process necessary data, then it is all fine. But polling like the above code is definitely not a good thing. That would be a waste of cpu resources.
    I still find it hard to believe. Most source I read worked something like this:
    Code:
    While running:
      While event available
        Handle event
      Render
    So we only lack any events to handle once per frame. And most frame rates of games don't go over 60 or 120 per second. So how much processor power can we waste on polling events? I doubt it'll be much.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    A lot (I think? ). The whole while running is unnecessary polling.
    Use a block to stop the main thread from running when there are no events and use a quit event to quit the game.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C Programming 2d Array Question
    By jeev2005 in forum C Programming
    Replies: 3
    Last Post: 04-26-2006, 03:18 PM
  2. beach bar (sims type game)
    By DrKillPatient in forum Game Programming
    Replies: 1
    Last Post: 03-06-2006, 01:32 PM
  3. Game Engine Link Prob
    By swgh in forum Game Programming
    Replies: 2
    Last Post: 01-26-2006, 12:14 AM
  4. My Memory Game
    By jazy921 in forum C Programming
    Replies: 0
    Last Post: 05-05-2003, 05:13 PM
  5. Im a Newbie with a graphics design problem for my simple game
    By Robert_Ingleby in forum C++ Programming
    Replies: 1
    Last Post: 11-23-2001, 06:41 PM