Posted: Thu May 08, 2003 10:39 pm Post subject: [tutorial]Frame per Seconds
I decided that I will write this up, since it helped me out so much in my game. Btw, this is my first tutorial, so bear with me if I am not making things clear, also post anything that you don't get.
The whole idea is about delaying the game when your game runs too fast.
The Idea:
if the time between refreshing of the screen is very little, then we put a delay at the end, after our drawscreen procedure (having this procedure will benefit you alot), if the time between refreshing is too long, then we don't delay, because that's the maximum rate your computer can draw.
code:
var Time_Start : int
var Time_LastFrame : int := 0
var Time_Frame : int := 0
var Time_LastFrameRate : int := 0
var Time_FrameRate : int
const Time_MaxFrameRate : int := 30
const Time_MinMilliSecBetwFrames : int := 1000 div Time_MaxFrameRate
procedure drawscreen
% do everything else here, like drawing your objects
% then do this after you have drawn everything
Time_Frame is the last time your program refreshed
Therefore, the frame-rate is the time between the last time your
computer refreshed and the current time, all divided into 1000
because the time functions in turing all uses milliseconds.
code:
Time_FrameRate := 1000 div (Time.Elapsed - Time_Frame)
Here, if the frame rate differ by more than one, usually through some actions taken by your program, we change the last frame rate to the current one, this way, the last frame rate is always updated.
code:
if abs (Time_LastFrameRate - Time_FrameRate) > 1 then
Time_LastFrameRate := Time_FrameRate
end if
code:
% resetting Time_Frame
Time_Frame := Time.Elapsed
end drawscreen
%Getting the starting time
Time_Start := Time.Elapsed
loop
%Drawing the screen first, and get all your required calculation done
drawscreen
Here we check to see the time between last time this part was accessed and the current time. If the difference between these are very small, then that means your program is running very fast, and the screen is being constantly refreshed, then we want to delay the game for a bit, so the game doesn't run so fast so the player will have time to react. But how long do we delay for? That is usually predetermined by the user under the Time_MaxFrameRate variable. Since Time_MinMilliSecBetwFrames = 1000 div Time_MaxFrameRate, then the bigger u set Time_MaxFrameRate, the smaller Time_MinMilliSecBetwFrames is. The smaller this is, the faster your program runs, because we are delaying an amount proportional to Time_MinMilliSecBetwFrames.
code:
if Time.Elapsed - Time_LastFrame < Time_MinMilliSecBetwFrames then
delay (Time_MinMilliSecBetwFrames - (Time.Elapsed - Time_LastFrame))
end if
% resetting Time_LastFrame
Time_LastFrame := Time.Elapsed
end loop
Hopefully this tutorial will help someone, I know it helped me, and I just want to share this with everyone else. If you have a question, suggestion, and especially improvements, please post.
Posted: Thu May 08, 2003 10:41 pm Post subject: (No subject)
nice tutorial
i used a similar method in my asteroids game to cap the frame rate at 30fps (after i posted)
Tony
Posted: Thu May 08, 2003 10:46 pm Post subject: (No subject)
awesome tutorial +50 Bits
though I'd also like to see you use it in an example when its all put together. Doesnt have to be complex, just put all the code together and put something into draw procedure... then attach as a file
Posted: Thu May 08, 2003 10:47 pm Post subject: (No subject)
i dont get it... =(
why would u need to know how many frames per second u use to make a game and even if u wanna know howmany frames u used in one second
u could just simply put
frame+=1 after each view.Update
and in every second count the number of frames
code:
function timedelay (var r : int, t : int) : boolean
var tt : int
clock (tt)
if r = 0 then
clock (r)
result false
end if
if tt - r >= t then
r := tt
result true
else
result false
end if
end timedelay
var time1, frames, i := 0
View.Set ("offscreenonly")
loop
drawfillarc (320, 200, 150, 150, i, i + 20, i div 10)
View.Update
frames += 1
i += 1
if timedelay (time1, 1000) then
locate (1, 1)
put frames, " fps"
View.Update
frames := 1
i := 1
end if
end loop
Tony
Posted: Thu May 08, 2003 10:51 pm Post subject: (No subject)
the point is to balance out the game speed. Such as in Catalyst's asteroyds demo (he said he fixed it now)...
at the beginning when you have all those asteroids game is running slow as there's a lot of calculations and drawings going on... but as you kill it, speed increaes 10 times...
using frames per second to adjust your delay with balance the speed issue out so you'll have roughly the same game speed regardless of the situation.
Posted: Thu May 08, 2003 10:52 pm Post subject: (No subject)
I see... good thinkin...
is my code doing the same thing as asiansensaition is doing...or does it have to be changed to be able to help....?
Tony
Posted: Thu May 08, 2003 10:57 pm Post subject: (No subject)
no, yours just measures the frame rate... his actually goes a step further and adjusts the delay.
A little sujestion though... if speed gets really bad (i donno, more objects on speed then you expect) that delay value gets up to 0, it might be faster to use an if statment to bypass it as delay(0) still pauses...
someone, please tell me. Whats faster to execute? a loop with delay(0) or a loop with "if 1-1 >0 then delay(0) end if"
want to know what takes up more time. Delay(0) or an if statment. Let me know
Posted: Wed May 14, 2003 3:29 pm Post subject: thx
thx meng for ur help
naoki
Posted: Mon May 19, 2003 3:04 pm Post subject: (No subject)
really useful for a program like mine that has procs and processes popping in and out
*thumbs up*
hello
Posted: Thu May 22, 2003 7:33 pm Post subject: (No subject)
im still confused because when i run it the is still some difference in speed
can u expnad on the tutorial
do i need to have the frames part in every proc or process that i have drawn something
AsianSensation
Posted: Thu May 22, 2003 7:43 pm Post subject: (No subject)
k, I'll try to answer that question.
Notice how the delay is structured. It is at the very end of the main loop. After each time the screen is refreshed, you will get bunch of values for all the Frame variables. So if you redraw your screen at some other instance other than refreshing it, for example, you want to clear the screen and put whatever is on the screen back on, then you called the drawscreen procedure, but that means that you got a whole new bunch of values for the Frame variables, and when you refresh the screen at the end, the time passed is not that much, so it delays the program more.
You can fix this by setting a couple of flags, and only activate the Frame part of your drawscreen procedure if the flag is true, and only turn the flag true if you are trying to refresh the screen.