hrdnutz timing code

BlitzMax Forums/BlitzMax Programming/hrdnutz timing code

rs22(Posted 2009) [#1]
With reference to: http://www.blitzbasic.com/codearcs/codearcs.php?code=2039

My own code:



This seems to be common with all fixed step implementations I've seen in BlitzMax. If you hold the mouse down on the title bar, the code seems to keep running, causing objects to 'jump' to new positions. Also, if you happen to be holding a key down and hold your mouse down on the titlebar, the same happens, but the object also keeps moving! Not ideal at all, in my opinion, so how could I go about preventing this from happening? I would like the object to start again from where it was when the game was interrupted by clicking on the titlebar, or whatever else causes this.

This does not happen with delta timing, but I do not want to use that as I intend to use Chipmunk physics in my game.

Thanks!


degac(Posted 2009) [#2]
You need to checkout with AppSuspended() if the application is or not on 'focus' and manage the internal time accordangly.
A better solution is to check the EVENTs associated (check the BRL.Event module for a complete list of events handled by Bmax)


EVENT_APPSUSPEND Application suspended
EVENT_APPRESUME Application resumed
EVENT_APPTERMINATE Application wants to terminate



and keep track of the status during the game

when EVENT_APPSUSPEND raise 'stop' every timer (and the game of course), then re-set all the timers (t, dt, execution_time) at the EVENT_APPRESUME.

Personally I managed a simply function CheckGameStatus() (with a global variable Game_Status) to keep track of what Bmax-OperationSystem-User are doing...


rs22(Posted 2009) [#3]
Thanks for your reply. I've tried AppSuspended(), with no success. Any chance you could have a go and see if you can make it work?


degac(Posted 2009) [#4]
This is my piece of code I'm using on my application
'Modulo Controllo Eventi
Const game_run:Int = 1
Const game_paused:Int = 2
Const game_main_menu:Int = 3
Const game_quit:Int = 4
Const GAME_ASK_TO_EXIT:Int = 5
Const GAME_CREATE_USER:Int = 6
Const GAME_NEWUSER:Int = 7
Const game_option_menu:Int = 8
Const game_failed:Int = 9
Const game_tutorial_mode:Int = 10

Global game_status_string:String[] = ["RUN" , "PAUSED" , "MAIN MENU" , "QUIT" , "ASK TO EXIT" , "CREATE USER" , "NEWUSER","OPTIONS","FAILED","TUTORIAL"]

Global game_resumed:Int=1
Global game_status_last:Int=game_run
Global game_Status:Int=game_run
Global game_pause_timer:Int

Function EventControl()
	PollEvent()

	Select CurrentEvent.ID
	
		Case EVENT_APPSUSPEND,EVENT_MOUSELEAVE
			If game_Status=game_run
					game_status_last=game_status
					game_status = game_paused
					game_resumed=0
			End If
			game_pause_timer=MilliSecs()

			FlushMouse

		Case EVENT_APPRESUME,EVENT_MOUSEENTER
			
			If game_status = game_paused
					game_resumed = 1
					'game_status = game_run
			End If
			FlushMouse
			FlushKeys
			
	
		Case EVENT_APPTERMINATE
				game_status = game_ask_to_exit'game_quit
				game_resumed=0
				FlushMouse

	End Select
End Function

The game has a GAME_STATUS general variable that can has (for my purpose) the states GAME_RUN and GAME_PAUSED

PS: sorry I was editing my first post...


degac(Posted 2009) [#5]
Ok, I integrated your code with mine (save the above souce code as Lib_GameStatus.bmx")
You can move the image/rect only when the application is on-focus
Graphics(640, 480)

Include "lib/lib_gameStatus.bmx"

Global UPDATE_FREQUENCY = 10 ' times per second
Global update_time = 1000 / UPDATE_FREQUENCY
Global t , dt , execution_time = 0

' boucing ball
Global X# , Y#, oldX#, oldY#
Global dirX# = 1

x=100
y=100
oldx=x
oldy=y

Global img:TImage = LoadImage("ufo.png")

game_Status=game_run

t = MilliSecs()

While Not AppTerminate()

	EventControl() 

	Select game_status
	
		Case game_run
			'------------------------- game run
			execution_time:+ dt
			 	dt=MilliSecs()-t
				t=MilliSecs()
				' fixed interval update loop    		
			   While execution_time >= update_time
					Update()
					execution_time:- update_time
				Wend
				
				' calculate the remainder for motion interpolation
				Local et# = execution_time
				Local ut# = update_time
				Local tween# = et / ut
				
				Render(tween)
			' game is on pause
		Case game_paused
		
			If game_resumed = 1
				game_status = game_run
				game_resumed = 0
			End If

		
	End Select
Wend

Function Update()
	' time independent speed
	Local Speed# = 150.0 / (1000.0 / Float(update_time)) ' 150.0 pixels per second
	
	' record the old position for tweening
	oldX = X
	oldY = Y
	
	' move the ball	
	If KeyDown(KEY_RIGHT) Then X:+(Speed)
	If KeyDown(KEY_LEFT) Then X:-(Speed)
	If KeyDown(KEY_UP) Then Y:-(Speed)
	If KeyDown(KEY_DOWN) Then Y:+(Speed)

End Function

Function Render(tween#)
	Cls

	' interpolate between old and actual positions
	Local tx# = X * tween + OldX * (1.0 - tween)
	Local ty# = Y * tween + OldY * (1.0 - tween)
		
	' draw bouncing ball with interpolated values

	DrawRect  tx - 16 , ty - 16,14,14
	DrawText "Game Status : "+game_Status,0,0
	DrawText "Game Resumed: "+game_resumed,0,10
	Flip 1
End Function



rs22(Posted 2009) [#6]
Thanks, degac. Your code works, but I don't want the MOUSELEAVE/MOUSEENTER stuff. Taking this out, the problem returns.

Start moving the rectangle, then hold your mouse down on the titlebar. Release both the key and the mouse and the rectangle will keep moving on its own. FlushKeys/FlushMouse doesn't seem to affect this. Why does it do that?


dan_upright(Posted 2009) [#7]
Thanks, degac. Your code works, but I don't want the MOUSELEAVE/MOUSEENTER stuff. Taking this out, the problem returns.

Start moving the rectangle, then hold your mouse down on the titlebar. Release both the key and the mouse and the rectangle will keep moving on its own. FlushKeys/FlushMouse doesn't seem to affect this. Why does it do that?
dragging the window doesn't send an appsuspend event, so although your program stops running max doesn't tell you

you can add "print currentevent.id" after pollevent() in the eventcontrol function to see that the only events max sends you are mouseleave/mouseenter (and only by coincidence - if there's a way to move the current window without using the mouse, you might not even get those)


rs22(Posted 2009) [#8]
Hm, okay, thanks.


ImaginaryHuman(Posted 2009) [#9]
An alternative is to use maxgui, create your own window, invent your own pretend title bar and handle all the events - you can keep the screen updating even when you're dragging it.