--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() -- --