Last active
August 9, 2022 17:46
-
-
Save L0laapk3/b40be2a48c14e07204b21517ab41e869 to your computer and use it in GitHub Desktop.
computercraft fireworks screensaver animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Fireworks screensaver animation | |
-- By L0laapk3, based on Rectar's Fireworks | |
launchRate = 0.03 | |
fireworks = {} | |
particles = {} | |
fcolors={1,2,4,8,16,32,64,512,1024,2048,8192,16384} | |
particleChars = {"#","X","+","*","."} | |
starsChance = "+x*..." | |
stars = {} | |
function getWidth() | |
local w, h = term.getSize() | |
return w | |
end | |
function getHeight() | |
local w, h = term.getSize() | |
return h | |
end | |
-- function generateStars() | |
local w, h = term.getSize() | |
local QSIZE = 7 | |
for xQ = 1, w + QSIZE, QSIZE do | |
for yQ = 1, h + QSIZE, QSIZE do | |
local star = {} | |
star.x = xQ + 1 + math.floor(math.random() * QSIZE) | |
star.y = yQ + 1 + math.floor(math.random() * QSIZE) | |
local charI = math.floor(#starsChance * math.random()) | |
star.char = starsChance:sub(charI, charI) | |
local closeColors = charI <= math.random() * #starsChance | |
star.color1 = closeColors and 0x1 or 0x80 | |
star.color2 = closeColors and 0x80 or 0x100 | |
star.blinkI = math.random() | |
star.blinkIncr = .02 * math.random() | |
star.blinkDecr = .15 * math.random() | |
star.isBright = math.random() > .2 | |
stars[#stars + 1] = star | |
end | |
end | |
function drawStars() | |
for i = 1, #stars do | |
local star = stars[i] | |
term.setCursorPos(star.x, star.y) | |
if star.isBright then | |
term.setTextColor(star.color1) | |
star.blinkI = star.blinkI - star.blinkDecr | |
if star.blinkI <= 0 then | |
star.isBright = false | |
end | |
else | |
term.setTextColor(star.color2) | |
star.blinkI = star.blinkI + star.blinkIncr | |
if star.blinkI >= 1 then | |
star.isBright = true | |
end | |
end | |
term.write(star.char) | |
end | |
end | |
function launchFirework() | |
local firework = {} | |
firework.x = (1.2 * math.random() - 0.1) * getWidth() | |
firework.y = getHeight() | |
firework.vx = (math.random()-0.5) * .7 | |
firework.vy = -((math.random())+3) | |
--firework.vy = (-math.random())*2 | |
firework.color = colors.white | |
table.insert(fireworks, firework) | |
end | |
function drawFireworks() | |
for k,firework in pairs(fireworks) do | |
local dx = math.floor(firework.x) | |
local dy = math.floor(firework.y) | |
term.setCursorPos(dx,dy) | |
term.setTextColor(firework.color) | |
term.write(-firework.vx * 1.5 > -firework.vy and "\\" or firework.vx * 1.5 > -firework.vy and "/" or "|") | |
end | |
end | |
function spawnParticles(x, y) | |
local particleColor = fcolors[math.floor(math.random()*#fcolors)+1] | |
local numPart = math.floor(math.random() * 90) + 20 | |
local commonPartSpeed = .25 + .45 * math.random() | |
for i=1,numPart do | |
local particle = {} | |
particle.x = x | |
particle.y = y | |
particle.c = particleColor | |
local angle = i * 6.283185 / numPart | |
local z = math.random() | |
particle.vx = math.sin(angle) * 3 * z * commonPartSpeed | |
particle.vy = math.cos(angle) * 2 * z * commonPartSpeed | |
particle.life = 1 | |
particle.lifeSpeed = .2 + .8 * math.random() | |
table.insert(particles, particle) | |
end | |
end | |
function updateFireworks() | |
local toRemove = {} | |
for k,firework in pairs(fireworks) do | |
firework.x = firework.x + firework.vx | |
firework.y = firework.y + firework.vy | |
firework.vx = firework.vx * 1.1 | |
firework.vy = firework.vy * 0.9 | |
if firework.vy > -0.5 then | |
spawnParticles(firework.x, firework.y) | |
table.insert(toRemove, k) | |
end | |
end | |
for k,v in pairs(toRemove) do | |
table.remove(fireworks, v) | |
end | |
end | |
function drawParticles() | |
term.setBackgroundColor(colors.black) | |
for k,particle in pairs(particles) do | |
local dx = math.floor(particle.x) | |
local dy = math.floor(particle.y) | |
local pchar = particleChars[math.floor(particle.life)] or "" | |
term.setTextColor(particle.c) | |
term.setCursorPos(dx, dy) | |
term.write(pchar) | |
end | |
end | |
function updateParticles() | |
local toRemove = {} | |
for k,particle in pairs(particles) do | |
particle.x = particle.x + particle.vx | |
particle.y = particle.y + particle.vy | |
particle.vx = particle.vx * .98 | |
particle.vy = particle.vy * .98 + 0.01 | |
particle.life = particle.life + particle.lifeSpeed * math.random() | |
if particle.life >= 6 then | |
table.insert(toRemove,k) | |
end | |
end | |
for k,v in pairs(toRemove) do | |
table.remove(particles,v) | |
end | |
end | |
local window = window.create(term.current(), 1, 1, w, h) | |
term.redirect(window) | |
launchFirework() | |
local tid = os.startTimer(.05) | |
while true do | |
local e, etid, x, y = os.pullEvent() | |
if e == "timer" and tid == etid then | |
tid = os.startTimer(.05) | |
if math.random() > 1 - launchRate then | |
launchFirework() | |
end | |
updateFireworks() | |
updateParticles() | |
window.setVisible(false) | |
term.clear() | |
drawStars() | |
drawFireworks() | |
drawParticles() | |
window.setVisible(true) | |
elseif e == "mouse_click" then | |
spawnParticles(x, y) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
works best on medium-large size monitors,
monitor scale <dir> 0.5
can also help.