Hello,
I made this as a prototype for a new type of object in my game, so here’s the code:
displayMode(FULLSCREEN)
function setup()
parameter.watch("1/DeltaTime")
fixtures = {}
local gSize = vec2(WIDTH,HEIGHT/2)
local gScale = 5
local funnleSize = 20
funnle1 = physics.body(CHAIN,false,vec2(-gSize.x,gSize.y),
vec2(-funnleSize,-gSize.y/3),
vec2(-funnleSize,-gSize.y)
)
local funnle2 = physics.body(CHAIN,false,vec2(gSize.x,gSize.y),
vec2(funnleSize,-gSize.y/3),
vec2(funnleSize,-gSize.y)
)
local split = physics.body(CHAIN,false,vec2(-WIDTH/2,-HEIGHT/8),
vec2(0,HEIGHT/80),
vec2(WIDTH/2,-HEIGHT/8)
)
funnle1.x = WIDTH / 2
funnle1.y = HEIGHT - HEIGHT / 4
funnle1.type = STATIC
funnle2.x = WIDTH / 2
funnle2.y = HEIGHT - HEIGHT / 4
funnle2.type = STATIC
split.x = WIDTH / 2
split.y = HEIGHT/8
split.type = STATIC
--split.restitution = .5
table.insert(fixtures,funnle1)
table.insert(fixtures,funnle2)
table.insert(fixtures,split)
blankImage = image(WIDTH,HEIGHT)
blur = 30
water = {}
waterimage = softImage(color(0, 155, 255),5,blur)
allWater = blankImage
--[[waterMesh = mesh()
waterMesh.texture = waterimage]]--
mDisplay = mesh()
mDisplay:addRect(WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
mDisplay.shader = shader(alphaThreshold())
mDisplay.shader.smoothness = 0
mDisplay.shader.threshold = .1
mDisplay.shader.unpremultiply = 1
end
function draw()
background(0, 0, 0, 255)
physics.gravity(Gravity)
smooth()
setContext(allWater)
background(0, 0, 0, 0)
noStroke()
smooth()
--for i,v in ipairs(water) do
for i = #water,1,-1 do
v = water[i]
sprite(waterimage,v.body.x,v.body.y,blur,blur)
--waterMesh:addRect(v.body.x,v.body.y,blur*extraSpace,blur*extraSpace)
if v.body.x <= 0 or v.body.x >= WIDTH or v.body.y <= 0 or v.body.y >= HEIGHT then
v.body:destroy()
table.remove(water,i)
end
end
--waterMesh:draw()
--waterMesh:clear()
setContext()
mDisplay.texture = allWater
mDisplay:draw()
strokeWidth(12)
for i,v in ipairs(fixtures) do
pushMatrix()
translate(v.x,v.y)
local points = v.points
for j = 1,#points-1 do
a = points[j]
b = points[(j % #points)+1]
line(a.x, a.y, b.x, b.y)
end
popMatrix()
end
popMatrix()
end
function touched(t)
addWater(10,t.x,t.y)
end
function softImage(f,r,s)
simg = image(r,r)
setContext(simg)
pushStyle()
noStroke()
fill(f)
ellipse(simg.width/2,simg.height/2,simg.width)
popStyle()
setContext()
limg = image(s,s)
setContext(simg)
pushStyle()
smooth()
sprite(simg,0,0,s,s)
popStyle()
setContext()
return simg
end
function addWater(amnt,x,y)
local posRand = 20
local vRand = 0
for i = 1,amnt do
local b = physics.body(CIRCLE,3)
b.x = x + math.random(-posRand,posRand)
b.y = y + math.random(-posRand,posRand)
b.linearVelocity = vec2(math.random(-vRand,vRand),math.random(-vRand,vRand))
b.restitution = .1
table.insert(water,{body = b})
end
end
function alphaThreshold()
return [[
//
// A basic vertex shader
//
//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;
//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
//Pass the mesh color to the fragment shader
vColor = color;
vTexCoord = texCoord;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],
[[
precision highp float;
uniform lowp sampler2D texture;
uniform float threshold;
uniform float smoothness;
uniform float unpremultiply;
varying lowp vec4 vColor;
varying vec2 vTexCoord;
void main()
{
lowp vec4 color = texture2D( texture, vTexCoord ) ;
if( unpremultiply > 0.0 ) { color.rgb /= color.a ; }
float range = ( color.a - (1.0 - threshold) - (smoothness * 0.05) ) / (0.0001 + smoothness * 0.1) ;
color.a = smoothstep( 0.0, 1.0, range ) ;
color.rgb *= color.a ;
gl_FragColor = color ;
}]]
end