Ye olde water algorithm by Tinkerer10th May 2005 13:38
|
---|
Summary This is a simple demo of a well-known water algorithm. Description This is a simple demo of a well-known water algorithm. Mouse1 adjusts the interference level, and mouse2 adjusts the interference type. Further options can be set by adjusting variables. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com REM Project: water REM Created: 10/05/2005 03:09:33 REM REM ***** Main Source File ***** REM rem set sync up sync on : sync rate 60 rem hide the mouse pointer hide mouse rem declare the two arrays that will be used to hold height information dim imgbuffer1(1024, 1024) AS FLOAT dim imgbuffer2(1024, 1024) AS FLOAT rem make this as big as your system can handle! gridsize = 128 rem this value determines how large the matrix will be rendered gridmultiplier = 8 rem fill the arrays with zeros for z = 0 to gridsize + 1 for x = 0 to gridsize + 1 imgbuffer1(x, z) = 0.0 imgbuffer2(x, z) = 0.0 next x next z rem determine where the middle of the matrix will be middle = gridsize / 2 rem set this to a value BELOW ZERO. Or don't and enjoy the fireworks. rem 0.90 to 0.999 are "sensible" values. damping AS FLOAT damping = 0.99 rem making this higher will slow the wave frequency of the mouse+sine effect. wavefreq AS FLOAT wavefreq = 1 rem adjusting these two variables will determine how much mouse button 1 affects rem the interference generators. lowheight = 10 highheight = 100 rem you can customize your own water behaviour using the above three variables together rem the current pattern value is stored here pattern AS INTEGER pattern = 0 rem the current algorithm (water or mousepad foam) mtype = 0 rem the next two variables are used together to stop the pattern changing in a loop when rem mouse 2 is held down. clik AS INTEGER clik = 0 lastclik AS INTEGER lastclik = 0 rem the next two variables are used together to stop the matrix behaviour changing in a rem loop when the spacebar is held down. lastspace = 0 space = 0 rem a temporary variable. Used later on. tmp AS FLOAT rem current mouse position and mouse+sine wave generator height go here. mouseposx AS INTEGER mouseposz AS INTEGER waveheight AS INTEGER waveheight = lowheight rem load matrix texture here MImg = 1 : load image "wtex.jpg", MImg rem calulate matrix size and place in these two variables matrixsize AS FLOAT matrixsize = gridsize * gridmultiplier matrixmiddle AS FLOAT matrixmiddle = matrixsize / 2.0 rem declare and set the matrix here MObj = 1 : make matrix MObj, matrixsize, matrixsize, gridsize, gridsize MImg = 1 : load image "wtex.jpg", MImg prepare matrix texture MObj, MImg, 1,1 rem set the initial position of the camera here position camera 0,(sin(timer() / 100.0) * 100.0) + matrixsize,300.0,(cos(timer() / 110.0) * 100.0) + matrixsize rem main loop do rem get the new mouse position mouseposx = mouseposx + (mousemovex() / 5) mouseposz = mouseposz + -(mousemovey() / 5) rem limit the mouse position to valid array indices if mouseposx > gridsize then mouseposx = gridsize if mouseposz > gridsize then mouseposz = gridsize if mouseposx < 1 then mouseposx = 1 if mouseposz < 1 then mouseposz = 1 rem pan the camera around slowly position camera 0,matrixmiddle - (sin(timer() / 100.0) * 200.0),300.0,(cos(timer() / 110.0) * 100.0) point camera matrixmiddle,-300,matrixmiddle rem calculate current wave generator values sinfreq = timer() / wavefreq sincalc = 0.0 + sin(sinfreq) * waveheight coscalc = 0.0 + cos(sinfreq) * waveheight rem capture mouse values and change pattern and waveheight values accordingly lastclik = clik clik = mouseclick() if clik <> lastclik select clik case 0 waveheight = lowheight endcase case 1 waveheight = highheight endcase case 2 waveheight = lowheight inc pattern endcase case 3 waveheight = highheight inc pattern endcase endselect endif if pattern > 2 then pattern = 0 select pattern case 0 print "Interference type: mouse + sine" imgbuffer1(mouseposx, mouseposz) = imgbuffer1(mouseposx, mouseposz) + sincalc endcase case 1 print "Inteference type: rain" randomize timer() tx = rnd(gridsize - 1) + 1 ty = rnd(gridsize - 1) + 1 imgbuffer1(tx, ty) = imgbuffer1(tx, ty) + sincalc endcase case 2 print "Interference type: none" endcase endselect rem get the spacebar state. lastspace = space space = spacekey() rem ignore if state is same as last state. if space <> lastspace if space = 1 inc mtype if mtype > 1 then mtype = 0 endif endif select mtype case 0 print "Matrix behaviour: water" endcase case 1 print "Matrix behaviour: memory foam" endcase endselect rem this is the place where algorithms are applied. Remarks left out for speed. rem the first set of embedded loops are for water, the second for a low rebound rem foam-like behaviour. The third set of loops is used by both behaviours to rem swap the contents of the two buffers. select mtype case 0 for z = 1 to gridsize for x = 1 to gridsize imgbuffer2(x, z) = (imgbuffer1(x - 1, z) + imgbuffer1(x + 1, z) + imgbuffer1(x, z + 1) + imgbuffer1(x, z - 1)) / 2 - imgbuffer2(x, z) imgbuffer2(x, z) = imgbuffer2(x, z) * damping next x next z endcase case 1 for z = 1 to gridsize for x = 1 to gridsize imgbuffer2(x, z) = (imgbuffer1(x - 1, z) + imgbuffer1(x + 1, z) + imgbuffer1(x, z + 1) + imgbuffer1(x, z - 1)) / 2 - imgbuffer2(x, z) imgbuffer2(x, z) = imgbuffer1(x, z) * damping next x next z endcase endselect for z = 1 to gridsize for x = 1 to gridsize tmp = imgbuffer1(x, z) imgbuffer1(x, z) = imgbuffer2(x, z) imgbuffer2(x, z) = tmp set matrix height MObj, x, z, imgbuffer2(x, z) next x next z rem done with water algorithm. Update matrix with new values. update matrix MObj rem print out a status display. set cursor 0,1 : print "mpx: "; mouseposx; " mpz: "; mouseposz; " fps: "; screen fps() rem flip the buffers. sync rem end of main loop loop end |