Wooo, springy nodes!
- weeeeeeee....
- Springy Nodes.png (138.6 KiB) Viewed 7915 times
By the way, ridiculous things WILL happen if you set the maxDist variable too high.
Edit 1: Optimized code a bit.
Code: Select all
local screen = {}
function love.load()
screen.width = love.window.getWidth()
screen.height = love.window.getHeight()
nodeList = {}
nodeRadius = 2
numNodes = 100
for i=1, numNodes do
local node = {}
node.x = math.random()*screen.width
node.y = math.random()*screen.height
local v = math.random()*150
local th = math.random()*2*math.pi
node.vx = v*math.cos(th)
node.vy = v*math.sin(th)
nodeList[i] = node
end
phyClock = {}
phyClock.curTime = 0
springConstant = 75
maxDist = 100
end
function love.update(dt)
-- do physics at about 100 frames per second
while phyClock.curTime < dt do
phyClock.curTime = phyClock.curTime + 0.01
for i=1, numNodes do
local A = nodeList[i]
for j=i+1, numNodes do
local B = nodeList[j]
local dx = (A.x-B.x)
local dy = (A.y-B.y)
local dist = dx^2 + dy^2
if dist < maxDist*maxDist then
local ang = math.atan2(dy, dx)
local falloff = 1-dist/(maxDist*maxDist)
local F = springConstant*falloff
A.vx = A.vx - F*math.cos(ang)*0.01
A.vy = A.vy - F*math.sin(ang)*0.01
B.vx = B.vx + F*math.cos(ang)*0.01
B.vy = B.vy + F*math.sin(ang)*0.01
end
end
end
for i=1, numNodes do
local node = nodeList[i]
node.x = node.x + node.vx*0.01
node.y = node.y + node.vy*0.01
if node.x+nodeRadius < 0 then
node.x = screen.width + nodeRadius
elseif node.x-nodeRadius > screen.width then
node.x = -nodeRadius
end
if node.y+nodeRadius < 0 then
node.y = screen.height + nodeRadius
elseif node.y-nodeRadius > screen.height then
node.y = -nodeRadius
end
end
end
phyClock.curTime = phyClock.curTime - dt
end
function love.draw()
for i=1, numNodes do
love.graphics.setColor(255, 255, 255)
local node = nodeList[i]
love.graphics.circle("fill", node.x, node.y, nodeRadius)
for j=i+1, numNodes do
local b = nodeList[j]
local dist = (node.x-b.x)^2 + (node.y-b.y)^2
local falloff = math.max((1-dist/(maxDist*maxDist)), 0)
if falloff > 0 then
--love.graphics.setColor(255, 255, 255, falloff*192)
love.graphics.setColor(HSL(falloff*255, 255, 128, falloff*255))
love.graphics.line(node.x, node.y, b.x, b.y)
end
end
end
end
-- Converts HSL to RGB. (input and output range: 0 - 255)
function HSL(h, s, l, a)
if s<=0 then return l,l,l,a end
h, s, l = h/256*6, s/255, l/255
local c = (1-math.abs(2*l-1))*s
local x = (1-math.abs(h%2-1))*c
local m,r,g,b = (l-.5*c), 0,0,0
if h < 1 then r,g,b = c,x,0
elseif h < 2 then r,g,b = x,c,0
elseif h < 3 then r,g,b = 0,c,x
elseif h < 4 then r,g,b = 0,x,c
elseif h < 5 then r,g,b = x,0,c
else r,g,b = c,0,x
end return (r+m)*255,(g+m)*255,(b+m)*255,a
end
Version 2:
- I'M ON FIAAAAAAAAAAA
- Springy Nodes 2.png (227.77 KiB) Viewed 7898 times
Code: Select all
local screen = {}
function love.load()
screen.width = love.window.getWidth()
screen.height = love.window.getHeight()
nodeList = {}
nodeRadius = 2
numNodes = 150
for i=1, numNodes do
local node = {}
node.x = math.random()*screen.width
node.y = math.random()*screen.height
local v = math.random()*200
local th = math.random()*2*math.pi
node.vx = v*math.cos(th)
node.vy = v*math.sin(th)
nodeList[i] = node
end
phyClock = {}
phyClock.curTime = 0
springConstant = 75
maxDist = 120
curTime = 0
end
function love.update(dt)
-- do physics at about 100 frames per second
curTime = curTime + dt
while phyClock.curTime < dt do
phyClock.curTime = phyClock.curTime + 0.01
for i=1, numNodes do
local A = nodeList[i]
for j=i+1, numNodes do
local B = nodeList[j]
local dx = (A.x-B.x)
local dy = (A.y-B.y)
local dist = dx^2 + dy^2
if dist < maxDist*maxDist then
local ang = math.atan2(dy, dx)
local falloff = 1-dist/(maxDist*maxDist)
local F = springConstant*falloff
A.vx = A.vx - F*math.cos(ang)*0.01
A.vy = A.vy - F*math.sin(ang)*0.01
B.vx = B.vx + F*math.cos(ang)*0.01
B.vy = B.vy + F*math.sin(ang)*0.01
end
end
end
for i=1, numNodes do
local node = nodeList[i]
node.x = node.x + node.vx*0.01
node.y = node.y + node.vy*0.01
if node.x+nodeRadius < 0 then
node.x = screen.width + nodeRadius
elseif node.x-nodeRadius > screen.width then
node.x = -nodeRadius
end
if node.y+nodeRadius < 0 then
node.y = screen.height + nodeRadius
elseif node.y-nodeRadius > screen.height then
node.y = -nodeRadius
end
end
end
phyClock.curTime = phyClock.curTime - dt
end
function love.draw()
love.graphics.setBlendMode("additive")
for i=1, numNodes do
love.graphics.setColor(0, 255, 255)
local node = nodeList[i]
love.graphics.circle("fill", node.x, node.y, nodeRadius)
for j=i+1, numNodes do
local b = nodeList[j]
local dist = (node.x-b.x)^2 + (node.y-b.y)^2
local falloff = math.max((1-dist/(maxDist*maxDist)), 0)
if falloff > 0 then
--love.graphics.setColor(255, 255, 255, falloff*192)
love.graphics.setColor(HSL((falloff*255+curTime*32)%255, 255, 128, falloff*255))
--love.graphics.setLineWidth(falloff*nodeRadius*2)
love.graphics.line(node.x, node.y, b.x, b.y)
end
end
end
end
-- Converts HSL to RGB. (input and output range: 0 - 255)
function HSL(h, s, l, a)
if s<=0 then return l,l,l,a end
h, s, l = h/256*6, s/255, l/255
local c = (1-math.abs(2*l-1))*s
local x = (1-math.abs(h%2-1))*c
local m,r,g,b = (l-.5*c), 0,0,0
if h < 1 then r,g,b = c,x,0
elseif h < 2 then r,g,b = x,c,0
elseif h < 3 then r,g,b = 0,c,x
elseif h < 4 then r,g,b = 0,x,c
elseif h < 5 then r,g,b = x,0,c
else r,g,b = c,0,x
end return (r+m)*255,(g+m)*255,(b+m)*255,a
end