Весьма примитивно и не гибко.
Обычно делают так :
1) Прописывают флаги состояний игры.
2) Формируется хук отрисовки / обновления и он же (хук) регистрируется в системе при запуске приложения.
3) Любое состояние управляется с помощью системы событий.
Все это дело есть в БМаксе. В Б3Д надо делать самому ( хуки и события ).
в конечном итоге управление состояниями сводится к такому виду :

'Обьявление констант и хуков
Const GAME_MENU:Byte = 0
Const GAME_GAME:Byte = 1
Const GAME_PAUSE:Byte = 2
Const GAME_END:Byte = 125
' регистрируем события :
AllocUserEventID(GAME_MENU,"МЕНЮ!")
AllocUserEventID(GAME_GAME,"ИГРА!")
...
' Обработчик событий :
Function UpdateState:Object(id:Int,data:Object,context:Object)
' Здесь обрабатываются все игровые события
' Если обработчик ничего не обработал то необходимо :
Return data
EndFunction
' Регистрация обработчика в системе событий
AddHook(EmitEventHook, UpdateState) ' Функция регистрируется в системе событий
Function Draw(id:Int)
' рисование ( id говорит о том, что надо рисовать )
EndFunction
Function Update(id:Int, dt:Float)
' Обновление ( id говорит о том, что надо обновлять )
EndFunction
' ХУК
Function Hook:Object(id:Int,data:Object,context:Object)
' id - содержит текущее состояние программы
Local dt:Float = UpdateDeltaTime() ' Обновление значения дельты времени
...
по полученным данным обновляем и рисуем все, что надо
Update(id,dt)
Draw(id)
Return data
EndFunction
' Регистрируем хук в системе
AddHook(FlipHook,Hook) ' Хук вызовится перед Flip()
...
' Цикл
Repeat
Cls()
Flip(True) ' Запуск всех хуков, после этого произойдет смена буффера
Forever
' Управляется так :
CreateEvent(GAME_PAUSE, 1, 0, 0, 0, Null).Emit()
' Это озночает что мы послали системе сообщение о смене игрового стейта на
' ИГРА В ПАУЗЕ
Одной строчкой кода мы запускаем хук EmitEventHook, в котором обработается созданое событие, в обработке события примет участие и наш созданный выше обработчик.
Смотри сорсы БМакса. Ничего сложного нет. =)