Advertisement

Handling different game modes.

Started by March 13, 2003 09:58 AM
4 comments, last by Utwo 21 years, 8 months ago
I'm making a Tetris game, and I'm a little bit stuck on how best to approach one concept. Here's what my Tetris game consists of, along with some of the tasks it will need to do: - Splash Screen - Main Menu - Game Setup Submenu - Initialize game - Piece in play (where the actual game is played) - Game Paused - Set Piece - Weapon animations (You can collect bombs and deply them to blow up pieces) I need some way of managing all of this. I figured that the best way to do that is to make an enum called MODES and give each one of the above tasks a name, like SPLASH, MAINMENU, SUBMENU, INPLAY, SETPIECE, WEAPONANIM, etc. and then have a switch statement withing both GameMain() and DrawScreen() so that these functions know what to do. However there are still a few loose ends. First of all, I want to have an animated transition between the splash screen, menu, and submenu. Do I make an entirely different mode for these transition periods? Second of all, each mode will require that different bitmaps are loaded and memory DC's initialized. Would it be best to have a switch statement within my GameInit() function and call on GameInit whenever there is a mode change? Or is there a better way? [edited by - Utwo on March 13, 2003 10:59:35 AM]
---signature---" Actually, at the time, I didn't give a damn about the FoxNews issue... just that you would come swooping in with your Super Mith cape flapping behind you and debunk it just because it didn't happen in your living room." - InnocuousFox
No ideas?

Would a different forum be more appropriate?
---signature---" Actually, at the time, I didn't give a damn about the FoxNews issue... just that you would come swooping in with your Super Mith cape flapping behind you and debunk it just because it didn't happen in your living room." - InnocuousFox
Advertisement
Without starting any DX/GL holy wars, I would just suggest taking a look at the "Donuts3D" example. I found it in the DirectX 8.0 SDK under samples\multimedia\Demos\Donuts3D. It uses something similar to what you have proposed- from the code:

  // States the app can be inenum{ APPSTATE_LOADSPLASH, APPSTATE_DISPLAYSPLASH, APPSTATE_ACTIVE,       APPSTATE_BEGINLEVELSCREEN, APPSTATE_DISPLAYLEVELSCREEN };  

The program uses the states thusly:

  //from WndProc:        case WM_KEYDOWN:            // Move from splash screen when user presses a key            if( g_dwAppState == APPSTATE_DISPLAYSPLASH )            {                if( wParam==VK_ESCAPE )                {                    // Escape keys exits the app                    PostMessage( hWnd, WM_CLOSE, 0, 0 );                    g_bDisplayReady = FALSE;                }                else                {                    // Get rid of splash bitmap                    DeleteObject( g_hSplashBitmap );                    // Advance to the first level                    g_dwAppState = APPSTATE_BEGINLEVELSCREEN;                    DXUtil_Timer( TIMER_START );                    AdvanceLevel();                }            }            return 0;// What I think will really help you is the framemove function, though,// called thusly in WinMain:    while( WM_QUIT != msg.message  )    {        // Use PeekMessage() if the app is active, so we can use idle time to        // render the scene. Else, use GetMessage() to avoid eating CPU time.        if( g_bIsActive )            bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );        else            bGotMsg = GetMessage( &msg, NULL, 0U, 0U );        if( bGotMsg )        {            // Translate and dispatch the message            TranslateMessage( &msg );            DispatchMessage( &msg );        }        else        {            // Render a frame during idle time (no messages are waiting)            if( g_bDisplayReady )            {                FrameMove();                RenderFrame();            }        }    }// FrameMove works like so://-----------------------------------------------------------------------------// Name: FrameMove()// Desc://-----------------------------------------------------------------------------HRESULT FrameMove(){    switch( g_dwAppState )    {        case APPSTATE_LOADSPLASH:            // Set the app state to displaying splash			// Neil''s quick jump:			                g_dwAppState = APPSTATE_ACTIVE;			//            g_dwAppState = APPSTATE_DISPLAYSPLASH;            // Draw the splash bitmap            g_hSplashBitmap = (HBITMAP)LoadImage( GetModuleHandle( NULL ),                                                  TEXT("SPLASH"), IMAGE_BITMAP,                                                  0, 0, LR_CREATEDIBSECTION );            SendMessage( g_hWndMain, WM_PAINT, 0, 0 );            break;        case APPSTATE_ACTIVE:            UpdateDisplayList();            CheckForHits();            if( IsDisplayListEmpty() )            {                AdvanceLevel();                g_dwAppState = APPSTATE_BEGINLEVELSCREEN;            }            break;        case APPSTATE_BEGINLEVELSCREEN:            PlaySound( g_pBeginLevelSound );            DXUtil_Timer( TIMER_RESET );            g_dwAppState = APPSTATE_DISPLAYLEVELSCREEN;            break;        case APPSTATE_DISPLAYLEVELSCREEN:            // Only show the Level intro screen for 3 seconds            if( DXUtil_Timer( TIMER_GETAPPTIME ) > 3.0f )            {                g_dwAppState = APPSTATE_ACTIVE;            }            break;    }    return S_OK;}  


Hope that helped.






---email--- Tok ----surf----
~The Feature Creep of the Family~
--------------------------~The Feature Creep of the Family~
Thanks. That helps immensily.

Does anyone have any insight into whether this is the way it is normally done? It seems as though every game needs a solution for this, and so it is very suprising to me that these solutions are not well-documented.

It''s not that I don''t know how to program this. Obviously, the game state enum along with the switch statement will work. The intricacies of the menu transition animations and the initialization / destruction of objects needed in each mode can be handled with Init/Shutdown functions and/or more MODEs. However, it seems as though there must be a far more clever way of handling this that I just can''t see. And again, I can''t believe this isn''t better-documented.
---signature---" Actually, at the time, I didn't give a damn about the FoxNews issue... just that you would come swooping in with your Super Mith cape flapping behind you and debunk it just because it didn't happen in your living room." - InnocuousFox
This can be done in an object oriented way with a state manager. Each state in the game would be a class derived from a basic state class. Here''s a pretty good article about this -

http://www.codeproject.com/tips/statepattern3.asp

Tony
A good way to do this is to use a stack structure that holds the game states, and runs the state currently on top of the stack. For instance, at the start of the game you push the APPSTATE_DISPLAYSPLASH, and from there you could push APPSTATE_DISPLAYSPLASH, push the APPSTATE_BEGINLEVELSCREEN, and push the APPSTATE_DISPLAYLEVELSCREEN . When the level is over, you pop once, which makes APPSTATE_BEGINLEVELSCREEN the active state, until you push APPSTATE_DISPLAYLEVELSCREEN again. I think LaMothe covers this in DirectX for Roleplaying Games. This might be an overly complicated way to get the job done for your Tetris game which only has a few game states, but once you start adding more states to a game, like a pause screen or inventory screens, etc, it starts to make more sense.

This topic is closed to new replies.

Advertisement