Space Harrier - Input freaking out?

Blitz3D Forums/Blitz3D Beginners Area/Space Harrier - Input freaking out?

Imperium(Posted 2013) [#1]
Working on a little project to replicate the classic Space Harrier. I was moving along fine until I noticed the controls are randomly freezing. I'm not sure why this is happening, could someone help me add some tweening to separate the input updates from the actual fps? Take a look what I have so far. If you try out the code for yourself you will see that it works fine then will lock up or the player will drop bellow the maximum movement range specified.


Main.bb


Globals.bb








Yasha(Posted 2013) [#2]
First thing: your "FPS limiter" code (that bit where it says "leave this alone") is broken and doesn't do what you think. It's also the root of the problem: on my machine at least, removing that gets rid of all pauses. Manual calls to Delay do not play nicely with Flip unless you turn off Flip's own vsync, and will introduce random jitters as the two pause mechanisms conflict with each other (you can of course make the boolean condition to flip, or the existence of VWait, something adjustable as an option for those machines where this isn't true).


Here's an example of separating the render and update loops to run on different timers. It's a loose translation of the code from the famous Gaffer article Fix Your Timestep!. This code is copied directly from a real released project (interesting bits removed and replaced with ;!COMMENTS, but the timer code is unmodified from something that works):



The organisation is mainly to separate the two cycles (for instance, it works very happily drawing at 60FPS while updating at 100FPS), but it also provides a tween value for rendering that can be passed to RenderWorld (and any custom draw functions that use tweening). Notice also that to actually apply tweening to 3D entities, you need to Capture them with CaptureWorld in the update loop (which in turn requires them to not be hidden); tweening is between their captured position and their current position, not anything to do with where they were at the last RenderWorld call.

There is no requirement to actually tween your renders, but because the update section works by either skipping iterations or adding extra iterations within the "owning" render loop, not tweening may cause the movement to appear jerky (the movement will not actually be jerky internally - it justs risks looking jerky due to mismatches between loops). At reasonably high framerates (60+), this is not usually a problem in practice; nor is it a problem if the updates and renders use the same timer (so you can set updates to use the same FPS as the most common draw rate, e.g. 60, and then skip the tweening on the majority of setups!). Tweening is also more annoying than it sounds if you have e.g. moving 2D elements, because you have to do it manually.

To apply this to your code, just dump everything up to the UpdateWorld command in the update loop at ;!UPDATE STUFF, and everything below that (minus the delay code) into the render loop at ;!DRAW STUFF.


Imperium(Posted 2013) [#3]
I would have never suspected my FPS limiter. Considering it has worked fine up until now but I'm glad you discovered my mistake. Here is my attempt at applying the posted code. I'm having some trouble following it. The showentity "WHATEVER" has me most confused.



Do you accept donations Yasha? Most often you're the first person to rescue me from my code issues. I really appreciate the help. :)


Yasha(Posted 2013) [#4]
OK, working down from the top...

-- the strange expressions 'Settings\DrawRate' and similar are assuming that you have a custom type object containing program settings. You can replace these with constants or any other numerical expression; '60' and '50' might work well for the draw rate and update rate, for example.

-- the line 'Local ShowDebugInfo = ...' is irrelevant; I overlooked it when deleting stuff. You have your own FPS measurement code that does the same thing.

-- CaptureWorld, like Render- and UpdateWorld, only deals in entities that are not hidden. This means that if an entity is un-hidden during the ensuing update loop, it may have the wrong old location still Captured for it when the loop ends; therefore, all entities that might be relevant should be Shown before CaptureWorld, and then set back to hidden again if necessary. In practice this may not actually be very relevant for you (the program this was taken from did a lot of showing and hiding based on events in the update loop, so it needed this step).

-- the 'WHATEVER' in capitals was just meant to represent that you should apply this to entities that need it as relevant. Probably best to just delete these two lines for now.

-- you ...don't need my update functions ('UpdateTouchMouse'?) in your program - they just show where to put your control-update functions.

-- if you use animation or collision, you need to use UpdateWorld (conversely, programs that don't use animation or collision - the things that need to be updated in the background of a frame - don't need UpdateWorld). If you use it, it should be the last thing before the end of the update loop (or at least, alongside any other related functions; it should be the last thing to operate on 3D entities). UpdateWorld doesn't need a parameter, as the parameter is for delta-timing, which is roughly the opposite of render tweening (fixed-speed render loop and a variable-speed update loop; we're doing it the other way round).

-- the FPS-counter and text display count as "draw stuff" (technically the counter part is updating, but it's doing it based on the draw loop), so they should go in the 'DRAW STUFF' area.

-- as with the update rates, the flags for vsync and delay were represented as part of a settings object. Different setups seem to respond differently to vsync so it's always good to make it optional.

-- I can't remember offhand why I was subtracting 1 from the Delay value. Much smoother without that (if you don't delay accurately, you end up needing VWait or Flip True, and then they tend to conflict and stutter).

That gives this:




Also... 'Yue'? (and.... no thanks. Besides, very little of this is my ideas.)


Yue(Posted 2013) [#5]
oO?? Yue i confused. xD


Imperium(Posted 2013) [#6]
Well that was embarrassing. Next time I should pay closer attention. Either way your help is greatly appreciated. :)


Imperium(Posted 2013) [#7]
I hate to bother with this again but the input keys are still freezing. If I hit up,right, and down in quick session or hold them down the main character get's stuck.

edit: found my goof in the keyboard inputs. I had a keyboard left set for keyboard right and a - integer where a positive should have been.