sync on
backdrop on
sync rate 40
set camera range 50,10000
set ambient light 40
 
 
gosub make_car
gosub make_texture
gosub make_desert
 
color backdrop RGB(0,0,64)
fog on
fog color RGB(0,0,64)
fog distance 9000
 
accel#=1
speed#=0
brake#=2
gfric#=0.5
x#=7500.0
z#=7500.0
oldm_x=2
oldm_z=2
 
do
 
if upkey()
   speed#=speed#+accel#
else
   if downkey()
      speed#=speed#-brake#
   else
      speed#=speed#-gfric#
   endif
endif
if speed#<=0 then speed#=0
if speed#>60 then speed#=60
 
if speed#>0 then yr#=wrapvalue(yr#+rightkey()-leftkey())
x#=x#+sin(yr#)*speed#
z#=z#+cos(yr#)*speed#
y#=get ground height(1,x#,z#)
cx#=x#-sin(yr#)*500
cz#=z#-cos(yr#)*500
cy#=y#+200
 
pos_bugy(x#,y#,z#,yr#)
 
position object 1,x#,y#+25,z#
position camera cx#,cy#,cz#
point camera x#,y#,z#
 
if spacekey() then end
 
sync
loop
end
 
make_car:
`create the "car" thingy
make object box 1,40,30,100
color object 1,RGB(128,128,0)
make object sphere 2,20: scale object 2,400,20,20: make mesh from object 1,2
add limb 1,1,1: add limb 1,2,1
delete object 2: delete mesh 1
make object sphere 2,40: scale object 2,50,100,100: make mesh from object 1,2
for k=3 to 6: add limb 1,k,1: next k
offset limb 1,1,0,-10,-35: color limb 1,1,RGB(255,255,255)
offset limb 1,2,0,-10,35: color limb 1,2,RGB(255,255,255)
offset limb 1,3,35,-10,-35: color limb 1,3,RGB(0,0,0)
offset limb 1,4,-35,-10,-35: color limb 1,4,RGB(0,0,0)
offset limb 1,5,35,-10,35: color limb 1,5,RGB(0,0,0)
offset limb 1,6,-35,-10,35: color limb 1,6,RGB(0,0,0)
delete object 2
delete mesh 1
 
`create arrays for wheel positioning and axis rotation
`4 - number of wheels
`5 - x,y,z position plus 2 angles(x,z)
dim w_pos#(4,5)
 
 
return
 
 
make_desert:
`matrix tile count and smoothing value
size=600
smooth=5
factor#=3
 
dim hm#(size,size)
dim nhm#(size,size)
`generate random height table
randomize timer()
 for y=0 to size
   for x=0 to size
      c=rnd(255)
      hm#(x,y)=c
   next x
next y
`smoothing process (my english is sooo rusty...)
for k=1 to smooth
for y=0 to (size)
   for x=0 to (size)
      if x < size and x > 0 and y < size and y > 0
         tot#=hm#(x-1,y-1)+hm#(x-1,y)+hm#(x-1,y+1)
         tot#=tot#+hm#(x,y-1)+hm#(x,y+1)+hm#(x+1,y-1)
         tot#=tot#+hm#(x+1,y)+hm#(x+1,y+1)
         tot#=tot#/8.0
         tot#=(tot#+hm#(x,y))/2.0
      endif
      nhm#(x,y)=tot#`it ought to use the same one as the last loop, just to give it a valid value :)
   next x
next y
`update height table
for y=0 to (size)
   for x=0 to (size)
      hm#(x,y)=nhm#(x,y)
   next x
next y
next k
`raise height by a factor
for y=0 to size
   for x=0 to size
      nhm#(x,y)=nhm#(x,y)*factor#
   next x
next y
`wrapping the edges
for tile=0 to (size)
   tot#=(nhm#(0,tile)+nhm#((size),tile))/2.0
   nhm#(0,tile)=tot#
   nhm#((size),tile)=tot#
   tot#=(nhm#(tile,0)+nhm#(tile,(size)))/2.0
   nhm#(tile,0)=tot#
   nhm#(tile,(size))=tot#
next tile
`creating the matrix
make matrix 1,100000,100000,size,size
prepare matrix texture 1,1,1,1
fill matrix 1,0,1
for y=0 to (size)
   for x=0 to (size)
      set matrix height 1,x,y,nhm#(x,y)
   next x
next y
`normalise (or something like that. too lazy to properly do it)
for y=0 to (size)
   for x=0 to (size)
      if x < size and x > 0 and y < size and y > 0
         nx#=nhm#(x+1,y)-nhm#(x,y)
         nz#=nhm#(x,y+1)-nhm#(x,y)
         nx#=-1*cos(atanfull((100000/size),nx#))
         nz#=-1*cos(atanfull((100000/size),nz#))
         ny#=0.1
      endif
      set matrix normal 1,x,y,nx#,ny#,nz#`it ought to use the same one as the last loop, just to give it a valid value :)
   next x
next y
 
update matrix 1
return
 
 
make_texture:
ink RGB(176,133,2),0
box 1,1,128,128
`creating the sand texture
`its an effort to estimate values that should create
`several shades of orange-yellow.
`the slow way as always. couldn't be bothered.
for k=1 to 5000
   shadeR=rnd(70)
   red=150+shadeR
   shadeG=(6*shadeR)/7
   green=124+shadeG
   shadeB=shadeR/7
   blue=18+shadeB
   dot rnd(128),rnd(128),rgb(red,green,blue)
next k
get image 1,1,1,128,128
return
 
 
Function Pos_bugy(x#,y#,z#,yr#)
 
`conviniently enough the distance from the center of the car
`to each wheel axis is 35, as is the distance of each wheel
`from the center of the respective axis. ain't that nice?
 
`front axis (center)
   fax#=x#+sin(yr#)*35
   faz#=z#+cos(yr#)*35
`rear axis
   rax#=x#-sin(yr#)*35
   raz#=z#-cos(yr#)*35
 
`front wheels
   `right
   frwa#=wrapvalue(yr#+90)
   fwrx#=fax#+sin(frwa#)*35
   fwrz#=faz#+cos(frwa#)*35
   `left
   flwa#=wrapvalue(yr#-90)
   fwlx#=fax#+sin(flwa#)*35
   fwlz#=faz#+cos(flwa#)*35
`rear wheels
   `right
   rrwa#=wrapvalue(yr#+90)
   rwrx#=rax#+sin(rrwa#)*35
   rwrz#=raz#+cos(rrwa#)*35
   `left
   rlwa#=wrapvalue(yr#-90)
   rwlx#=rax#+sin(rlwa#)*35
   rwlz#=raz#+cos(rlwa#)*35
 
`find heights for each wheel and calculate axis angles
`this should be fun...
 
   frwh#=get ground height(1,fwrx#,fwrz#)
   flwh#=get ground height(1,fwlx#,fwlz#)
   rrwh#=get ground height(1,rwrx#,rwrz#)
   rlwh#=get ground height(1,rwlx#,rwlz#)
   `what a magnificent mess:)
 
   xd#=70    `this is not the real x distance but without the angle i cannot find it.
   yd#=frwh#-flwh#
   faza#=wrapvalue(90-atanfull(xd#,yd#))
   set object rotation zyx 1
   rotate object 1,0,yr#,faza#
 
Endfunction