Use sine and cosine commands that increment in random numbers, then smooth it with curveangle. Here's the function:
function get_drunk_angle(incr,angr#,smooth#)
s=wrapvalue(s+rnd(incr))
c=wrapvalue(c+rnd(incr))
s#=sin(s)*angr#
c#=cos(c)*angr#
result#=curveangle((s#+c#)/2,oldr#,smooth#)
oldr#=result#
endfunction result#
-incr sets the maximum frequency of the sine and cosine wave.
-angr# sets the maximum rotation value returned (if I don't want the car to rotate faster than 12, I set that to 12).
-smooth# sets the smooth value to smooth out the jagged mechanics of the calculations. A higher value is smoother, a low value is more jagged. I don't recommend a value lower than 8.
The function returns a value between 0 and the maximum angle you set (angr#), at the given frequency smoothed. So you have to add it to the cars current angle:
new_car_angle#=wrapvalue(current_car_angle#+drunk_angle#)
When switching from drunk to not drunk, made sure to set "drunk_angle#" to 0, or the car will jam and always rotate until you are drunk again.
And here is an example using it:
rem Drunken driver
rem by TheComet
rem setup screen
sync on
sync rate 60
backdrop on
color backdrop 0
hide mouse
rem make ground texture
create bitmap 1,8,8
ink rgb(0,255,0),0
box 0,0,7,7
ink rgb(0,100,0),0
box 2,2,6,6
get image 1,0,0,8,8
delete bitmap 1
rem make player
make object box 1,10,10,20
color object 1,rgb(0,0,255)
rem make world
make object plain 2,1000,1000
xrotate object 2,90
texture object 2,1
scale object texture 2,200,200
rem main loop
ink rgb(255,255,255),0
do
rem toggle between drunk and not drunk
center text 320,20,"Press <d> to toggle between drunk and not drunk"
if keystate(32)=1 and switch=0
switch=1
drunk=drunk+1-((drunk=2)*2)
drunkangle#=0.0
endif
if keystate(32)=0 then switch=0
rem use druck angle function to calculate drunken angle
if drunk=1 then drunkangle#=get_drunk_angle(10,12.0,20.0)
rem get input
speed#=curvevalue((upkey()-downkey())*2,speed#,30)
dangle#=curveangle((rightkey()-leftkey())*6,dangle#,10)
angle#=wrapvalue(angle#+dangle#+drunkangle#)
rem calculate players next positions
x#=newxvalue(x#,angle#,speed#)
z#=newzvalue(z#,angle#,speed#)
rem update player
position object 1,x#,5,z#
yrotate object 1,angle#
rem control camera
set camera to follow x#,5,z#,angle#,50,40,10,0
point camera x#,5,z#
rem refresh screen
sync
rem end of main loop
loop
rem end
end
function get_drunk_angle(incr,angr#,smooth#)
s=wrapvalue(s+rnd(incr))
c=wrapvalue(c+rnd(incr))
s#=sin(s)*angr#
c#=cos(c)*angr#
result#=curveangle((s#+c#)/2,oldr#,smooth#)
oldr#=result#
endfunction result#
And of course, have fun!
TheComet
Make the paths of your enemies easier with WaypointPro!