I was bored, so I thought I'd write a basic jetski physics engine. Just add a track, some opponent AI and some girls in bikinis, and you've got a wave-race type game.
Basically, the engine allows you to simulate any boat-like object which moves (reasonably realistically, hopefully) according to both user input and the wave motion.
You can adjust variables like power, amount of 'skid' through the water, wave properties, camera properties etc. in the code. It also incorporates a smooth chasecam, and a simple (but effective) mouse control steering system.
Use the up and down arrow keys to control the speed and the mouse to steer.
Have fun.
`Jetski physics engine by Ric.
sync on
sync rate 70
hide mouse
`set mouse position to centre
position mouse 0.5*screen width(),0
`***camera properties***
autocam off
set camera range 1,10000
camdist#=20 `cam distance
camheight#=8 `cam height
smoothness=50 `chasecam smoothness
fog on
fog distance 150
fog color rgb(100,100,120)
`*********************
`***wave properties***
`size of wave area
rows=50
columns=50
`wavegenerator1 x,z coordinates:
a=15
b=10
`wavegenerator2 x,z coordinates:
c=35
d=40
`wave characteristics
elasticity#=0.002 `determines wave speed
damping#=0.995 `determines the decay of the wave height
amplitude#=20 `the wave height at the generator points
frequency#=1 `how quickly the generator points move up and down
current#=0.02 `how much the wave slope affects the jetski
`******************
`***jetski motion properties***
friction#=0.99 `1=no friction - slides all over the place
`0=big friction - like moving through concrete
power#=0.01 `controls the acceleration of the jetski
`***note***
`ideally, the friction should get bigger as the speed of
`the jetski increases, thus establishing a maximum speed
`....haven't coded that bit yet though.
`**********
`******************set up wave matrix********************
`********************************************************
dim tile(rows+1,columns+1)
dim v#(rows,columns)
make matrix 1,rows*10,columns*10,rows,columns
`make matrix 2,rows*10,columns*10,rows,columns
`give every tile of the matrix a coordinate - tile(x,z)
for x=1 to rows
for z=1 to columns
tile(x,z)=tile
tile=tile+1
next z
next x
`fix the wave generator points
dim fixed(rows*columns)
fixed(tile(a,b))=1
fixed(tile(c,d))=1
`***apply texture to wave***
`load image "watertexture.jpg",1
create bitmap 1,10,10
ink rgb(255,255,255),0
box 0,0,10,10
ink rgb(0,0,180),0
box 0,0,9,9
get image 1,0,0,10,10,1
prepare matrix texture 1,1,1,1
ghost matrix on 1
`tile=1
`for x=rows-1 to 0 step -1
`for z=0 to columns-1
`set matrix tile 1,z,x,tile
`inc tile
`next z
`next x
`***************************
`******************************************************
`******************************************************
`*******************make objects**********************
`make simple skysphere
make object sphere 2000,-10000
ink rgb(150,150,250),0
box 0,0,10,10
get image 3,0,0,10,10
texture object 2000,3
set object fog 2000,0
`***load track***
`load object "track.x",1000
`scale object 1000,100,40,100
`set object collision to polygons 1000
`position object 1000,250,0,250
`****************
`Make a simple jetski - object number 1
make object cube 1,0.1
make object box 2,2,1,4
make mesh from object 1,2
delete object 2
make object cone 3,2
scale object 3,100,200,100
xrotate object 3,90
make mesh from object 2,3
delete object 3
make object sphere 4,2
make mesh from object 3,4
delete object 4
add limb 1,1,1
add limb 1,2,2
offset limb 1,2,0,0,2
add limb 1,3,3
ink rgb(255,0,0),0
box 0,0,10,10
get image 2,0,0,10,10
set current bitmap 0
texture object 1,2
ink rgb(255,255,255),0
`*****************************************************
`*******initial positions and speeds *********
number=50 `number of floating boxes
dim x#(number)
dim y#(number)
dim z#(number)
dim frontspeed#(number)
dim sidespeed#(number)
x#(1)=rnd(250) `initial x position of jetski
z#(1)=rnd(250) `initial z position of jetski
for object=2 to number
make object cube object,5
x#(object)=rnd(500) `initial x position of boxes
z#(object)=rnd(500) `initial z position of boxes
next object
`**********************************
`************MAIN PROGRAM LOOP***************
do
gosub wave
gosub control
gosub get_wave_slope
gosub chasecam
text 0,0,str$(screen fps())
sync
loop
`************subroutines***************
wave:
`****move the generator points up and down****
y#=amplitude#*sin(theta#)
theta#=theta#+frequency#
if fixed(tile(a,b))=1
set matrix height 1,a,b,y#
endif
if fixed(tile(c,d))=1
set matrix height 1,c,d,y#
endif
`********************************************
`****make wave propogate through matrix******
for x=1+1 to rows-1
for z=1+1 to columns-1
`check x+1 height
if x<rows
distxp1#=get matrix height(1,x+1,z)-get matrix height (1,x,z)
endif
`check x-1 height
if x>1
distxm1#=get matrix height(1,x-1,z)-get matrix height (1,x,z)
endif
`check z+1 height
if z<columns
distzp1#=get matrix height(1,x,z+1)-get matrix height (1,x,z)
endif
`check z-1 height
if z>1
distzm1#=get matrix height(1,x,z-1)-get matrix height (1,x,z)
endif
`calculate vector some of heights adjacent to tile
`and make this proportional to the tile's acceleration
vectorsum#=distxp1#+distxm1#+distzp1#+distzm1#
a#=vectorsum#*elasticity#
`increase tile's velocity by it's acceleration amount
v#(tile(x,z))=v#(tile(x,z))+a#
if fixed(tile(x,z))=0
`reposition tile
set matrix height 1,x,z,get matrix height(1,x,z)+v#(tile(x,z))
v#(tile(x,z))=v#(tile(x,z))*damping#
endif
next z
next x
update matrix 1
`****************************************************
return
get_wave_slope:
for object=1 to number
y#(object)=get ground height(1,x#(object),z#(object))
yfront#=get ground height(1,newxvalue(x#(object),angle#,1),newzvalue(z#(object),angle#,1))
yside#=get ground height(1,newxvalue(x#(object),angle#+90,1),newzvalue(z#(object),angle#+90,1))
frontspeed#(object)=frontspeed#(object)+(y#(object)-yfront#)*current#
sidespeed#(object)=sidespeed#(object)+(y#(object)-yside#)*current#
x#(object)=newxvalue(x#(object),angle#,frontspeed#(object))
z#(object)=newzvalue(z#(object),angle#,frontspeed#(object))
x#(object)=newxvalue(x#(object),angle#+90,sidespeed#(object))
z#(object)=newzvalue(z#(object),angle#+90,sidespeed#(object))
position object object,x#(object),y#(object),z#(object)
next object
return
control:
`***steering****
if mousex()>0.5*screen width() then polarity=1
if mousex()<0.5*screen width() then polarity=-1
`the square function is so that the steering is less sensitive
`in the middle and more sensitive for extreme turns
`note: squaring makes the mouse position always positive,
`hence the need for a polarity.
turn#=(((mousex()-(0.5*screen width()))^2)/10000)*polarity
if turn#>1 then turn#=1
if turn#<-1 then turn#=-1
yrotate object 1,object angle y(1)+turn#
direction#=wrapvalue(direction#+turn#)
rotate limb 1,1,0,0,-turn#*20 `roll the jetski body according to turn amount
`***************
`*****speed*****
if upkey()=1 then frontspeed#(1)=frontspeed#(1)+(power#*cos(direction#)):sidespeed#(1)=sidespeed#(1)+(power#*sin(direction#))
if downkey()=1 then frontspeed#(1)=frontspeed#(1)-(power#*cos(direction#)):sidespeed#(1)=sidespeed#(1)-(power#*sin(direction#))
for object=1 to number
frontspeed#(object)=frontspeed#(object)*friction#
sidespeed#(object)=sidespeed#(object)*friction#
next object
`***************
return
chasecam:
yrotate camera curveangle(direction#,camera angle y(),smoothness)
position camera object position x(1),object position y(1)+camheight#,object position z(1)
move camera -camdist#
point camera object position x(1),object position y(1)+camheight#,object position z(1)
return
`********have a nice day*************