LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Using Millisec to create smooth animations

Root / Submissions / [.]

PetrifiedLasagnaCreated:
I have noticed that a lot of programs still use vsync set the timing of their programs, and there is nothing wrong with this approach. However, as soon as your program takes longer than 1s/60frames to finish a single loop the drop in the speed of animations becomes noticeable. So we need a timing method that is absolute, that is not tied to the clock cycle of the CPU. This is where Millisec comes in. I am sure everyone is familiar with measurements of time, but just to make sure one second is equal to one thousand milliseconds. Now we'll take a look at an example below a ball that travels moves across the screen
VAR BX,BY
BX=0
BY=120

VAR T,DELTA
T=MILLISEC

VAR LASTTIME=T

WHILE 1
'WAIT 5

'DELTA TIME IN SECONDS
DELTA=(MILLISEC-T)/1000

'UPDATE T
INC T,DELTA

'MOVE 50 PIXELS EVERY SECOND
INC BX,50*DELTA

IF BX+15>400 THEN
 DEC BX,400
 CLS
 PRINT (MILLISEC-LASTTIME)/1000
ENDIF
WEND
When you run this you will see a ball move from left to right every 8 seconds. You can even try uncommenting the wait command and you should get roughly the same results, albeit with a noticeable drop in frame rate. I will include a code for a more complex program below which can draw 10 or even 1000 bouncing balls with no drop in the perceived timings of the physics. One thing I would like to note is that MILLISEC continues to count up even if the user has pressed the home button, so you can use something like the following to prevent unnecessarily large delta times.
'SOMEWHERE AROUND THE 2-4 SECOND RANGE IS ADEQUATE FOR MOST CASES
IF DELTA># THEN DELTA=#
Now this technique does not have to be applied to every situation, but if you are doing something physics related or you know that your application experiences lag from time to time, then this may be what you need in order to 'pretend' you have a smooth sixty frames per second all the time. Also, you want to make sure you take the necessary precautions if you are applying this in a physics engine. One example of this is "collision tunneling" which will not detect a collision between two high speed and/or small objects and they will effectively pass right through each other. If you are interested in applying absolute timing to your physics based game, there is a wealth of resources related to the subject that can be searched. Just to give you an idea, SmileBasic allows you to specify a collision velocity which can be used to effectively resolve collisions between sprites. Of course if your app is running less than five frames per second then optimization may be the route you are looking for ;) Code: 252E724V Instructions: -Up/Down: increase/decrease number of balls (max/default 2000) -A: reset(number of balls stays the same)

This is very useful. However, anyone that use this with physics should keep in mind that this could provoke "collision tunneling". I've read that this can be prevent with raycast but I've never done that before on smilebasic.

Replying to:raimondz
This is very useful. However, anyone that use this with physics should keep in mind that this could provoke "collision tunneling". I've read that this can be prevent with raycast but I've never done that before on smilebasic.
That is an excellent point. I was considering whether or not I should include that as a note, but decided that it would be more appropriate for a tutorial that is dedicated to "resolving" collisions (The web is your best friend here). For example, the app that can be downloaded does not resolve collisions between the balls and the edges of the screen. It simply asks "are they out of bounds and going away from the screen?" If it really resolved the collisions, it would check if the ETA between the ball and the wall is less than the delta time and go from there. Of course, this approach is most appropriate for when accurate collision detection is needed(i.e. lossless physics, not an actual term). I will include that into the tutorial somewhere as a heads up, and I'm glad you liked it!

T+=DELTA would be better than T=MILLISEC, just in case there is a 'tick' of the millisec clock in between one instruction and the next.

Replying to:SquareFingers
T+=DELTA would be better than T=MILLISEC, just in case there is a 'tick' of the millisec clock in between one instruction and the next.
Do you mean INC T,DELTA? SB has no += so I have to be sure.

Replying to:SquareFingers
T+=DELTA would be better than T=MILLISEC, just in case there is a 'tick' of the millisec clock in between one instruction and the next.
Updated.

` != '

So I can use this to sense the home button being pressed? That would be cool for an idea I have.

Wow This Is amazing! a way to detect the home button being pressed! The only downside to this is if you spam tap the bottom screen it will detect that too, but it isn't not a big deal. Thanks!!!!!!!!
T=MILLISEC
WHILE 1
'wait is optional
WAIT 4
DELTA=(MILLISEC-T)/1000
INC T,DELTA

IF DELTA>"2-5" THEN whatever happens when home button is pressed"
WEND

Replying to:Joshuaham123
Wow This Is amazing! a way to detect the home button being pressed! The only downside to this is if you spam tap the bottom screen it will detect that too, but it isn't not a big deal. Thanks!!!!!!!!
T=MILLISEC
WHILE 1
'wait is optional
WAIT 4
DELTA=(MILLISEC-T)/1000
INC T,DELTA

IF DELTA>"2-5" THEN whatever happens when home button is pressed"
WEND
Use my function instead, it's more reliable and you don't have to run it constantly.

what are you trying to say?