`Standard setup
Sync on : Sync rate 60
Set display mode 1024,768,16 : Hide mouse
Autocam off : Set camera range 1,0x7fffffff
 
`Load Physics Functions
`#include "ZPhysics.dba"
 
`Start World Physics
Start_World_Physics()
Set_World_Standards()
 
`Create Player
create Bitmap 1,128,128 : set current bitmap 1
for x=1 to 64 : for y=1 to 64
   if rnd(1)=1 then ink rgb(133,162,119),0 else ink rgb(0,128,0),0
   box ((x*2)-2),((y*2)-2),(x*2),(y*2)
next x : next y
blur bitmap 1,3 : get image 5,1,1,128,128
set current bitmap 0 : delete bitmap 1
wheels=4
for w=1 to wheels
    create_tyre(w,10,30,20.0,0.97,0.98,10.0)
next w
Create_Chassi(5,50,30,80,20.0,0.97,0.98,10.0)
texture object 5,5 : scale object texture 5,0.1,0.1
turn#=25.0
fuel#=200.0
 
`Create world
create bitmap 1,128,128 : set current bitmap 1
cls rgb(0,128,0)
for d=1 To 10000
ink rgb(0,rnd(255),rnd(50)),0
dot rnd(128),rnd(128)
next d
blur bitmap 1,4
get image 10,0,0,128,128
set current bitmap 0 : delete bitmap 1
 
`Create and Mold
make matrix 1,20000,20000,50,50
randomize matrix 1,50
prepare matrix texture 1,10,1,1
update matrix 1
 
`**Main loop**
Do
 
`Controls
if upkey()=1 or keystate(17)=1 then set_linear_force(5,dirX(5)*MoveConstant(5),dirY(5),DirZ(5)*MoveConstant(5))
if leftkey()=1
   set_angular_force(1,0,-(Movespeed(1)/turn#),0)
   set_angular_force(2,0,-(Movespeed(1)/turn#),0)
endif
if rightkey()=1
   set_angular_force(1,0,(Movespeed(1)/turn#),0)
   set_angular_force(2,0,(Movespeed(1)/turn#),0)
endif
if upkey()=0 and keystate(17)=0 or fuel#=0.0 then set_linear_force(5,0,0,0)
if leftkey()=0 and rightkey()=0 then set_angular_force(1,0,0,0) : set_angular_force(2,0,0,0)
Set_Next_Angle_Y(5,1,10.0)
For w=3 to 4
   Set_Next_Angle_Y(w,5,10.0)
Next w
 
`Update Physics
for w=1 to wheels
   Set_Linear_Velocity(w,VelX(5),VelY(5),VelZ(5))
   Position_At_Object(w,5)
   Place_On_Matrix(w,1,Object Size Y(w)/2)
next w
Place_On_Matrix(5,1,(Object Size Y(5)/2)+(Object Size Y(5)/5))
Calculate_Offsets_AB(1,5,0,315,60) : Calculate_Offsets_AB(2,5,0,45,60)
Calculate_Offsets_AB(3,5,0,135,60) : Calculate_Offsets_AB(4,5,0,215,60)
for w=1 to 5
Get_Old_Position(w)
Get_Object_Direction(w)
Get_Traction_Force(w)
Get_Drag_Force(w)
Get_Force(w)
Get_Speed(w)
Get_Acceleration(w)
Set_Acceleration(w)
Set_Velocity(w)
Get_Angular_Acceleration(w)
Get_Angular_Velocity(w)
Update_Coordinates_Slide(w)
Update_Angles(w)
Get_Lateral_Forces(w)
Fully_Update_Object_Position(w)
Update_Object_Rotation(w)
Get_Movement_Angle(w)
next w
if upkey()=0 and keystate(17)=0
   if abs(MoveAngY(1)-AngleY(1)) < abs((MoveAngY(1)+180)-AngleY(1))
      angleY(1)=curveangle(MoveAngY(1),angleY(1),10.0)
      angleY(2)=curveangle(MoveAngY(1),angleY(2),10.0)
   else
      angleY(1)=curveangle(MoveAngY(1)+180,angleY(1),10.0)
      angleY(2)=curveangle(MoveAngY(1)+180,angleY(2),10.0)
   endif
endif
 
 
`Camera
ca#=curveangle(angleY(5),ca#,20.0)
cx#=positionX(5)-sin(ca#)*600
cz#=positionZ(5)-cos(ca#)*600
cy#=positionY(5)+300
position camera cx#,cy#,cz#
point camera positionX(5),positionY(5),positionZ(5)
 
`Create DashBoard
dec fuel#,movespeed(5)/2000
if fuel#<=0.0 then fuel#=0.0
ink rgb(0,0,0),0 : box 0,648,1024,768
create_meter(movespeed(5),60,708,5,30,rgb(255,0,255),rgb(255,255,0),"0","90","180","270")
create_meter(fuel#,964,708,5,30,rgb(255,0,255),rgb(255,255,0),"0","90","180","270")
ink rgb(255,255,255),0
text 110,652,"Speed: "
text 914-text width("Fuel: "),652,"Fuel: "
 
`**End loop**
Sync
Loop
 
 
`**Functions**
Function Start_World_Physics()
Dim Gravity(0) as float
Dim Drag(0) as Float
Dim Windx(0) as float
Dim Windy(0) as float
Dim Windz(0) as float
Endfunction
 
Function Start_Object_Physics(o)
Dim Positionx(o) as Float : Dim Positiony(o) as Float : Dim Positionz(o) as Float
Dim OldPosX(o) as Float : Dim OldPosY(o) as Float : Dim OldPosZ(o) as Float
Dim Anglex(o) as Float : Dim Angley(o) as Float : Dim Anglez(o) as Float
Dim MoveAngX(o) as Float : Dim MoveAngY(o) as Float : Dim MoveAngZ(o) as Float
Dim LongForceX(o) as Float : Dim LongForceY(o) as Float : Dim LongForceZ(o) as Float
Dim TracForceX(o) as Float : Dim TracForceY(o) as Float : Dim TracForceZ(o) as Float
Dim DragForceX(o) as Float : Dim DragForceY(o) as Float : Dim DragForceZ(o) as Float
Dim AngForceX(o) as Float : Dim AngForceY(o) as Float : Dim AngForceZ(o) as Float
Dim AngVelX(o) as Float : Dim AngVelY(o) as Float : Dim AngVelZ(o) as Float
Dim AngAccX(o) as Float : Dim AngAccY(o) as Float : Dim AngAccZ(o) as Float
Dim VelX(o) as Float : Dim VelY(o) as Float : Dim VelZ(o) as Float
Dim AccX(o) as Float : Dim AccY(o) as Float : Dim AccZ(o) as Float
Dim DirX(o) as Float : Dim DirY(o) as Float : Dim DirZ(o) as Float
Dim OffsetX(o) as Float : Dim OffsetY(o) as Float : Dim OffsetZ(o) as Float
Dim MoveTime(o) as Float : Dim MoveDist(o) as Float : Dim Power(o) as Float
Dim Movespeed(o) as Float : Dim MoveConstant(o) as Float : Dim Acceleration(o) as Float
Dim TractionConstant(o) as Float : Dim AngularTractionConstant(o) as Float
Dim Mass(o) as Float : Dim Weight(o) as Float
Dim KineticEnergy(o) as Float: Dim WorkDone(o) as Float
Dim LatForce(o) as Float : Dim PushX(o) as Float : Dim PushY(o) as Float : Dim PushZ(o) as Float
Dim Force(o) as Float
Endfunction
 
Function Set_Standard_Gravity()
Gravity(0)=9.8
Endfunction
 
Function Set_Standard_Drag()
Drag(0)=0.43
Endfunction
 
Function Set_World_Standards()
Gravity(0)=9.8
Drag(0)=0.43
Endfunction
 
Function Set_Gravity(g#)
Gravity(0)=g#
Endfunction
 
Function Set_Drag(d#)
Drag(0)=d#
Endfunction
 
Function Create_Chassi(o,w#,h#,l#,mv#,t#,a#,m#)
make object box o,w#,h#,l#
Start_Object_Physics(o)
Set_Object_Constants(o,mv#,t#,a#,m#)
Endfunction
 
Function Create_Tyre(o,w#,r#,mv#,t#,a#,m#)
make object sphere o,100 : scale object o,w#,r#,r#
Start_Object_Physics(o)
Set_Object_Constants(o,mv#,t#,a#,m#)
Endfunction
 
Function Set_Object_Constants(o,mv#,t#,a#,m#)
Set_Move_Constant(o,mv#)
Set_Traction_Constant(o,t#)
Set_Angular_Traction_Constant(o,a#)
Set_Body_Mass(o,m#)
Endfunction
 
Function Set_Move_Constant(o,c#)
MoveConstant(o)=c#
Endfunction
 
Function Set_Traction_Constant(o,c#)
TractionConstant(o)=c#
Endfunction
 
Function Set_Angular_Traction_Constant(o,c#)
AngularTractionConstant(o)=c#
Endfunction
 
Function Set_Body_Mass(o,m#)
Mass(o)=m#
Endfunction
 
Function Weigh_Object(o)
Weight(o)=Mass(o)*Gravity(0)
Endfunction
 
Function Set_Linear_Force(o,x,y,z)
LongForceX(o)=x : LongForceY(o)=y : LongForceZ(o)=z
Endfunction
 
Function Set_Linear_Velocity(o,x,y,z)
VelX(o)=x : VelY(o)=y : VelZ(o)=z
Endfunction
 
Function Set_Angular_Force(o,x,y,z)
AngForceX(o)=x : AngForceY(o)=y : AngForceZ(o)=z
Endfunction
 
Function Set_Angular_Velocity(o,x,y,z)
AngVelX(o)=x : AngVelY(o)=y : AngVelZ(o)=z
Endfunction
 
Function Move_Object(o,spd)
VelX(o)=dirX(o)*spd
VelY(o)=dirY(o)*spd
VelZ(o)=dirZ(o)*spd
Endfunction
 
Function Push_Object(o,spd)
LongForceX(o)=dirX(o)*spd
LongForceY(o)=dirY(o)*spd
LongForceZ(o)=dirZ(o)*spd
Endfunction
 
Function Control_Object_Using_Forces(o,push,turn)
if upkey()=1 then Push_Object(o,push)
if downkey()=1 then Push_Object(o,-push)
if leftkey()=1 then set_angular_Force(o,0,-(MoveSpeed(o)/turn),0)
if rightkey()=1 then set_angular_Force(o,0,(MoveSpeed(o)/turn),0)
if upkey()=0 and downkey()=0 then Push_Object(o,0)
if leftkey()=0 and rightkey()=0 then set_angular_force(o,0,0,0)
Standard_Update(o)
Endfunction
 
Function Control_Object_Using_Velocities(o,spd,turn)
if upkey()=1 then Move_Object(o,spd)
if downkey()=1 then Move_Object(o,-spd)
if leftkey()=1 then set_angular_velocity(o,0,-turn,0)
if rightkey()=1 then set_angular_velocity(o,0,turn,0)
if upkey()=0 and downkey()=0 then Move_Object(o,0)
if leftkey()=0 and rightkey()=0 then set_angular_velocity(o,0,0,0)
Standard_Update(o)
Endfunction
 
Function Get_Movement_Angle(o)
MoveAngX(o)=AtanFull(VelY(o),VelZ(o))
MoveAngY(o)=AtanFull(VelX(o),VelZ(o))
MoveAngZ(o)=AtanFull(VelX(o),VelY(o))
Endfunction
 
Function Set_Next_Angle_X(a,b,smth#)
AngleX(a)=Curveangle(AngleX(b),AngleX(a),smth#)
Endfunction
 
Function Set_Next_Angle_Y(a,b,smth#)
AngleY(a)=Curveangle(AngleY(b),AngleY(a),smth#)
Endfunction
 
Function Set_Next_Angle_Z(a,b,smth#)
AngleZ(a)=Curveangle(AngleZ(b),AngleZ(a),smth#)
Endfunction
 
Function Position_At_Object(a,b)
PositionX(a)=PositionX(b)
PositionY(a)=PositionY(b)
PositionZ(a)=PositionZ(b)
Endfunction
 
Function Get_Old_Position(o)
OldPosX(o)=PositionX(o)-VelX(o)
OldPosY(o)=PositionY(o)-VelY(o)
OldPosZ(o)=PositionZ(o)-VelZ(o)
Endfunction
 
Function Get_Object_Direction(o)
DirX(o)=sin(AngleY(o))*cos(AngleX(o))
DirY(o)=-sin(AngleX(o))
DirZ(o)=cos(AngleY(o))*cos(AngleX(o))
Endfunction
 
Function Get_Traction_Force(o)
TracForceX(o)=DirX(o)*MoveConstant(o)
TracForceY(o)=DirY(o)*MoveConstant(o)
TracForceZ(o)=DirZ(o)*MoveConstant(o)
Endfunction
 
Function Get_Drag_Force(o)
DragForceX(o)=-Drag(0)*VelX(o)*MoveSpeed(o)
DragForceY(o)=-Drag(0)*VelY(o)*MoveSpeed(o)
DragForceZ(o)=-Drag(0)*VelZ(o)*MoveSpeed(o)
Endfunction
 
Function Get_Force(o)
Force(o)=Sqrt(LongForceX(o)^2+LongForceY(o)^2+LongForceZ(o)^2)
Endfunction
 
Function Get_Speed(o)
MoveSpeed(o)=sqrt(VelX(o)^2 + VelY(o)^2 + VelZ(o)^2)
Endfunction
 
Function Get_Acceleration(o)
Acceleration(o)=Sqrt(AccX(o)^2+AccY(o)^2+AccZ(o)^2)
Endfunction
 
Function Set_Acceleration(o)
AccX(o)=LongForceX(o)/Mass(o)
AccY(o)=LongForceY(o)/Mass(o)
AccZ(o)=LongForceZ(o)/Mass(o)
Endfunction
 
Function Set_Velocity(o)
VelX(o)=VelX(o)+AccX(o) : VelX(o)=VelX(o)*TractionConstant(o)
VelY(o)=VelY(o)+AccY(o) : VelY(o)=VelY(o)*TractionConstant(o)
VelZ(o)=VelZ(o)+AccZ(o) : VelZ(o)=VelZ(o)*TractionConstant(o)
Endfunction
 
Function Get_Angular_Acceleration(o)
AngAccX(o)=AngForceX(o)/Mass(o)
AngAccY(o)=AngForceY(o)/Mass(o)
AngAccZ(o)=AngForceZ(o)/Mass(o)
Endfunction
 
Function Get_Angular_Velocity(o)
AngVelX(o)=AngVelX(o)+AngAccX(o) : AngVelX(o)=AngVelX(o)*AngularTractionConstant(o)
AngVelY(o)=AngVelY(o)+AngAccY(o) : AngVelY(o)=AngVelY(o)*AngularTractionConstant(o)
AngVelZ(o)=AngVelZ(o)+AngAccZ(o) : AngVelZ(o)=AngVelZ(o)*AngularTractionConstant(o)
Endfunction
 
Function Update_Coordinates_Straight(o)
PositionX(o)=PositionX(o)+(DirX(o)*Movespeed(o))
PositionY(o)=PositionY(o)+(DirY(o)*Movespeed(o))
PositionZ(o)=PositionZ(o)+(DirZ(o)*Movespeed(o))
Endfunction
 
Function Update_Coordinates_Slide(o)
PositionX(o)=PositionX(o)+VelX(o)
PositionY(o)=PositionY(o)+VelY(o)
PositionZ(o)=PositionZ(o)+VelZ(o)
Endfunction
 
Function Update_Angles(o)
AngleX(o)=Wrapvalue(AngleX(o)+AngVelX(o))
AngleY(o)=Wrapvalue(AngleY(o)+AngVelY(o))
AngleZ(o)=Wrapvalue(AngleZ(o)+AngVelZ(o))
Endfunction
 
Function Get_Lateral_Forces(o)
LatForce(o)=abs(AngVelY(o))*(MoveSpeed(o)/Mass(o))
If AngVelY(o)>0.0
   PushX(o)=(sin(Wrapvalue(AngleY(o)-90))*LatForce(o))
   PushZ(o)=(cos(Wrapvalue(AngleY(o)-90))*LatForce(o))
endif
If AngVelY(o)<0.0
   PushX(o)=(sin(Wrapvalue(AngleY(o)+90))*LatForce(o))
   PushZ(o)=(cos(Wrapvalue(AngleY(o)+90))*LatForce(o))
endif
Endfunction
 
Function Calculate_Offsets(o,sax#,say#,out#)
OffsetX(o)=(Sin(Wrapvalue(AngleY(o)+say#))*Cos(Wrapvalue(AngleX(o)+sax#)))*Out#
OffsetY(o)=-Sin(Wrapvalue(AngleX(o)+sax#))*out#
OffsetZ(o)=(Cos(Wrapvalue(AngleY(o)+say#))*Cos(Wrapvalue(AngleX(o)+sax#)))*out#
Endfunction
 
Function Calculate_Offsets_AB(a,b,sax#,say#,out#)
OffsetX(a)=(Sin(Wrapvalue(AngleY(b)+say#))*Cos(Wrapvalue(AngleX(b)+sax#)))*out#
OffsetY(a)=-Sin(Wrapvalue(AngleX(b)+sax#))*out#
OffsetZ(a)=(Cos(Wrapvalue(AngleY(b)+say#))*Cos(Wrapvalue(AngleX(b)+sax#)))*out#
Endfunction
 
Function Place_On_Matrix(o,m,h#)
PositionY(o)=Get ground height(m,positionX(o),PositionZ(o))+h#
Endfunction
 
Function Update_Object_Position(o)
Position Object o,PositionX(o),PositionY(o),PositionZ(o)
Endfunction
 
Function Update_Position_With_Push_Forces(o,a,b,c)
Position object o,Positionx(o)+(PushX(o)*a),Positiony(o)+(PushY(o)*b),Positionz(o)+(PushZ(o)*c)
Endfunction
 
Function Update_Position_With_Offsets(o,a,b,c)
Position Object o,Positionx(o)+(offsetx(o)*a),Positiony(o)+(offsety(o)*b),PositionZ(o)+(offsetZ(o)*c)
Endfunction
 
Function Fully_Update_object_Position(o)
Position Object o,PositionX(o)+PushX(o)+OffsetX(o),PositionY(o)+PushY(o)+OffsetY(o),PositionZ(o)+PushZ(o)+OffsetZ(o)
Endfunction
 
Function Update_object_Rotation(o)
Rotate object o,AngleX(o),AngleY(o),AngleZ(o)
Endfunction
 
Function Standard_Update(o)
Get_Old_Position(o)
Get_Object_Direction(o)
Get_Traction_Force(o)
Get_Drag_Force(o)
Get_Force(o)
Get_Speed(o)
Get_Acceleration(o)
Set_Acceleration(o)
Set_Velocity(o)
Get_Angular_Acceleration(o)
Get_Angular_Velocity(o)
Update_Coordinates_Straight(o)
Update_Angles(o)
Get_Lateral_Forces(o)
Fully_Update_Object_Position(o)
Update_Object_Rotation(o)
Endfunction
 
Function Update_Speed(o)
if MoveSpeed(o)<0.9 then MoveSpeed(o)=MoveSpeed(o)*0.0
Endfunction
 
Function Get_Movement_Time(o)
If MoveSpeed(o)<>0 then MoveTime(o)=Movetime(o)+1.0 else MoveTime(o)=0.0
Endfunction
 
Function Get_Movement_Distance(o)
MoveDist(o)=MoveSpeed(o)*MoveTime(o)
Endfunction
 
Function Get_Kinetic_Energy(o)
KineticEnergy(o)=(Mass(o)/2)*(Movespeed(o)^2)
Endfunction
 
Function Get_Work_Done(o)
WorkDone(o)=Force(o)*MoveDist(o)
Endfunction
 
Function Get_Excerted_Power(o)
If MoveTime(o)>0.0 then Power(o)=KineticEnergy(o)/MoveTime(o) else Power(o)=0.0
Endfunction
 
Function create_meter(var#,speedox,speedoy,speedow,speedl,col1,col2,m1$,m2$,m3$,m4$)
ink col1,0
circle speedox,speedoy,speedl
line speedox,speedoy,speedox+sin(wrapvalue(int(360-var#)+180))*(speedow/2),speedoy+cos(wrapvalue(int(360-var#)+180))*(speedow/2)
line speedox,speedoy,speedox-sin(wrapvalue(int(360-var#)+180))*(speedow/2),speedoy-cos(wrapvalue(int(360-var#)+180))*(speedow/2)
line speedox+sin(wrapvalue(int(360-var#)+180))*(speedow/2),speedoy+cos(wrapvalue(int(360-var#)+180))*(speedow/2),speedox+sin(wrapvalue(int(360-var#)+270))*speedl,speedoy+cos(wrapvalue(int(360-var#)+270))*speedl
line speedox-sin(wrapvalue(int(360-var#)+180))*(speedow/2),speedoy-cos(wrapvalue(int(360-var#)+180))*(speedow/2),speedox+sin(wrapvalue(int(360-var#)+270))*speedl,speedoy+cos(wrapvalue(int(360-var#)+270))*speedl
ink col2,0
center text speedox-(speedl*1.5),speedoy,m1$ : center text speedox,speedoy-(speedl*1.5),m2$
center text speedox+(speedl*1.5),speedoy,m3$ : center text speedox,speedoy+(speedl*1.5),m4$
endfunction