Here's a punk model riding a snow board, sliding down hills. There's also a neat effect of a fading trail that follows behind the board. Study the code all you want, just make sure you understand it before trying to use it.
`Coded by Phaelax (phaelax@hotmail.com)
autocam off
hide mouse
sync on
backdrop on
color backdrop 0
REM VARIABLES
grav#=1.5
`total_amount=150
`dim plive(total_amount)
`dim px#(total_amount)
`dim py#(total_amount)
`dim pz#(total_amount)
REM LOAD IMAGES
load image "snow2.jpg", 1
load image "snow.bmp", 2
load image "tree.bmp", 3
REM SETUP MATRIX
make matrix 1,1000,1000,50,100
prepare matrix texture 1,1,1,1
for z=0 to 99
for x=0 to 49
height#=50.0-(sin((x*12))*50)
height#=height#+(50.0-(sin((z*12))*50))
height#=height#/2.0
set matrix height 1,x,z,height#
next x
next z
update matrix 1
rem Use matrix normals to make it smooth
for z=1 to 99
for x=1 to 49
rem Get matrix heights
h8#=get matrix height(1,x,z-1)
h4#=get matrix height(1,x-1,z)
h#=get matrix height(1,x,z)
h2#=get matrix height(1,x,z)
rem Calculate projected angle X using heights
x1#=(x-1)*25.0 : y1#=h#
x2#=(x+0)*25.0 : y2#=h4#
dx#=x2#-x1#
dy#=y2#-y1#
ax#=atanfull(dx#,dy#)
ax#=wrapvalue(90-ax#)
rem Calculate projected angle Z using heights
z1#=(z-1)*25.0 : y1#=h2#
z2#=(z+0)*25.0 : y2#=h8#
dz#=z2#-z1#
dy#=y2#-y1#
az#=atanfull(dz#,dy#)
az#=wrapvalue(90-az#)
rem Make normal from projected angle
nx#=sin(ax#)
ny#=cos(ax#)
nz#=sin(az#)
rem Setting matrix normal for smoothness
set matrix normal 1,x,z,nx#,ny#,nz#
next x
next z
update matrix 1
set ambient light 5
set point light 0, 200,200,200
REM MAKE AND SETUP OBJECTS
`board
make object cube 1,1
scale object 1, 500,100,1500
color object 1, 120
`temp spheres
make object sphere 2, 2
color object 2, rgb(0,200,0)
make object sphere 3,2
color object 3, rgb(0,200,0)
make object sphere 4,2
color object 4, rgb(200,0,0)
make object sphere 5, 2
color object 5, rgb(200,0,0)
`dummy object
make object cone 6, 5
hide limb 6,0
make object cone 8, 5
hide limb 8,0
`make object cube 9,15
`scale object 9,100,20,100
`character
load object "l-punk-static.x", 7
`load object "m-raptor-static.x", 7
yrotate object 7, 270
fix object pivot 7
scale object 7, 1500,1500,1500
`hide object 9
glue object to limb 1,6,0
glue object to limb 7,8,0
px=0
pz=0
for obj=0 to 100 step 5
p1x=-5
p1y=0
p1z=5
p2x=5
p2y=0
p2z=50
make object triangle 10+obj,px,0,pz,px,5,pz,opx,5,opz
make object triangle 11+obj,opx,0,opz,opx,5,opz,px,0,pz
next obj
obj=0
spd#=1
rem fog
fog on
fog color rgb(20,20,20)
fog distance 1200
speed#=18
REM ======================== MAIN LOOP ========================
DO
rem Control player with arrow keys
`if ground=1
if upkey()=1 or joystick up()=1 then x#=newxvalue(x#,a#,speed#) : z#=newzvalue(z#,a#,speed#)
if leftkey()=1 or joystick left()=1 then a#=wrapvalue(a#-5.0)
if rightkey()=1 or joystick right()=1 then a#=wrapvalue(a#+5.0)
`endif
`endif
rem configure smooth moving
dx#=curvevalue(x#,dx#, 15.0)
dz#=curvevalue(z#,dz#, 15.0)
da#=curveangle(a#, da#, 10.0)
`if ground=0 then y#=y#-grav#
`dec y#, 4
`y#=get ground height(1,dx#,dz#)+1.0
`if y# < get ground height(1,dx#,dz#)+1.0
` y#=get ground height(1,dx#,dz#)+1.0
` ground=1
`else
` ground=0
`endif
dec y#, grav#
if y# < get ground height(1,dx#,dz#)
y#=get ground height(1,dx#,dz#)
ground=1
else
ground=0
endif
rem Position camera to the back of the character
cx#=newxvalue(x#,wrapvalue(a#+180),100)
cz#=newzvalue(z#,wrapvalue(a#+180),100)
cy#=get ground height(1,cx#,cz#)+50.0
position camera dx#,y#+100,dz#-100
rem Point camera at object
point camera dx#,y#+5,dz#
position light 0, dx#, y#+100, dz#-100
if ground=1
rem find the ground height at each corner of the snowboard
temp_angle#=curveangle(a#, da#-20, 10.0)
front_left_x#=newxvalue(dx#,wrapvalue(temp_angle#),7.5)
front_left_z#=newzvalue(dz#,wrapvalue(temp_angle#),7.5)
front_left_height#=get ground height(1,front_left_x#,front_left_z#)
temp_angle#=curveangle(a#, da#+20, 10.0)
front_right_x#=newxvalue(dx#,wrapvalue(temp_angle#),7.5)
front_right_z#=newzvalue(dz#,wrapvalue(temp_angle#),7.5)
front_right_height#=get ground height(1,front_right_x#,front_right_z#)
temp_angle#=curveangle(a#, da#+20, 10.0)+180
rear_left_x#=newxvalue(dx#,wrapvalue(temp_angle#),7.5)
rear_left_z#=newzvalue(dz#,wrapvalue(temp_angle#),7.5)
rear_left_height#=get ground height(1,rear_left_x#,rear_left_z#)
temp_angle#=curveangle(a#, da#-20, 10.0)+180
rear_right_x#=newxvalue(dx#,wrapvalue(temp_angle#),7.5)
rear_right_z#=newzvalue(dz#,wrapvalue(temp_angle#),7.5)
rear_right_height#=get ground height(1,rear_right_x#,rear_right_z#)
rem calculate the amount to angle-tilt snowboard
length#=((rear_left_height#-front_left_height#)+(rear_right_height#-front_right_height#))/0.6
width#=((front_right_height#-front_left_height#)+(rear_right_height#-rear_left_height#))/0.2
endif
`if front_right_height# > rear_right_height# then z#=newzvalue(z#,a#,-1.0)
`if front_right_height# < rear_right_height# then z#=newzvalue(z#,a#,1.0)
rem update object
`position object 9,dx#,y#,dz#
position object 6,dx#,y#,dz#
yrotate object 6,da#
position object 8,dx#,y#,dz#
yrotate object 8,da#
rotate object 1,wrapvalue(length#),0,wrapvalue(width#)
rotate object 7,wrapvalue(length#),0,wrapvalue(width#)
if dx#>1000 or dx#<0 or dz#>1000 or dz#<0
dx#=500:dz#=500
x#=500:z#=500
endif
rem control sliding due to angle of slope
opx#=dx#
opz#=dz#
tx#=opx#+7.5
tz#=opz#+7.5
tx2#=opx#-7.5
tz2#=opz#-7.5
opy1#=get ground height(1,tx#,opz#)
opy2#=get ground height(1,tx2#,opz#)
opy3#=get ground height(1,opx#,tz#)
opy4#=get ground height(1,opx#,tz2#)
`sx#=abs(opy1#-opy2#)*0.286
`sz#=abs(opy3#-opy4#)*0.286
sx#=abs(opy1#-opy2#)*0.4
sz#=abs(opy3#-opy4#)*0.4
if opy1#>opy2# then dec x#, sx#
if opy1#<opy2# then inc x#, sx#
if opy3#>opy4# then dec z#, sz#
if opy3#<opy4# then inc z#, sz#
rem misc text
set cursor 0,0
print object position x(6)
print object position y(6)
print object position z(6)
set cursor 1,70
print str$(width#)
set cursor 1,80
print str$(length#)
gosub updatetrails
sync
LOOP
updatetrails:
delete object 10+obj
delete object 11+obj
p1x#=object position x(6)-2.5+sin(rnd(360))*0.25
p1y#=y#
p1z#=object position z(6)+sin(rnd(360))*0.25
p2x#=object position x(6)+2.5+sin(rnd(360))*0.25
p2y#=y#
p2z#=object position z(6)+sin(rnd(360))*0.25
make object triangle 10+obj,p1x#,p1y#,p1z#,p2x#,p2y#,p2z#,op2x#,op2y#,op2z#
make object triangle 11+obj,op1x#,op1y#,op1z#,op2x#,op2y#,op2z#,p1x#,p1y#,p1z#
color object 10+obj,rgb(0,255,255)
color object 11+obj,rgb(0,255,255)
set object 10+obj,1,1,0
set object 11+obj,1,1,0
ghost object on 10+obj
ghost object on 11+obj
`Fade the trails
fade=0
for n=obj+10 to 100 step 5
color object 10+n,rgb((spd#/10.00)*fade,0,fade)
color object 11+n,rgb((spd#/10.00)*fade,0,fade)
inc fade,10 : if fade>255 then fade=255
next n
for n=0 to obj step 5
color object 10+n,rgb((spd#/10.00)*fade,0,fade)
color object 11+n,rgb((spd#/10.00)*fade,0,fade)
inc fade,10 : if fade>255 then fade=255
next n
inc obj,5
if obj>100 then obj=0
`Record last emitter positions
op1x#=p1x#
op1y#=p1y#
op1z#=p1z#
op2x#=p2x#
op2y#=p2y#
op2z#=p2z#
return