I spent a while trying to make sense of the whole thing and did come cleaning/commenting.
Import BRL.Random
Import BRL.BMPLoader
Global scx#=800,scy#=600
Graphics scx,scy,0,60
Global pathsize=1024 'This is the paths TRUE length (integer?)
Global multiplier#=250 'This is how much this path is interpolated. (pathsize is multiplied by this)
Global pathlength#=pathsize*multiplier 'This is the virtual paths length.
Global pathc2#[pathsize+1]
Global pathd2#[pathsize+1]
Global pathflag2[pathsize+1] 'Set flags for what is on the track:'1=streetlamps,2=left wall,3=right wall,4=tunnel
Global iswater[pathsize+1]
Global drawamt=700 'Amount of track to draw in one go
Global drawbit[drawamt+1] 'Buffer used to store which bits of track need to be drawn
Global maxcars=50 '500 cars at one time on the track!?!?! lower this for less ;)
Global carx#[maxcars+1] 'Where on the track the car is (left-right. Values -1 to +1)
'Global cary#[maxcars+1] 'Not used yet- Maybe add jumping?
Global carpos#[maxcars+1] ' where along the path each car is stored
Global drawcar[maxcars+1] 'Flag for each car- does it get drawn?
Global drawx[maxcars+1] 'X coordinate for drawing car. Set when you set Drawcar[car]=1
Global drawy[maxcars+1] 'y coordinate for drawing car. Set when you set Drawcar[car]=1
Global drawsz#[maxcars+1] 'size for drawing car. Set when you set Drawcar[car]=1
Global carspeed#[maxcars+1] 'Speed of car. Best results are between 1 and 3.
Global maxspeed#[maxcars+1] 'max Speed of car. Best results are between 1 and 3.
Global player=1 'Player's car number
'Position the cars randomly
For n=1 To maxcars
carx#(n)=((n Mod 2)-.5)
carspeed(n)=0
maxspeed(n)=Rnd(2,3)
carpos(n)=n*10
Next
maxspeed(1)=3.5
Rem
Graphics loading routine here
EndRem
AutoMidHandle 1
SetMaskColor(10,20,255)
'Global maxframes=49
'Global carimage=LoadAnimImage("caranim.png",256,128,0,maxframes+1)
Global maxframes=5 ' was 49
Global carimage=LoadAnimImage("space1.bmp",256,128,0,maxframes+1)
If carimage=Null Then RuntimeError "Car not found!"
'##############################################################
'Generate the level data using random info
'##############################################################
c#=0 ' represents the change in X
d#=0 ' represents the change in slope
targd#=Rand(-3,4)
targc#=Rand(-3,3)
cnt=0
For n=multiplier To pathlength
' Handle water
If Rand(0,1000)>999 And watercount=0 Then
watercount=Rand(1,3)*1
EndIf
If watercount>0 Then
iswater[n/multiplier]=1
watercount=watercount-1
EndIf
' Put stuff on the track
If Rand(0,multiplier)>multiplier-(multiplier/100) Then
pathflag2(n/multiplier)=Rand(1,4)
EndIf
' update the direction
If Rand(0,100)>99 Or cnt>multiplier*10 Then
cnt=0
tc#=targc
targc#=Rand(-3,3)
If Rand(0,10)>5 Or tc<>0 Then
targc=0
cnt=-1
EndIf
EndIf
If cnt>-1 Then
cnt=cnt+1
EndIf
mc#=mc+(c#-targc#)/10.0
If Abs(mc)>.1 Then
mc=Sgn(mc)*.1
EndIf
' Update the slope
If Rand(0,100)>90 Then
targd#=Rand(-3,4)
If Rand(0,10)>5 Then
targd=0
EndIf
EndIf
md#=(d#-targd#)/5.0 ' 10.0 5 is harder
If Abs(md)>.1 Then
md=Sgn(md)*.1
EndIf
' some fiddling... go figure
If n=0 Or n>pathlength-100 Then
targd=0
targc=0
EndIf
' Update the parameters with the modifiers
c=c+mc
mc=mc*.9
'c=targc this is not needed
d#=d#-md
d=d*.9 'slowly diminish
c=c*.9 'slowly diminish
'c=0
'd=0
pathc2[n/multiplier]=c*2 'was 5 : intensity of the turn
pathd2[n/multiplier]=d*.001
'Print "mc="+mc+" md="+md
Next
'##############################################################
' MAIN LOOP
'##############################################################
patchmult=4
dmult#=1.02 'very important parms but not that understandable now...
ymult#=1.0 '0.5 '.5 'very important parm to update y (.1 makes the track very flat, .8 more viewed from above)
pathpos#=0
cnt=0
Repeat
If KeyDown(key_tab) Then WaitKey;WaitKey
'##############################################################
' Update car positions
'##############################################################
For n=1 To maxcars
carpos(n)=carpos(n)+carspeed(n)
carpos(n)=carpos(n) Mod pathlength
If carpos(n)<0 Then carpos(n)=carpos(n)+pathlength
carpos(n)=carpos(n)
drawcar(n)=0
carspeed(N)=carspeed(N)*.999
If carspeed(n)>maxspeed(n) Then carspeed(n)=maxspeed(N)
If n<>player Then carspeed(n)=carspeed(n)+.01
Next
'##############################################################
' Move 1 step further in the path
'##############################################################
pathpos=(pathpos+1) Mod pathlength
' Steer player's car.
xdir#=xdir#-KeyDown(key_left)+KeyDown(key_right)
' dampen movement
xdir=xdir*.8
' change X position on track by 1%
' carx(player) is between -1 and +1 to stay on track. It can go further but this will be in the outside of the track.
carx(player)=carx(player)+xdir#*.01
' Manage speed: increase/decrease 1%
carspeed(player)=carspeed(player)+(KeyDown(key_up)-KeyDown(key_down))*.01
pathpos2#=pathpos
pos#=pathpos
x#=scx/2.0 ' Middle of screen / track
y#=scy*1 '.2 BOTTOM OF SCREEN
d#=10 ' d = ?
d2#=10*120 'd2 = 120 x 10 (120=track width)
oy#=y 'oldy ?
miny#=scy*4 ' 4 times the screen height (just to be sure it is more than scy I guess)
' remember that carx(player) is between -1.0 and +1.0
' -1 means: scx/2 - (-1) * scx *1.5 : 400 - (-1)*1200 = +1600
' +1 means: 400 - (+1) *1200 = 800
x=(scx/2.0)-carx(player)*scx*1.5
xdf#=((scx/2.0)-x)*.003*.7
stx#=carx(player)
mv#=((pathc(pathpos)-pathc(opathpos))/10.0)
cnt=0
dc#=0
xc#=0
' divide to advance on track : 5%
div#=.05
'##############################################################
' DETERMINE WHAT HAS TO BE DRAWN
'##############################################################
Repeat
ok=0
drawbit(cnt)=0
If y<=miny Then
miny=y
drawbit(cnt)=1
EndIf
cnt=cnt+1
If cnt>drawamt Then
ok=1 'set the OK flag if we've gone through enough track.
EndIf
d#=d#/dmult#
d2#=d2#/dmult
d4#=d#
If d4<1 Then
d4=1
EndIf
'Change X value to make the tracks corners work properly
x=x+(Float(pathc(pos)-pathc(pathpos)))
x=x+xdf*d
'Change y value to make the tracks corners work properly and give perspective
'This is the key place !!!
dc#=dc#+pathd(pos)
y=y+dc
y=y-(d*ymult)
'adiv
adiv#=div#
If adiv<1 Then
adiv=1
EndIf
'advance on track
pos=(pos+adiv) Mod pathlength
If pos<0 Then
pos=pos+pathlength
EndIf
'increase div by 2%
div=div*1.02
Until ok=1 Or KeyDown(key_escape)
' Drawing starts here.
Cls
SetColor 70,50,200
DrawRect 0,0,scx,miny-1 'draw sky (using the damn miny)
'Okay, now lets do it all again backwards and draw stuff at the same time.
od3#=0
Repeat
DIV=DIV/1.02
adiv#=div#
If adiv<1 Then
adiv=1
EndIf
opos#=pos#
pos=(pos-adiv) Mod pathlength
If pos<0 Then
pos=pos+pathlength
EndIf
cnt=cnt-1
'Change y value to make the tracks corners work properly and give perspective
y=y+(d*ymult)
y=y-dc
dc=dc-pathd(pos)
'Change X value to make the tracks corners work properly
X=x-(Float(PATHC(POS)-PATHC(pathpos)))
x=x-xdf*d
ok=0
d=d*dmult
d2=d2*dmult
d4#=d#
If d4<1 Then
d4=1
EndIf
x1=x-(pathc(pos))-d2
x2=x+(pathc(pos))+d2
dq=0
If Abs(y-oy)>.01 Then
dq=1
EndIf
y2#=Abs(y-oy)
' There is something to draw for the current position
If drawbit(cnt)=1 Then
'grass/water colouring
If iswater(pos/multiplier)=0 Then
If (Int(pos/(8*patchmult)) Mod 2)=0 Then SetColor 0,180,0 Else SetColor 0,200,0
Else
SetColor 0,0,255
EndIf
'draw the grass/water
If dq=1 Then
Drawquad 0,y,x1,y,ox1,oy,0,oy
Drawquad scx,y,x2,y,ox2,oy,scx,oy
EndIf
'Draw track "edges"
If (Int(pos/(2*patchmult)) Mod 2)=0 Then SetColor 255,0,0 Else SetColor 255,255,255
drawquad x1-d*16,y,x1,y,ox1,oy,ox1-d*16,oy
drawquad x2,y,x2+d*16,y,ox2+d*16,oy,ox2,oy
'tarmac colouring
If (Int(pos/(7*patchmult)) Mod 2)=0 Then SetColor 120,120,120 Else SetColor 80,80,80
'draw tarmac
If dq=1 Then
drawquad x1-1,y,x2+1,y,ox2+1,oy,ox1-1,oy
EndIf
'Draw white strip
If (Int(pos/(9*patchmult)) Mod 2)=0 And dq=1 Then
SetColor 255,255,255
Drawquad x-d,y,x+d,y,ox+od#,oy,ox-od#,oy
EndIf
EndIf
'Draw tunnels and stuff outside of the "should i draw" check above
d3#=d
apos#=pos
ct=0
div2=div
If div2<.2 Then
div2=.2
EndIf
If pos > apos+div2 Then
pos=apos+div2
EndIf
If d3<.02 Then
d3=.02
EndIf
' There is a lamp pole
If pathflag(pos)=1 Then
SetColor 255,255,255
If Int(pos Mod 20)=10 Then
DrawRect x2+(d3*40),y-(d3*100),d3*10,d3*100
EndIf
If Int(pos Mod 20)=0 Then
DrawRect x1-(d3*40),y-(d3*100),d3*10,d3*100
'DrawLine x1,y-(d*100),x1,y
EndIf
EndIf
drawtunnel=pathflag(pos)-1 ' since walls and tunnels are higher than 1, there will be something to do.
If drawtunnel<0 Then
drawtunnel=0
EndIf
' There is something to do
If drawtunnel>0 Then
SetColor 10,100,20
'Left wall or tunnel, draw left edge
If drawtunnel=1 Or drawtunnel=3 Then
Drawquad x2+(d3*25),y-(d3*100),ox2+(od3#*25),oy-(od3*100),ox2+(od3*25),oy,x2+(d3*25),y
EndIf
'Right wall or tunnel, draw right edge
If drawtunnel=2 Or drawtunnel=3 Then
Drawquad x1-(d3*25),y-(d3*100),ox1-(od3#*25),oy-(od3*100),ox1-(od3*25),oy,x1-(d3*25),y
EndIf
'Tunnel, draw top
If drawtunnel=3 Then
DY1=y-(d3*100)+2
DY2=Oy-(Od3*100)+2
SetColor 0,60,0
Drawquad X1-(D3*25),DY1,X2+(D3*25),DY1,oX2+(oD3*25),DY2,ox1-(od3*25),dy2
EndIf
EndIf
' ??? what is D ?
' Draw cars
If d > 0.1 Then
SetColor 255,255,255
For n=1 To maxcars
If Int(carpos[n])=Int(pos) Then 'Draw car
'set flag and store where to draw the cars!?
drawcar(n)=1 ' draw it
drawx(n)=x+carx(n)*(d2) ' x position
drawy(n)=y ' y position
drawsz#(n)=d*10 ' size
' compute scaling factor
sc#=d/10
sc=sc*2
SetScale sc,sc
' Which frame to draw (depend on the position of the car vs the position of the driver's car)
fr=-(carx(n)-stx)*10
If n=1 Then fr=fr+xdir
fr=fr+(pathc(pos)-pathc(pathpos))*5
If fr<-8 Then fr=-8
If fr>8 Then fr=8
fr=fr+8
If fr>maxframes Then fr=maxframes
If fr<0 Then fr=0
DrawImage carimage,drawx(n),drawy(n)-(ImageHeight(carimage)/3)*sc,fr
EndIf
Next
SetScale 1,1
EndIf
'Store old values.
od3#=d3#
ox1=x1
ox2=x2
ox=x
oy=y
od#=d#
If cnt<1 Then ok=1 'set the OK flag If weve drawn enough track.
Until ok=1 Or KeyDown(key_escape)
opathpos=pathpos
DrawText pathpos,10,10
DrawText carx(player),10,40
pathpos=carpos(player)-10
If pathpos<0 Then pathpos=pathpos+pathlength
'bglSwapBuffers()
Flip
Until KeyDown(key_escape)
End
Function drawquad(x1#,y1#,x2#,y2#,x3#,y3#,x4#,y4#)
Local poly#[]=[Float(x1),Float(y1),Float(x2),Float(y2),Float(x3),Float(y3),Float(x4),Float(y4)]
DrawPoly poly
End Function
Function pathc#(pos#)
pos=pos/multiplier
pos=pos Mod pathsize
Local pos2=(pos+1) Mod pathsize
val1#=pathc2#(Floor(pos))
val2#=pathc2#(Floor(pos2))
val3#=pos#-Floor(pos#)
Return interpolate#(val1#,val2#,val3#)
End Function
Function pathd#(pos#)
pos=pos/multiplier
pos=pos Mod pathsize
Local pos2=(pos+1) Mod pathsize
val1#=pathd2#(Floor(pos))
val2#=pathd2#(Floor(pos2))
val3#=pos#-Floor(pos#)
Return interpolate#(val1#,val2#,val3#)
End Function
Function pathflag(pos)
Return Floor(pathflag2((pos/multiplier) Mod pathsize))
End Function
Function interpolate#(val1#,val2#,decimal#)
Return Float(val1)+Float(Float(val2)-Float(val1))*decimal
End Function
Of course, there are places where I have not clue on what this does. I googled for a while but wasn't able to find out any info on the algorithm.
|