Getting Serious

Started by
1 comment, last by Brain me 15 years, 3 months ago
Hi everyone! I joined the forums a few days ago and I've just been reading as many posts as I can and giving my two cents on a few occasions (which usually isn't very helpful, as I have found out..) - just trying to become comfortable since I'll probably be spending the next few months here ;) Anyway, I've been writing simple 2D games for a while now, and recently a few simple 3D games. Now I'm getting into much more complex games, and I would like to make sure that what I'm doing is correct, as well as receive any advice on how to do a number of things that I'll get to. First, the game loop. I began learning DirectX/3D from directxprogramming.com, which was very informative - on the basics. I've since moved on to just reading the documentation for the DirectX SDK. When I used those tutorials from directxprogramming, a really crappy game loop was used. I've tried making what improvements (hopefully...) I can on the game loop and I've arrived at this. First, I built myself a Timer class that utilizes the QueryPerformanceFrequency and QueryPerformanceCounter to determine accurate timesteps for the game loop. Next, I implemented my game loop to be within the Run() method of my GameEngine class. The Run method takes as its two parameters a void function pointer that takes a float, pointing to the update method to be called, and a void function pointer that is the game's rendering function. I think that this is a very good system, but if it's not, PLEASE let me know - that's why I'm posting.

// GetTime() actually returns the time since the timer was created, but by comparing subsequent values, we can determine the timestamp.
void GameEngine::Run(unsigned short framesPerSecond, void (*Update) (float), void (*RenderFrame) () )
{
     float fps = framesPerSecond;
     float fFrameDelay = 1.0f / (float)fps;

     Timer* timer = new Timer();
     float fCurrentTime = timer -> GetTime();
     float fLastTime - fCurrentTime;

     // only perform 1 update and then render on first loop
     float fStartTime = fCurrentTime - frameDelay;
     
     MSG mMessage;
     while( 1 )
     {
          while( PeekMessage( &mMessage, 0, 0, 0, PM_REMOVE ) )
          {
               // TODO: inform the game that the app is ending - *function??
               if( mMessage.message == WM_QUIT )
               {
                    break;
               }

               TranslateMessage( &mMessage );
               DispatchMessage( &mMessage );
          }

          // TODO: develop a much more effective system of handling events
          // NOTE: the only reason I have refrained is because theoretically,
          // the devices can't change too much within frames, since they are
          // fractions of a second apart
          diKeyboard -> GetDeviceState( 256, (LPVOID)keyboardBuffer );
          diMouse -> GetDeviceState( 16, (LPVOID)mouseState );

          do
          {
               (*Update)( fCurrentTime = timer -> GetTime() ) - fLastTime );
               fLastTime = fCurrentTime;
          } while( ((timer -> GetTime()) - fStartTime) < fFrameDelay );

          (*RenderFrame)();
     }

     delete timer;
}

I had the loop performing an fps check and interpolating what the variable fps should be, but that required calling GetTime() 4 times per frame, which really isn't much, but I'm working on a system of globalizing the fps withing the game engine and letting the game set the new fps. The game could perform tracking of the updates called per frame with simple counters, etc. Well, this is the first thing that I need to make sure is smooth before I start tackling my other objectives. In the mean time, if anyone could provide links, explanations, source ( :) ), or examples of different methods of displaying the world? I'm reading up on BSP trees, but it's hard to understand without concrete examples. I've looked at the DOOM code, just to see how it was used in a simple game, but that's a little TOO simple... Thanks in advance.
Advertisement
What do you mean by letting the game set the new FPS?
I mean instead of calculating fFrameDelay within the run loop, it is a member of the GameEngine class. That way, and game having created the GameEngine can at any time call a modifier method that sets the frameDelay.

EDIT: Oops, the while loop for the whole game loop should check bGameRunning, and the WM_QUIT message should set bGameRunning to false;

[Edited by - Brain me on January 16, 2009 5:31:49 PM]

This topic is closed to new replies.

Advertisement