Post by Guy on Dec 20, 2017 11:17:50 GMT
This shows a bunch of bubble things that bump into each other... and glow! Stare at it or not, your preference.
Copy/Paste program below:
---------------
--####################
--# Bubbles Thingy
--####################
local bubbles = {}
function bubbles.new(o, i, maxSize) -- minSize is 3
i = i or #o
maxSize = maxSize and maxSize > 3 and maxSize or 3
local r = math.random
local a = {} -- Atom
-- x, y
a[1], a[2] = r(20, W - 20), r(20, H - 20)
-- dx, dy
a[3], a[4] = (r()>0.5 and -1 or 1) * r()/6, (r()>0.5 and -1 or 1) * r()/6
-- Mass & Size, Color
a[5], a[6] = 3 + (maxSize - 3)*r(), {
0.5 + r() / 2, 0.5 + r() / 2, 0.5 + r() / 2, 1
}
-- Collided
a[7] = false
local function valid()
for i = 1, #o do
if o:collision(a, i) then
return false
end
end
return true
end
repeat
a[1], a[2] = r(20, W - 20), r(20, H - 20)
until valid()
o = a
end
-- Returns values of an bubble
function bubbles.getProp(o, i)
local a = o
return a[1], a[2], a[3], a[4], a[5], a[6]
end
function bubbles.co(o, i)
o[7] = true
end
function bubbles.gco(o, i)
if o[7] then
o[7] = false
return true
end return false
end
function bubbles.setVector(o, i, vx, vy)
local a = o
a[3], a[4] = vx, vy
end
function bubbles.setVectors(o, i, j, vx, vy, vxx, vyy)
o:setVector(i, vx, vy)
o:setVector(j, vxx, vyy)
end
-- Update a bubble's position
function bubbles.move(o, i, r)
local a, r = o, r or 1
a[1] = a[1] + a[3]*r
a[2] = a[2] + a[4]*r
end
-- Check if a bubble hits the boundaries
-- Change heading if needed
-- Uses global W & H set in main
function bubbles.wallCollision(o, i)
local x, y, vx, vy, r = o:getProp(i)
-- Right|Left wall
if x + r > W then
if vx > 0 then
o:setVector(i, -vx, vy)
end
o:co(i)
end
if x - r < 0 then
if vx < 0 then
o:setVector(i, -vx, vy)
end
o:co(i)
end
-- Bottom|Top wall
if y + r > H then
if vy > 0 then
o:setVector(i, vx, -vy)
end
o:co(i)
end
if y - r < 0 then
if vy < 0 then
o:setVector(i, vx, -vy)
end
o:co(i)
end
end
-- Checks for collision between bubbles and [j]
function bubbles.collision(o, i, j)
local a, b = type(i) == "table" and i or o, o[j]
local x, y, r = a[1] - b[1], a[2] - b[2], a[5] + b[5]
if x * x + y * y < r * r then -- Pythagorean Stuff
return true
end return false
end
-- vx|vy calculation after collision
function bubbles.calcV(v, m, vv, mm)
return v - 2 * mm * (v - vv) / (m + mm)
end
-- Returns new Vectors after collision
function bubbles.newVectors(o, i, j)
vtype = vtype or 0
local x, y, vx, vy, m = o:getProp(i)
local xx, yy, vxx, vyy, mm = o:getProp(j)
return o.calcV(vx, m, vxx, mm),
o.calcV(vy, m, vyy, mm),
o.calcV(vxx, mm, vx, m),
o.calcV(vyy, mm, vy, m)
end
-- Updates all bubbles
function bubbles.update(o, updateRate)
for i = 1, updateRate do
for i = 1, #o do -- Each bubble
o:wallCollision(i) -- Check wall hits
local j = i + 1
while j <= #o do -- bubbles that may collide
if o:collision(i, j) then -- Check Collisions
o:wallCollision(i)
o:setVectors(i, j, o:newVectors(i, j, 1))
o:co(i) o:co(j)
while o:collision(i, j) do
o:wallCollision(i)
o:move(i)
o:move(j)
o:co(i) o:co(j)
end
j = i
end
j = j + 1
end
end
if touch then
for i = 1, #o do
local v = {tx, ty, tdx, tdy, 30}
if o:collision(0, i) then
calcCollision(v, b, true)
end
end
end
for i = 1, #o do -- Move bubbles
o:move(i)
end
end
end
-- Draws a bubble
-- And a line for speed & direction
function bubbles.draw(o, i)
local x, y, vx, vy, r, c = o:getProp(i)
if o:gco(i) then
draw.fillcircle(x, y, r, c)
else
draw.circle(x, y, r, c)
end
--draw.line(x, y, x + 50 * vx, y + 50 * vy, c)
end
-- Draws all bubbles
function bubbles.drawAll(o)
for i = 1, #o do
o:draw(i)
end
end
--####################
--# Main Code
--####################
local function init(num, maxSize)
for i = 1, num do
bubbles:new(i, maxSize)
end
end
local function update()
bubbles:update(5)
end
local function disp()
bubbles:drawAll()
end
local function main(num, maxSize)
draw.setscreen(1)
draw.showtitle(false)
W, H = draw.getport()
init(num, maxSize)
while true do
draw.doevents()
update()
draw.clear(draw.black)
draw.beginframe()
disp()
draw.endframe()
end
end
main(100, 20)
Copy/Paste program below:
---------------
--####################
--# Bubbles Thingy
--####################
local bubbles = {}
function bubbles.new(o, i, maxSize) -- minSize is 3
i = i or #o
maxSize = maxSize and maxSize > 3 and maxSize or 3
local r = math.random
local a = {} -- Atom
-- x, y
a[1], a[2] = r(20, W - 20), r(20, H - 20)
-- dx, dy
a[3], a[4] = (r()>0.5 and -1 or 1) * r()/6, (r()>0.5 and -1 or 1) * r()/6
-- Mass & Size, Color
a[5], a[6] = 3 + (maxSize - 3)*r(), {
0.5 + r() / 2, 0.5 + r() / 2, 0.5 + r() / 2, 1
}
-- Collided
a[7] = false
local function valid()
for i = 1, #o do
if o:collision(a, i) then
return false
end
end
return true
end
repeat
a[1], a[2] = r(20, W - 20), r(20, H - 20)
until valid()
o = a
end
-- Returns values of an bubble
function bubbles.getProp(o, i)
local a = o
return a[1], a[2], a[3], a[4], a[5], a[6]
end
function bubbles.co(o, i)
o[7] = true
end
function bubbles.gco(o, i)
if o[7] then
o[7] = false
return true
end return false
end
function bubbles.setVector(o, i, vx, vy)
local a = o
a[3], a[4] = vx, vy
end
function bubbles.setVectors(o, i, j, vx, vy, vxx, vyy)
o:setVector(i, vx, vy)
o:setVector(j, vxx, vyy)
end
-- Update a bubble's position
function bubbles.move(o, i, r)
local a, r = o, r or 1
a[1] = a[1] + a[3]*r
a[2] = a[2] + a[4]*r
end
-- Check if a bubble hits the boundaries
-- Change heading if needed
-- Uses global W & H set in main
function bubbles.wallCollision(o, i)
local x, y, vx, vy, r = o:getProp(i)
-- Right|Left wall
if x + r > W then
if vx > 0 then
o:setVector(i, -vx, vy)
end
o:co(i)
end
if x - r < 0 then
if vx < 0 then
o:setVector(i, -vx, vy)
end
o:co(i)
end
-- Bottom|Top wall
if y + r > H then
if vy > 0 then
o:setVector(i, vx, -vy)
end
o:co(i)
end
if y - r < 0 then
if vy < 0 then
o:setVector(i, vx, -vy)
end
o:co(i)
end
end
-- Checks for collision between bubbles and [j]
function bubbles.collision(o, i, j)
local a, b = type(i) == "table" and i or o, o[j]
local x, y, r = a[1] - b[1], a[2] - b[2], a[5] + b[5]
if x * x + y * y < r * r then -- Pythagorean Stuff
return true
end return false
end
-- vx|vy calculation after collision
function bubbles.calcV(v, m, vv, mm)
return v - 2 * mm * (v - vv) / (m + mm)
end
-- Returns new Vectors after collision
function bubbles.newVectors(o, i, j)
vtype = vtype or 0
local x, y, vx, vy, m = o:getProp(i)
local xx, yy, vxx, vyy, mm = o:getProp(j)
return o.calcV(vx, m, vxx, mm),
o.calcV(vy, m, vyy, mm),
o.calcV(vxx, mm, vx, m),
o.calcV(vyy, mm, vy, m)
end
-- Updates all bubbles
function bubbles.update(o, updateRate)
for i = 1, updateRate do
for i = 1, #o do -- Each bubble
o:wallCollision(i) -- Check wall hits
local j = i + 1
while j <= #o do -- bubbles that may collide
if o:collision(i, j) then -- Check Collisions
o:wallCollision(i)
o:setVectors(i, j, o:newVectors(i, j, 1))
o:co(i) o:co(j)
while o:collision(i, j) do
o:wallCollision(i)
o:move(i)
o:move(j)
o:co(i) o:co(j)
end
j = i
end
j = j + 1
end
end
if touch then
for i = 1, #o do
local v = {tx, ty, tdx, tdy, 30}
if o:collision(0, i) then
calcCollision(v, b, true)
end
end
end
for i = 1, #o do -- Move bubbles
o:move(i)
end
end
end
-- Draws a bubble
-- And a line for speed & direction
function bubbles.draw(o, i)
local x, y, vx, vy, r, c = o:getProp(i)
if o:gco(i) then
draw.fillcircle(x, y, r, c)
else
draw.circle(x, y, r, c)
end
--draw.line(x, y, x + 50 * vx, y + 50 * vy, c)
end
-- Draws all bubbles
function bubbles.drawAll(o)
for i = 1, #o do
o:draw(i)
end
end
--####################
--# Main Code
--####################
local function init(num, maxSize)
for i = 1, num do
bubbles:new(i, maxSize)
end
end
local function update()
bubbles:update(5)
end
local function disp()
bubbles:drawAll()
end
local function main(num, maxSize)
draw.setscreen(1)
draw.showtitle(false)
W, H = draw.getport()
init(num, maxSize)
while true do
draw.doevents()
update()
draw.clear(draw.black)
draw.beginframe()
disp()
draw.endframe()
end
end
main(100, 20)