`Racing Challenge by Ric detail=40 `display settings if check display mode(1024,768,32)=1 then set display mode 1024,768,32 sync on sync rate 50 hide mouse autocam off hide light 0 color backdrop 0 set ambient light 0 make light 1 set light range 1,3 `set initial value for image numbers global image_seed image_seed=1000000 create bitmap 1,screen width(),screen height() position light 1,0,0,-1 set light range 1,2 make object sphere 1,1,100,100 set object specular power 1,20 set object specular 1,rgb(255,255,255) position camera 0,0,-2 sync sun=free_image() get image sun,screen width()/4,screen height()/4,screen width()*.75,screen height()*.75,1 set object light 1,0 sync flare1=free_image() get image flare1,screen width()/4,screen height()/4,screen width()*.75,screen height()*.75,1 delete object 1 delete bitmap 1 text 0,0,"Please wait ......" sync `camera and light settings set camera range 0.01,10000 position camera 64,0,64 color backdrop 0 set ambient light 20 `set size of terrain global matrixsize matrixsize=128 `fog settings fog on fog color rgb(200,200,200) fog distance matrixsize `set initial value for object numbers global object_seed object_seed=1000000 `position light for world illumination position light 1,200,30,200 set light range 1,100000 make object cube 2000,1 hide object 2000 position object 2000,light position x(1),light position y(1),light position z(1) global skyimage create_sky() global height# global rows global columns global terrainimage `set size of terrain rows=detail columns=detail global peaksoff global peaksoff2 global dim peakx(100) global dim peakz(100) global dim peakh(100) global dim peakx2(100) global dim peakz2(100) global dim peakh2(100) terraform() create_trench() Matrix_to_Object(1000,1,128,128,rows,rows,rows,rows,rows,rows) ink rgb(255,255,255),0 gosub calculate_shadows delete object 1000 set current bitmap 0 global sphere1 global sphere2 global sphere3 create_skysphere() sunplane=free_object() make object plain sunplane,160*4/3.0,160 set object fog sunplane,0 texture object sunplane,sun set object light sunplane,0 ghost object on sunplane,2 set object transparency sunplane,2 flareplane1=free_object() make object plain flareplane1,0.3*4/3.0,0.3 texture object flareplane1,flare1 set object light flareplane1,0 set alpha mapping on flareplane1,20 position object flareplane1,0,-0.5,0 `reference object for distant light source dummy=free_object() make object cube dummy,1 hide object dummy point object dummy,light position x(1),light position y(1),light position z(1) move object dummy,10000 position camera 64,height#+2+get ground height(1,64,64),64 `boaty and watery stuff `set mouse position to centre position mouse 0.5*screen width(),0 camdist#=4 `cam distance camheight#=2 `cam height smoothness=50 `chasecam smoothness `wavegenerator1 x,z coordinates: a=15 b=10 `wavegenerator2 x,z coordinates: c=35 d=40 `wave characteristics elasticity#=0.001 `determines wave speed damping#=0.992 `determines the decay of the wave height amplitude#=2.5 `the wave height at the generator points frequency#=2.0 `how quickly the generator points move up and down current#=0.01 `how much the wave slope affects the jetski `****************** `***jetski motion properties*** friction#=0.975 `1=no friction - slides all over the place `0=big friction - like moving through concrete power#=0.007 `controls the acceleration of the jetski dim tile(rows+10,columns+10) dim v#(rows*2,columns*2) make matrix 2,rows*4,columns*4,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*2) fixed(tile(a,b))=1 fixed(tile(c,d))=1 create bitmap 1,10,10 ink rgb(0,0,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 2,1,1,1 ghost matrix on 2,3 `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(250,0,50),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 scale object 1,20,20,20 `***************************************************** `*******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)=64 `initial x position of jetski z#(1)=96 `initial z position of jetski for object=2 to number make object cube object,5 hide object object x#(object)=rnd(500) `initial x position of boxes z#(object)=rnd(500) `initial z position of boxes next object `********************************** `main program loop do position object sunplane,camera position x(),camera position y(),camera position z() point object sunplane,object position x(dummy),object position y(dummy),object position z(dummy) move object sunplane,128*7 point object sunplane,camera position x(),camera position y(),camera position z() gosub wave gosub control gosub get_wave_slope gosub chasecam text 0,0,str$(screen fps()) sync loop `**************************************** `functions function terraform `create terrain make matrix 1,matrixsize,matrixsize,columns,rows set matrix 1,0,0,0,2,1,1,0 for peak=1 to 50 peakh(peak)=rnd(5)+5 peakx(peak)=rnd(rows-8)+4 peakz(peak)=rnd(rows-8)+4 set matrix height 1,peakx(peak),peakz(peak),peakh(peak) next peak update matrix 1 for times=1 to 120 if times>=90 then peaksoff=1 smooth_matrix(1,rows,rows) next times peaksoff=0 endfunction function create_trench() data$="663663222222222222121477441114788888889698744444478998888963336666" x=20 z=30 length=len(data$) for n=1 to length check$=right$(left$(data$,n),1) if check$="1" then dec x:dec z if check$="2" then dec z if check$="3" then inc x:dec z if check$="4" then dec x if check$="6" then inc x if check$="7" then inc z:dec x if check$="8" then inc z if check$="9" then inc z:inc x for u=-1 to 1 for v=-1 to 1 set matrix height 1,x+u,z+v,-2 next v next u next n `fill with water water=free_object() make object plain water,4000,4000 xrotate object water,-90 ghost object on water,3 set object fog water,0 position object water,0,-1.8,0 color object water,rgb(0,0,255) water2=free_object() make object plain water2,4000,4000 xrotate object water2,-90 `ghost object on water2,3 set object fog water2,0 position object water2,0,-2.85,0 color object water2,rgb(0,0,255) endfunction function smooth_matrix(matnum,tilex,tilez) for x=2 to tilex-2 for z=2 to tilez-2 b=-get matrix height(matnum,x,z)+get matrix height(matnum,x,z+1) d=-get matrix height(matnum,x,z)+get matrix height(matnum,x+1,z) f=-get matrix height(matnum,x,z)+get matrix height(matnum,x,z-1) h=-get matrix height(matnum,x,z)+get matrix height(matnum,x-1,z) total=b+d+f+h set matrix height matnum,x,z,get matrix height(matnum,x,z)+total*0.1 next z next x for peak=1 to 100 `peakh(peak)=peakh(peak)*0.999 if matnum=1 if peaksoff=0 then set matrix height 1,peakx(peak),peakz(peak),peakh(peak) endif if matnum=2 if peaksoff=0 then set matrix height 2,peakx2(peak),peakz2(peak),peakh2(peak) endif next peak update matrix matnum endfunction function free_object object=object_seed repeat inc object until object exist(object)=0 endfunction object function check_free_object_number object=object_seed repeat inc object until object exist(object)=0 endfunction object function free_image image=image_seed repeat inc image until image exist(image)=0 endfunction image function create_skysphere `get image for sphere by taking snapshot of terrain terrainimage=free_image() set camera fov 90 fog off position camera matrixsize/2.0,3,-matrixsize*0.3 sync get image terrainimage,0,0,screen width(),screen height() fog on fog color rgb(200,200,200) fog distance matrixsize set camera fov 60 sphere2=free_object() make object sphere sphere2,matrixsize*10 set object collision off sphere2 xrotate object sphere2,180 `yrotate object sphere2,30 set object cull sphere2,0 texture object sphere2,terrainimage set object texture sphere2,2,0 scale object texture sphere2,8,2.6 set object fog sphere2,0 set object transparency sphere2,2 ghost object on sphere2,5 set alpha mapping on sphere2,20 set object emissive sphere2,rgb(80,60,100) `set object specular power sphere2,100 `fade object sphere2,200 `set object light sphere2,0 position object sphere2,matrixsize/2,-135,matrixsize/2 `sphere 3 (sky) - a third, outer sphere for the sky sphere3=free_object() make object sphere sphere3,matrixsize*20 set object collision off sphere3 set object cull sphere3,0 texture object sphere3,skyimage scale object texture sphere3,1,1.8 set object light sphere3,0 set object fog sphere3,0 position object sphere3,matrixsize/2,0,matrixsize/2 endfunction function create_sky() `creates a dark to light bluish gradient cls for n=0 to 250 ink rgb(n,n-20,n-40),0 line 0,n,250,n next n skyimage=free_image() get image skyimage,0,0,250,250 endfunction function move_camera control camera using arrowkeys 0,0.2,3 position camera camera position x(),height#+.2+get ground height(1,camera position x(),camera position z()),camera position z() if inkey$()="a" then inc height#,1 if inkey$()="z" then dec height#,1 endfunction calculate_shadows: undim pixelshaded1(128,128) undim pixelshaded2(128,128) dim pixelshaded1(128,128) dim pixelshaded2(128,128) `if light1>0 create bitmap 1,128,128 set current bitmap 1 ink rgb(20,155,0),0 box 0,0,128,128 for n=0 to 5000 tone=rnd(100)+150 ink rgb(tone/10,tone+15,tone/15),0 dot rnd(128),rnd(128) next n ink rgb(10,10,10),0 for y=0 to 128 for x=0 to 128 `shadows cast by terrain - matrix converted to object 1000 ray2#=intersect object(1000,x,get ground height(1,x,y)+0.1,y,light position x(1),light position y(1),light position z(1)) if ray2#=0 then ray2#=1000 if ray2#<0 then ray2#=1 if ray2#<=100 tone=40+ray2#*8 `if pixelshaded2(x,y)=1 or pixelshaded1(x,y)=1 then tone=tone/1.5 if tone>155 then tone=155 ink rgb(20,tone,0),0 dot x,128-y `pixelshaded1(x,y)=1 endif next x next y blur bitmap 1,3 shadowmap=5000000 get image shadowmap,0,0,128,128 delete bitmap 1 `set light mapping on 2,shadowmap `(light1 exist) `texture matrix prepare matrix texture 1,shadowmap,rows,columns 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 `endif update matrix 1 return function Matrix_to_Object( object, matrixnum, matxsize#, matzsize#, matxsegs, matzsegs, tilex, tilez, limbx, limbz ) `safety in case limbx and limbz is smaller than the texture x and z a = 0 if limbx < tilex then limbx = tilex : a = 1 if limbz < tilez then limbz = tilez : a = 1 if a > 0 sync print "limbx or limbz was less than tilex or tilez : Error corrected" print "Press any key to continue." sync wait key endif `safety in case matxsegs and matzsegs is not evenly divisible by tilex and tilez if matxsegs mod tilex > 0 EXIT PROMPT "Number of matrix xsegs not evenly divisible by tilex", "Texture tilex error" end endif if matzsegs mod tilez > 0 EXIT PROMPT "Number of matrix zsegs not evenly divisible by tilez", "Texture tilez error" end endif `safety in case matxsegs and matzsegs is not evenly divisible by tilex and tilez if matxsegs mod limbx > 0 EXIT PROMPT "Number of matrix xsegs not evenly divisible by limbx", "Texture tilex error" end endif if matzsegs mod limbz > 0 EXIT PROMPT "Number of matrix zsegs not evenly divisible by limbz", "Texture tilez error" end endif `calc the number of polys in the matrix num_mat_polys = (matxsegs*matzsegs)*2 `make array to store vert info `storage indexs = poly number, vert number, x/y/z vert pos/norm/uv `polys are numbered starting from left to right, front to `back, one row at a time (with 2 polys per tile) dim vert_store#(num_mat_polys,2,7) `calc the width and depth of each tile on the matrix `formula size#/number mat_x_wide# = matxsize#/matxsegs mat_z_deep# = matzsize#/matzsegs `****************************************************************************** `get vert position data `placeholder variable for poly numbers a = 1 `one row at a time (front to back) for j = 0 to matzsegs - 1 `one tile at a time (left to right) for i = 0 to matxsegs - 1 `tile top left poly info `bottom left vert (x,y,z) vert_store#(a,0,0) = i*mat_x_wide# vert_store#(a,0,1) = GET MATRIX HEIGHT(matrixnum, i, j) vert_store#(a,0,2) = j*mat_z_deep# `top left vert (x,y,z) vert_store#(a,1,0) = i*mat_x_wide# vert_store#(a,1,1) = GET MATRIX HEIGHT(matrixnum, i, j+1) vert_store#(a,1,2) = (j+1)*mat_z_deep# `top right vert (x,y,z) vert_store#(a,2,0) = (i+1)*mat_x_wide# vert_store#(a,2,1) = GET MATRIX HEIGHT(matrixnum, i+1, j+1) vert_store#(a,2,2) = (j+1)*mat_z_deep# inc a, 1 `tile bottom right poly info `bottom left vert (x,y,z) vert_store#(a,0,0) = i*mat_x_wide# vert_store#(a,0,1) = GET MATRIX HEIGHT(matrixnum, i, j) vert_store#(a,0,2) = j*mat_z_deep# `top right vert (x,y,z) vert_store#(a,1,0) = (i+1)*mat_x_wide# vert_store#(a,1,1) = GET MATRIX HEIGHT(matrixnum, i+1, j+1) vert_store#(a,1,2) = (j+1)*mat_z_deep# `bottom right vert (x,y,z) vert_store#(a,2,0) = (i+1)*mat_x_wide# vert_store#(a,2,1) = GET MATRIX HEIGHT(matrixnum, i+1, j) vert_store#(a,2,2) = j*mat_z_deep# inc a, 1 next i next j `****************************************************************************** `****************************************************************************** `calc normals for polys `Thanks to ADR for posting this code on the DBP forums :) for i = 1 to num_mat_polys `acuire vert positions P1X# = vert_store#(i,0,0) P1Y# = vert_store#(i,0,1) P1Z# = vert_store#(i,0,2) P2X# = vert_store#(i,1,0) P2Y# = vert_store#(i,1,1) P2Z# = vert_store#(i,1,2) P3X# = vert_store#(i,2,0) P3Y# = vert_store#(i,2,1) P3Z# = vert_store#(i,2,2) null = make vector3(1) null = make vector3(2) null = make vector3(3) ` -- calculate the two directional vectors for the adj and opp edges... set vector3 1, P1X#, P1Y#, P1Z# set vector3 2, P2X#, P2Y#, P2Z# set vector3 3, P3X#, P3Y#, P3Z# subtract vector3 2, 2, 1 subtract vector3 3, 3, 1 ` -- vector 3 and 1 are now directional vectors normalize vector3 2,2 ` -- normalize em normalize vector3 3,3 cross product vector3 1, 2,3 ` -- use the origin vector (1) to store the face normal normalize vector3 1,1 `save normals (all 3 verts have same normals) vert_store#(i,0,3) = x vector3(1) vert_store#(i,0,4) = y vector3(1) vert_store#(i,0,5) = z vector3(1) vert_store#(i,1,3) = vert_store#(i,0,3) vert_store#(i,1,4) = vert_store#(i,0,4) vert_store#(i,1,5) = vert_store#(i,0,5) vert_store#(i,2,3) = vert_store#(i,0,3) vert_store#(i,2,4) = vert_store#(i,0,4) vert_store#(i,2,5) = vert_store#(i,0,5) null = delete vector3(1) null = delete vector3(2) null = delete vector3(3) next i `****************************************************************************** `****************************************************************************** `calc UV data for polys `save current x tile number xtiles = 1 `save current z tile number ztiles = 1 `calc how much to step each u data per tile stepu# = (1.0/tilex) `calc how much to step each v data per tile stepv# = (1.0/tilez) `set base u data for new set of tiles baseu# = 0 `set base v data for new set of tiles basev# = 1-stepv# `poly number placeholder variable i = 1 `from front to back for k = 1 to matzsegs `reset the number of x tiles to 1 and the u base to 0 `at the beginning of each row xtiles = 1 baseu# = 0 `from left to right for l = 1 to matxsegs `2 polys per tile for m = 1 to 2 `write all 3 verts of each matrix poly for j = 0 to 2 `select which formula to apply depending on polygon side `and vert number (0 to 2) `j selects the vert number `m selects the polygon side (back/left or front right : 1 or 2) select j case 0 if m = 1 testu# = baseu# testv# = basev#+stepv# else testu# = baseu# testv# = basev#+stepv# endif endcase case 1 if m = 1 testu# = baseu# testv# = basev# else testu# = baseu#+stepu# testv# = basev# endif endcase case 2 if m = 1 testu# = baseu#+stepu# testv# = basev# else testu# = baseu#+stepu# testv# = basev#+stepv# endif endcase endselect `store calculated data for each vert of each poly `u data vert_store#(i,j,6) = testu# `v data vert_store#(i,j,7) = testv# next j inc i, 1 `next polygon side of this tile next m `update u data and xtiles place holder inc baseu#, stepu# inc xtiles, 1 `reset data when texture tile width has been reached if xtiles > tilex baseu# = 0 xtiles = 1 endif `next x tile next l `update v data and ztiles place holder dec basev#, stepv# inc ztiles, 1 `reset data when texture depth has been reached if ztiles > tilez basev# = 1-stepv# ztiles = 1 endif `next z tile next k `****************************************************************************** `****************************************************************************** `make object from matrix verts `calc number of memblocks needed tempx = matxsegs/limbx tempz = matzsegs/limbz tempmem = tempx * tempz `make arrays to store memblock positions and memblock numbers dim membhold(tempx, tempz) dim mempos(tempmem) `enter memblock numbers for each texture tile based on the x and z limbs to use a = 1 for i = 1 to tempz for j = 1 to tempx membhold(j, i) = a inc a, 1 next j next i `calc the memblock size `formula is 12 byte header + ((( 32 bytes per vert * limb x segs)*(limb z segs * 2 polys))* 3 verts per poly) mat_mem_size = 12+(((32*limbx)*(limbz*2))*3) `make memblocks and write headers for each memblock and set the beginning `position for vert data to 12 for i = 1 to tempmem make memblock i, mat_mem_size `write objects fvf format as 274 write memblock dword i, 0, 274 `write bytes per vert as 32 (8 floats xpos#,ypos#,zpos#,xnorm#,ynorm#,znorm#,u#,v#) write memblock dword i, 4, 32 `write number of verts in matrix (polys*3) write memblock dword i, 8, ((limbx*limbz)*2)*3 `set beginning position for vert data after header(0-8)+4 = 12 mempos(i) = 12 next i `image tile, row, and memblock placeholders xtile = 1 ztile = 1 xrow = 1 xmem = 1 zmem = 1 `polygon placeholders (b=2 is 1 tile complete) b = 1 `enter all polys' verts to memblock for i = 1 to num_mat_polys `select memblock number to write to use current x and z limb tile to pick tempmemnum = membhold(xmem, zmem) `write all 3 verts of each matrix poly for j = 0 to 2 `xpos write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,0) `increment the current memblock position inc mempos(tempmemnum), 4 `ypos write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,1) inc mempos(tempmemnum), 4 `zpos write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,2) inc mempos(tempmemnum), 4 `xnorm write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,3) inc mempos(tempmemnum), 4 `ynorm write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,4) inc mempos(tempmemnum), 4 `znorm write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,5) inc mempos(tempmemnum), 4 `u data write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,6) inc mempos(tempmemnum), 4 `v data write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,7) inc mempos(tempmemnum), 4 next j `after each poly increase b by 1 inc b, 1 `after 2 polys have been completed 1 tile has been entered if b > 2 `reset poly count to 1 b = 1 `move to next x tile inc xtile, 1 `if at the next limb if xtile > limbx `reseet the x tile to 1 xtile = 1 `update the tile count to know when to move to the next row inc xrow, limbx `inc the xmem selector placeholder inc xmem, 1 `if at the last xmem wide then start back at the begining if xmem > tempx xmem = 1 endif endif `when at the end of the row if xrow > matxsegs `go back to the far left xrow = 1 `update the number of rows done inc ztile, 1 `when the number of rows done is > the preset depth if ztile > limbz `reset row count back to 1 ztile = 1 `move to the next zmem selector placeholder inc zmem, 1 `if row count overlaps predetermined number if zmem > tempz `wrap to 1 zmem = 1 endif endif endif endif next i `undim arrays when done with them undim vert_store#(0,0,0) undim membhold(0, 0) undim mempos(0) `set the mesh number to use (can be replaced with a findfreemesh function) mesh = 1 `make object and limbs from data setup for i = 1 to tempmem `make temp mesh from info make mesh from memblock mesh, i `delete temp memblock delete memblock i `if it is the first memblock mesh, use it as the base object if i = 1 `make temp object for NGC make object object, mesh, 0 `else turn each memblock mesh into limbs else add limb object, i-1, mesh endif `delete temp mesh delete mesh mesh next i `****************************************************************************** endfunction function check_free_image_number() `this functionworks in the same way as the check_free_object function, `except it works for images. image=image_seed repeat inc image until image exist(image)=0 endfunction image wave: `****move the generator points up and down**** y#=amplitude#*sin(theta#) theta#=theta#+frequency# if fixed(tile(a,b))=1 set matrix height 2,a,b,y# endif if fixed(tile(c,d))=1 set matrix height 2,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(2,x+1,z)-get matrix height (2,x,z) endif `check x-1 height if x>1 distxm1#=get matrix height(2,x-1,z)-get matrix height (2,x,z) endif `check z+1 height if z<columns distzp1#=get matrix height(2,x,z+1)-get matrix height (2,x,z) endif `check z-1 height if z>1 distzm1#=get matrix height(2,x,z-1)-get matrix height (2,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 2,x,z,get matrix height(2,x,z)+v#(tile(x,z)) v#(tile(x,z))=v#(tile(x,z))*damping# endif next z next x update matrix 2 `**************************************************** return get_wave_slope: for object=1 to number y#(object)=get ground height(2,x#(object),z#(object)) yfront#=get ground height(2,newxvalue(x#(object),angle#,1),newzvalue(z#(object),angle#,1)) yside#=get ground height(2,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*************