Water Simulation/Source

-- Water Simulation with waves based on the tutorial on gamedeveloppement.tutplus.com by Michael Hoffman waterColor = {0, 0.5, 1, 1} -- <<-- Transparency to 0.5

function main -- Set draw screen draw.setscreen(1) draw.settitle('Water Simulation') draw.clear

-- Initialize variables initializeVariables

-- Do events draw.tracktouches(clicked, moved, ended) while true do     draw.doevents update drawScreen sleep(10) end end

function initializeVariables sw, sh = draw.getport ballRadius, ballDropped = 20, false tension, dampening, spread = 0.025, 0.04, 0.25 waterLevel, count = sh/2, sw/10 + 1 height, velocity = {}, {}

for i = 1, count do     height[i], velocity[i] = waterLevel, 0 height[i] = waterLevel end end

function update -- Update springs for i = 1, count do     local x = height[i] - waterLevel local acceleration = -tension * x - velocity[i]*dampening height[i] = height[i] + velocity[i] velocity[i] = velocity[i] + acceleration end

-- Make the waves propagate leftDeltas, rightDeltas = {}, {} for j = 1, 8 do     for i = 1, count do         if i > 1 then leftDeltas[i] = spread * (height[i] - height[i-1]) velocity[i-1] = velocity[i-1] + leftDeltas[i] end if i < count-1 then rightDeltas[i] = spread * (height[i] - height[i+1]) velocity[i+1] = velocity[i+1] + rightDeltas[i] end end for i = 1, count do        if i > 1 then height[i-1] = height[i-1] + leftDeltas[i] end if i < count-1 then height[i+1] = height[i+1] + rightDeltas[i] end end end

if ballDropped == true then -- Accelerate the water spring spring = math.floor(ballX/10) if ballY > height[spring] then velocity[spring] = velocity[spring] + ballVelocity end

-- Accelerate the ball if ballY < height[spring]+ballRadius then ballVelocity = ballVelocity + 6 else ballVelocity = 5 end ballY = ballY + ballVelocity

-- Enable possibility to drop another ball if ballY > sh+ballRadius then ballDropped, ballX = false, 0 end end end

function drawScreen draw.beginframe draw.clear

-- Draw the ball if necessary if ballX ~= nil then draw.setantialias(true) draw.setlinestyle(4, 'round') draw.circle(ballX, ballY, ballRadius, draw.black) end

-- Draw the water draw.setantialias(false) -- Smoother water for i = 1, count-1 do     draw.filltriangle((i-1)*10, height[i], i*10, height[i+1], (i-1)*10, sh, waterColor) draw.filltriangle(i*10, height[i+1], i*10, sh, (i-1)*10, sh, waterColor) end

draw.endframe end

function clicked(x, y) moved(x, y) end function moved(x, y)  -- Move the ball according to the touch position if ballDropped == false and y < waterLevel and x > ballRadius and x < sw-ballRadius then ballX, ballY = x, y end end function ended(x, y)  -- Drop the ball ballDropped, ballVelocity = true, 0 end

main -- --