Sign in to follow this  
julian boolean

my game loop (is it okay?)

Recommended Posts

julian boolean    122
(allegro/c++) inside the gameinit case i load the map and graphics and whatever else is needed, i have a seperate initialization function used for more general stuff that i didnt bother including in the example
while(mainstate != shutdown)
{
	switch(mainstate)
	{
		case login
		{
		blah
		blah
		blah
		}

		case title
		{
		blah
		blah
		blah
		}

		case ingame
		{
			switch(gamestate)
			{
				case gameinit
				{
				blah
				blah
				blah
				}
				case gamerun
				{
				blah
				blah
				blah
				}
				case gameshutdown
				{
				destroy ingame related stuff
				mainstate = title
				}
			}
		}

		case mainshutdown
		{
		destroy everything else
		}
}

Share this post


Link to post
Share on other sites
Wavesonics    330
Well IMO the loop should look something like:




while( running ) {
// 1. Handle Input
// This part of course depends greatly on how you are getting your input
while( inputLeft ) {
handleInput( key );
}

// 2. Update Display
render();
}




So each pass, the input affects the data model, then at the end of the pass you simply update the display, render the frame or what ever the dislay might be.

The loop is part of the "Platform Layer" which, I think, should have no game logic in it at all.

But that's just my two cents.

Share this post


Link to post
Share on other sites
ToohrVyk    1595
It's one way to do it, and it is acceptable for very small projects where you only have a small number of possible game states, and (very important) the game states do not need to store internal data exclusively.

For any non-trivial project (i.e. anything past Pong, Tetris or Breakout), it's better to drop the switch altogether, and use a stack of polymorphic game state objects instead, as these can encapsulate game behaviour much better.

My typical game loop looks like this:


let loop () =
(* Prepare a new frame *)
let scheduler = schedulers # top in
let time = timer # now in

(* Read input *)
input # poll time;

(* Update state *)
while scheduler # next < time do
scheduler # pop # execute time
done;

(* Render scene *)
renderer # frame time;

(* Repeat *)
loop ();;

Share this post


Link to post
Share on other sites
Bob Janova    769
I agree with those guys above me, the main loop shouldn't contain game logic. Mine would look something like:
while(running){
processInput();
updatePhysicsAndGameEntities();
render();
}


For maintiaining different game states (what your switch block is doing), I recommend having a state stack and a GameState class that controls how the game is 'played' in that state, so updatePhysicsAndGameEntities() becomes gameEngine.currentState.update().

Share this post


Link to post
Share on other sites
Specchum    242
I'm not sure how good this method is but I update my game entities every 30 frames mainly because I don't have physics or AI logic that's dependant on high frame rates. My render loop, however, runs every frame.

Something like this in pseudo-code:

while (!done)
{
if (30 frames done)
{
UpdateGameEntities(); //basically animation - runs at 30 fps
}
Render();
}

Share this post


Link to post
Share on other sites
ToohrVyk    1595
Quote:
Original post by Specchum
I'm not sure how good this method is but I update my game entities every 30 frames mainly because I don't have physics or AI logic that's dependant on high frame rates.

UpdateGameEntities(); //basically animation - runs at 30 fps


That's quite impressive — your program has to render at 900fps in order for the updates to be done at 30tps.

Share this post


Link to post
Share on other sites
rk_theone    100
Quote:
Original post by Specchum
I'm not sure how good this method is but I update my game entities every 30 frames mainly because I don't have physics or AI logic that's dependant on high frame rates. My render loop, however, runs every frame.

Something like this in pseudo-code:

while (!done)
{
if (30 frames done)
{
UpdateGameEntities(); //basically animation - runs at 30 fps
}
Render();
}



i think this should be like :

float lasttime;
float curtime;

while (!done)
{
curtime = getcurtime;
gamespeed = curtime-lasttime;

lasttime=curtime;

UpdateGameEntities(entityspeed*gamespeed);
render();
}

speed independent game movement. more is the rendering time more will be the entities movement ans vice versa.

Share this post


Link to post
Share on other sites
Specchum    242
Quote:
Original post by ToohrVyk
That's quite impressive — your program has to render at 900fps in order for the updates to be done at 30tps.


Erm.. there goes that logic for a six! Theoretically then. ;)

Share this post


Link to post
Share on other sites
haegarr    7372
Quote:
Original post by ToohrVyk
That's quite impressive — your program has to render at 900fps in order for the updates to be done at 30tps.

Moreover, why to render the same game state 30 times in a row? The only effect would be to heat up the maschine...

@Specchum: Do you mean to limit the game loop to run at 30fps?

while(!done) {
curtime = getcurtime();
timedelta = curtime-recenttime;
if(timedelta >= 1/30) {
input();
update();
render();
recenttime = curtime;
}
}

Share this post


Link to post
Share on other sites
ChurchSkiz    1101
Quote:
Original post by ToohrVyk
It's one way to do it, and it is acceptable for very small projects where you only have a small number of possible game states, and (very important) the game states do not need to store internal data exclusively.

For any non-trivial project (i.e. anything past Pong, Tetris or Breakout), it's better to drop the switch altogether, and use a stack of polymorphic game state objects instead, as these can encapsulate game behaviour much better.

My typical game loop looks like this:


let loop () =
(* Prepare a new frame *)
let scheduler = schedulers # top in
let time = timer # now in

(* Read input *)
input # poll time;

(* Update state *)
while scheduler # next < time do
scheduler # pop # execute time
done;

(* Render scene *)
renderer # frame time;

(* Repeat *)
loop ();;


Anyone have any good beginner articles/tutorials on this subject? I'm interested in what Toohr said but having a hard time grasping the concept because of the language he uses.

Share this post


Link to post
Share on other sites
Kylotan    9866
It's quite simple really - as with most good object-oriented designs, you should use subclasses where practical instead of switch statements. The classes have methods such as Update() or Render() which you call every frame, and you just swap in the appropriate class (eg. SplashScreen, Game, Menu, Paused) when you change states. Once you're comfortable with that, it's a short step towards having a hierarchical state system where you keep a stack of states, so that you can push a Paused state onto the stack without losing the current GamePlay state.

Share this post


Link to post
Share on other sites
Ultimape    100
Quote:
Original post by Kylotan
It's quite simple really - as with most good object-oriented designs, you should use subclasses where practical instead of switch statements. The classes have methods such as Update() or Render() which you call every frame, and you just swap in the appropriate class (eg. SplashScreen, Game, Menu, Paused) when you change states. Once you're comfortable with that, it's a short step towards having a hierarchical state system where you keep a stack of states, so that you can push a Paused state onto the stack without losing the current GamePlay state.



could you put some sample code of "swaping" the appropricate class.. would that just be another switch within update or render? or is there another methodto hold these constructs?

Share this post


Link to post
Share on other sites
Specchum    242
Hmm... what I was thinking was that my update should cap at 30fps but rendering should run as fast as possible.

haegarr, basically my loop looks like yours except that the render() is outside the if statement.

Share this post


Link to post
Share on other sites
Kylotan    9866
Quote:
Original post by Ultimape
could you put some sample code of "swaping" the appropricate class.. would that just be another switch within update or render? or is there another methodto hold these constructs?


Within your general game logic somewhere:

if (timeToMoveToNextState)
currentState = NextState()


That's all. Each frame, you call your update/render/input functions on currentState. You change the object that the currentState variable refers to when you wish to change state. Just create a new one of the appropriate type and assign it.

Share this post


Link to post
Share on other sites
haegarr    7372
Quote:
Original post by Specchum
what I was thinking was that my update should cap at 30fps but rendering should run as fast as possible.

haegarr, basically my loop looks like yours except that the render() is outside the if statement.

IMHO my loop measures the elapsed time, and decides to update and render if 1/30 second has gone. Otherwise it does nothing. Assuming that the update/render stuff durates less than 1/30 seconds, say 1/50 seconds, then my loop yields in 30 fps in both update and rendering. If 1/20 seconds are consumed instead, then it runs at 1/20 seconds.

Your loop as I (and obviously ToohrVyk) understand it, counts frames and updates if the counter has reached 30. Assuming that the update time is 1/100 seconds and the render time also (yielding in 1/50 seconds total like in the example above) then your loop renders 30 frames at a rate of 100 fps. That durates obviously 0.3 seconds. Now an update is done. So, in this example updates are done only approx. 3 times a second (what is definitely too less). To reach an update rate of 30 per second your rendering must be (as ToohrVyk has stated) as fast as 1.1 ms or 900 fps!

So our loops differ in that
(1) my loop does not waste time to render the same state 30 times a row but only once (nevertheless its "active waiting" can be made more effective),
(2) my loop restricts the update/render cycle to an upper limit of 30 fps, and
(3) my loop allows reasonable update rates even if the render time goes halfway into the cellar.

IMHO your loop _is_ capable of performing as you desire, but under unrealistic circumstances only. Please correct me if I'm wrong.

Share this post


Link to post
Share on other sites
Specchum    242
Quote:
Original post by haegarr
Your loop as I (and obviously ToohrVyk) understand it, counts frames and updates if the counter has reached 30.


*Goes back and reads his original post which seems to be the source of this confusion and come across this line:
if (30 frames done)
*

Duh. My bad. That was from my original code that actually used frame based animation (for mobile phones). My recent code (and the one that I was actually talking about looks like this - copy pasted this time to prevent ****ups):


//Update
if ((timer->GetTicksMS() - prevTime) > 1000/30)
{
//The main game update loop
Update();
prevTime = timer->GetTicksMS();
}

//Refresh Display
ShowDisplay();



Hope that clears up things.

Share this post


Link to post
Share on other sites
yi1ect    100
this would be my input for the game loop:

// 1 - class factory invokation, create objects and stuff

while( gameActive ) {
// 2 - Handle the input (keyboard, joystick etc..)
// 3 - have a on keyDown and keyUp conditions so only within that
// period that events happen
while( onKeyDown ) {
handleInput( key );
}
while( onKeyUp ) {
handleInput( key );
}

// 4 - Update objects, render etc..
render();

// 5 - Need to check if game still active
}

what do u guys think?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this