REM Project: CodeChallenges REM Created: 13/12/2005 19:35:48 REM REM ***** Main Source File ***** REM `RACE sync on : sync rate 80 `Create media cls rgb(0,150,0) for x = 1 to 200 ink rgb(0,150+rnd(150),0),0 dot 5 + rnd(90),5 + rnd(90) next x get image 1,0,0,100,100 `make basic object make object box 1,5,3,7 position object 1,2500,2,2500 `make wheels for w = 1 to 4 make object cylinder 1 + w,2 zrotate object 1 + w,90 : fix object pivot 1 + w scale object 1 + w,100,50,100 set object rotation ZYX 1 + w next w make matrix 1,5000,5000,50,50 prepare matrix texture 1,1,1,1 `define pi #constant pi = 3.141592654 `Make a car type type CarData ForceX# as float ForceY# as float EngineForce# as float Xspeed# as float Zspeed# as float Speed# as float MaxSpeed# as float Mass# as float Traction# as float SteeringAng# as float CarAngle# as float WheelDist# as float SlipVal# as float Regrip# as float Slip# as float endtype dim Car(5) as CarData `setup 1 car Car(1).EngineForce# = 0.4 Car(1).MaxSpeed# = 5.0 Car(1).Mass# = 100.0 Car(1).Traction# = 0.97 Car(1).WheelDist# = 6 Car(1).SlipVal# = 40.0 Car(1).Regrip# = 10.0 Car(1).Slip# = Car(1).SlipVal# do `gosub physics of car if upkey() = 1 then up = 1 else up = 0 if downkey() = 1 then down = 1 else down = 0 if leftkey() = 1 then left = 1 else left = 0 if rightkey() = 1 then right = 1 else right = 0 if spacekey() = 1 then brake = 1 else brake = 0 gosub CarPhysics gosub UpdateCar `let the camera chase the car ChaseCam(1) sync loop `Carphysics CarPhysics: `Controls on car if up = 1 Car(1).Xspeed# = newxvalue(Car(1).Xspeed#, Car(1).CarAngle#, Car(1).EngineForce#) Car(1).Zspeed# = newzvalue(Car(1).Zspeed#, Car(1).CarAngle#, Car(1).EngineForce#) endif if left = 1 if Car(1).SteeringAng# > -7.0 then dec Car(1).SteeringAng# endif if right = 1 if Car(1).SteeringAng# < 7.0 then inc Car(1).SteeringAng# endif if brake = 1 Car(1).Speed# = Car(1).Speed# * 0.5 endif `*** Calculate continuous physics *** `Steering angle correction. if Car(1).SteeringAng# > 0.0 then dec Car(1).SteeringAng#, 0.2 if Car(1).SteeringAng# < 0.0 then inc Car(1).SteeringAng#, 0.2 if Car(1).SteeringAng# < 0.25 and Car(1).SteeringAng# > -0.25 then Car(1).SteeringAng# = 0.0 `calculate speed Car(1).Speed# = sqrt( Car(1).Xspeed#^2 + Car(1).Zspeed#^2) `if lateral forces are too big, slip if abs(Car(1).ForceX#) < Car(1).Slip# Car(1).Slip# = Car(1).SlipVal# `Traction Car(1).Xspeed# = Car(1).Xspeed# * Car(1).Traction# Car(1).Zspeed# = Car(1).Zspeed# * Car(1).Traction# `If the car is below minimum speed, stop the car if Car(1).Speed# < 0.25 and Car(1).Speed# > -0.25 then Car(1).Speed# = 0.0 `if the car is above maximum speed, keep max speed if Car(1).Speed# > Car(1).MaxSpeed# then Car(1).Speed# = Car(1).MaxSpeed# if Car(1).Speed# < Car(1).MaxSpeed# * -0.5 then Car(1).Speed# = Car(1).MaxSpeed# * -0.5 `Adjust Car angle according to the current steering angle if Car(1).SteeringAng# <> 0.0 trad# = tan(wrapvalue(90 - (Car(1).SteeringAng#*0.4))) * (Car(1).WheelDist#*0.5) TurnValue# = (180 * Car(1).Speed# / (pi * trad#)) `Calculate Forces Car(1).ForceX# = sin(TurnValue#) * Car(1).Speed# * Car(1).Mass# `Turn car Car(1).CarAngle# = wrapvalue( Car(1).CarAngle# + TurnValue# ) else `reset force when the steering angle is 0 Car(1).ForceX# = 0.0 endif else Car(1).Slip# = Car(1).Regrip# Car(1).Xspeed# = Car(1).Xspeed# * 0.94 Car(1).Zspeed# = Car(1).Zspeed# * 0.94 Car(1).CarAngle# = curveangle(wrapvalue(Car(1).CarAngle# + (Car(1).SteeringAng#*5)), Car(1).CarAngle#, 15) Car(1).ForceX# = ((sin(Car(1).CarAngle#) * Car(1).Zspeed#) + (sin(wrapvalue(90-Car(1).CarAngle#)) * Car(1).Xspeed#))*Car(1).Mass# if abs(Car(1).Slip#) < Car(1).Slip# Car(1).Zspeed# = tan(Car(1).CarAngle#) * Car(1).speed# Car(1).Xspeed# = tan(wrapvalue(90 - Car(1).CarAngle#)) * Car(1).speed# endif endif ink rgb(255,255,255),0 text 5,5, "Lateral force: " + str$(Car(1).ForceX#) text 5,25,"Speed: " + str$(Car(1).Speed#) text 5,50,"Angle: " + str$(Car(1).CarAngle#) return UpdateCar: `get object's position posx# = object position x(1) posy# = object position y(1) posz# = object position z(1) Angy# = object angle y(1) `update positions if abs(Car(1).ForceX#) > Car(1).SlipVal# posx# = posx# + Car(1).Xspeed# posz# = posz# + Car(1).Zspeed# else posx# = newxvalue(posx#, Car(1).CarAngle#, Car(1).Speed#) posz# = newzvalue(posz#, Car(1).CarAngle#, Car(1).Speed#) endif `update object position object 1, posx#, posy#, posz# rotate object 1, 0, Car(1).CarAngle#, 0 `position wheels WheelPivotFrontX# = newxvalue(posx#, Angy#, Car(1).WheelDist#*0.5) WheelPivotFrontZ# = newzvalue(posz#, Angy#, Car(1).WheelDist#*0.5) WheelPivotBackX# = newxvalue(posx#, Angy#, -Car(1).WheelDist#*0.5) WheelPivotBackZ# = newzvalue(posz#, Angy#, -Car(1).WheelDist#*0.5) `left front wheel position object 2, newxvalue(WheelPivotFrontX#, wrapvalue(Angy#-90),3),1,newzvalue(WheelPivotFrontZ#, wrapvalue(Angy#-90),3) rotate object 2,0,Angy# + (Car(1).SteeringAng#*3),0 `right front wheel position object 3, newxvalue(WheelPivotFrontX#, wrapvalue(Angy#+90),3),1,newzvalue(WheelPivotFrontZ#, wrapvalue(Angy#+90),3) rotate object 3,0,Angy# + (Car(1).SteeringAng#*3),0 `left back wheel position object 4, newxvalue(WheelPivotBackX#, wrapvalue(Angy#-90),3),1,newzvalue(WheelPivotBackZ#, wrapvalue(Angy#-90),3) rotate object 4,0,Angy#,0 `right back wheel position object 5, newxvalue(WheelPivotBackX#, wrapvalue(Angy#+90),3),1,newzvalue(WheelPivotBackZ#, wrapvalue(Angy#+90),3) rotate object 5,0,Angy#,0 return `**************** `Function `**************** function ChaseCam(id) posx# = object position x(id) posy# = object position y(id) posz# = object position z(id) angy# = wrapvalue(object angle y(id) - 180) d# = 20.0 h# = 15.0 camx# = newxvalue(posx#, angy#, d#) camz# = newzvalue(posz#, angy#, d#) camy# = posy# + h# camx# = curvevalue(camx#, camera position x(), 7.5) camy# = curvevalue(camy#, camera position y(), 7.5) camz# = curvevalue(camz#, camera position z(), 7.5) position camera camx#,camy#,camz# point camera posx#, posy# + (h#/2), posz# endfunction