Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: Shockwave on August 28, 2006
-
I have played around a lot with this and I have found that the best method is to take a reading of how many frames were drawn in the last 1/5 of a second and use that to divide an addition variable (for movement typically) by. Be careful that the program doesn't slow right down so that it stops. This can happen so be careful with the values that you give it.
This example is quite unelegant but it will give you the basic idea;
'###
'### Delta Timing Example.
'### This will show you how to make things look smooth on nearly all systems.
'###
option static
option explicit
' To run in fullscreen comment out the line below;
#define PTC_WIN
#Include Once "tinyptc.bi"
'
' Screen Resolution;
'
CONST XRES = 800
CONST YRES = 600
CONST HALFX = XRES/2
CONST HALFY=YRES/2
dim shared as UINTEGER BUFFER (XRES * YRES)
' Set up the starfield;
dim shared as integer stnum = 20000
dim shared as double stx(stnum)
dim shared as double sty(stnum)
dim shared as double stz(stnum)
dim shared lp as integer
for lp=1 to stnum
stx(lp) = -20000+rnd*(40000)
sty(lp) = -20000+rnd*(40000)
stz(lp) = rnd*32
next
declare sub stars()
DECLARE SUB DBUFFER()
DECLARE SUB DELTA()
DIM SHARED AS DOUBLE M ,oldtime,newtime
dim shared ticks as integer
'-------------------------------------------------------------------------
' Open Screen.
'-------------------------------------------------------------------------
If( ptc_open( "DELTA TIMING", XRES, YRES ) = 0 ) Then
End -1
End If
do
STARS()
DBUFFER()
'****
'**** REMOVE THE COMMENT BELOW AND TRY DIFFERENT SLEEP VALUES TO SLOW DOWN
'**** THE PROGRAM TO SEE HOW IT COMPENSATES.
'****
'SLEEP 1
loop until inkey$ = chr$(27)
PTC_CLOSE
END
SUB DBUFFER()
ptc_update@buffer(0)
'***
'*** THIS ADDITION TO THE FRAME COUNTER IS CRITICAL, WE WILL BASE THE SPEED
'*** OF THE STARFIELD ON HOW MANY FRAMES ARE DRAWN IN A GIVEN TIME.
'***
TICKS=TICKS+1
ERASE BUFFER
DELTA()
END SUB
Sub Stars()
dim tx,ty,clv as integer
DIM DMOVE AS DOUBLE
'***
'*** DMOVE IS THE VARIABLE WE USE TO MOVE THE STARS, THIS NEEDS CAREFUL THOUGHT.
'*** IF YOU CHOOSE A LOW VALUE THEN YOU NEED TO LOOK AT HOW MANY FRAMES YOU ARE
'*** AVERAGING OVER BECAUSE IF YOU ARE ONLY AVERAGING OVER A TINY AMOUNT OF FRAMES
'*** YOU WILL GET INCONSISTENCIES.
'*** IT IS BETTER TO CHOOSE A FAIRLY HIGH VALUE LIKE 7 IF YOU ARE AVERAGING OVER
'*** ANYTHING AROUND 1/3 OF A SECOND.
'*** TINKER WITH IT TO FIND THE BEST VALUE IS MY ADVICE.
'***
DMOVE = 7 / NEWTIME
for lp=1 to stnum
tx=(stx(lp)/stz(lP))+Halfx
ty=(sty(lp)/stz(lP))+Halfy
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES AND STZ(LP)>0 THEN
CLV = (INT( - STZ(LP) )+ 32 ) SHL 3
BUFFER(TX+(TY*XRES)) = RGB(CLV,CLV,CLV)
STZ(LP)=STZ(LP)-DMOVE
ELSE
stx(lp) = -20000+rnd*(40000)
sty(lp) = -20000+rnd*(40000)
stz(lp) = 32
END IF
next
end sub
SUB DELTA()
'*** WE WILL LOOK AT HOW MANY FRAMES HAVE BEEN DRAWN EVERY 1/5TH OF A SECOND.
'*** WE BASE OUR AVERAGE DIVISOR ON THIS.
'*** THIS DIVISOR IS USED IN THE STARS PROCEDURE TO MOVE THE STARS.
DIM LPT AS INTEGER
DIM TST AS STRING
dim as double bb
bb=timer
if bb-oldtime >=.2 then
oldtime=timer
newtime = ticks
TST = str( (newtime) )
TST = "DELTA FACTOR: "+TST
print tst
TST = str( (newtime*5) )
TST = "APPROX FPS: "+TST
print tst
'Prevent the program getting stuck!!;
'Progressive slowdown and eventual stop is possible without this.
newtime=newtime+1
ticks=0
end if
END SUB
-
cool example!!!
-
Neat mate, and welldone on figuring this out.
-
Thank you, I hope to see some smooth demos using this technique :)
-
Shockwave,
Ive just upped (is that a real word) the stars to 40,000 and it still as smooth as silk . . .
I know the object is delta timing but that starfield is superb!!!
Regards
DrewPee
-
Feel free to use / adapt the starfield if you like Drew. :)
On most modern PC's you'd need to increase the stars number to over 100,000 before it started to seriously hit the performance.
The thing to change is the sleep value if you really want to see hpw the program compensates for low fps.