You can take a look at this if you like - I wrote it a while ago as a basic engine for a game I was working on. The waves are bigger than the ripples you are talking about, but it is possible to change the size/speed/source of the waves.
`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
`****************
`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*************
