hrdnutz timing code
BlitzMax Forums/BlitzMax Programming/hrdnutz timing code
| ||
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! |
| ||
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... |
| ||
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? |
| ||
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... |
| ||
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 |
| ||
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? |
| ||
Thanks, degac. Your code works, but I don't want the MOUSELEAVE/MOUSEENTER stuff. Taking this out, the problem returns. dragging the window doesn't send an appsuspend event, so although your program stops running max doesn't tell youStart 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? 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) |
| ||
Hm, okay, thanks. |
| ||
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. |