Como desenhar lua e estrelas em Lua com LÖVE
A abordagem mais comum para criar uma cena de lua e estrelas em Lua é usando a engine LÖVE (também conhecida como Love2D). O código é curto, mas há detalhes que costumam travar quem está começando. Vou explicar do jeito que funciona na prática.
A base lua e estrelas desenho
Você precisa de um arquivo principal, geralmente chamado main.lua. Nele, você define o loop de jogo e desenha tudo frame a frame. A cena básica tem um fundo escuro, estrelas distribuídas pela tela e um círculo que representa a lua. Para configurar o projeto, instale o LÖVE no site oficial (love2d.org) e crie uma pasta com o main.lua dentro. Abra o terminal nessa pasta e rode "love .". Isso já carrega o projeto sem precisar de configurações extras.
O código inicial fica assim: function love.load()
estrelas = {}
for i = 1, 150 do
table.insert(estrelas, {
x = math.random(love.graphics.getWidth()),
y = math.random(love.graphics.getHeight()),
raio = math.random(1, 2),
brilho = math.random(100, 255)
})
end
lua_x = love.graphics.getWidth() * 0.7
nbsp; lua_y = love.graphics.getHeight() * 0.3
lua_raio = 60
end
O loop de desenho é onde a maioria dos erros acontece. O código correto para renderizar tudo é: function love.draw()
love.graphics.clear(15/255, 15/255, 35/255)
for _, est in ipairs(estrelas) do
love.graphics.setColor(1, 1, 1, est.brilho / 255)
love.graphics.circle("fill", est.x, est.y, est.raio)
end
love.graphics.setColor(1, 0.95, 0.8)
love.graphics.circle("fill", lua_x, lua_y, lua_raio)
love.graphics.setColor(15/255, 15/255, 35/255)
love.graphics.circle("fill", lua_x + 15, lua_y - 10, lua_raio - 8)
end
A parte do Eclipse parcial, onde eu uso um círculo da cor do fundo sobreposto para simular a sombra da lua, é o que dá a ilusão de volume. Sem isso, a lua parece apenas um disco plano colado no céu. Eu demorei duas horas descobrindo esse truque porque tentava usar shaders antes de perceber que uma sobreposição simples resolve.
Fazendo as estrelas piscarem
Para dar vida à cena, você precisa atualizar o brilho das estrelas a cada frame. A função love.update recebe o deltaTime, que é o tempo entre frames, e você usa ele para variar o brilho de forma suave: function love.update(dt)
for _, est in ipairs(estrelas) do
est.brilho = est.brilho + math.random(-20, 20) * dt * 30
if est.brilho > 255 then est.brilho = 255 end
if est.brilho < 50 then est.brilho = 50 end
end
end
O problema aqui é que o math.random puro gera variações muito bruscas. As estrelas ficam piscando de forma artificial. Uma alternativa mais agradável é usar uma função seno baseada no tempo: function love.update(dt)
tempo = tempo + dt
for i, est in ipairs(estrelas) do
est.brilho = 128 + math.sin(tempo * est.x * 0.01 + i) * 80
end
end
Esse método sincroniza o brilho com a posição x da estrela, então estrelas mais à direita piscam em fases diferentes. O resultado é muito mais natural e exige muito menos ajuste manual.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Funcionamento detalhado do sistema
O LÖVE usa um sistema de coordenadas com a origem no canto superior esquerdo. O eixo Y cresce para baixo, não para cima. Se você esperar que a lua fique no topo da tela com y=100, vai se surpreender porque ela vai aparecer quase no topo mesmo assim, mas a escala do movimento vertical é invertida em relação ao que a intuição ditaria. Leva um dia ou dois de uso até o cérebro adaptar. O love.graphics.circle com o modo "fill" preenche o círculo inteiro. Se você usar "line" no lugar, desenha apenas a borda. O terceiro parâmetro é o raio em pixels. Não existe unidade abstracta aqui, tudo é pixel direto na tela. Se a janela for redimensionada, você precisa recalibrar as posições manualmente ou usar love.window.getMode() dentro de love.resize.
Uma coisa que não aparece em tutoriais básicos é o problema do aliasing nas bordas dos círculos. As estrelas e a lua ficam com bordas serrilhadas em resoluções altas. A solução é habilitar o antialiasing no love.conf antes de iniciar o projeto: function love.conf(t)
t.window.width = 800
t.window.height = 600
t.window.resizable = true
t.window.msaa = 4
end
O parâmetro msaa=4 ativa four-sample multisampling. O custo é mínimo em hardware moderno e a diferença visual é imediata. Sem isso, as bordas dos círculos parecem dentes de serra quando você exporta para uma resolução maior.
Limitações e quando esse método não funciona
Esse abordagem funciona bem para projetos simples, jogos 2D e visualizações educacionais. Mas tem limitações claras. Se você precisar de centenas ou milhares de estrelas com efeitos de partículas, o loop em Lua puro começa a ficar pesado. Nesse caso, migrar para um shader de GPU é mais eficiente. Outro ponto fraco é a iluminação realista. O círculo sobreposto simula sombra de forma grosseira. Se o objetivo for um visual cinematográfico com gradiente suave, glow atmosférico e transições de fase lunar, você vai precisar de shaders personalizados ou recorrer a bibliotecas como LÖVE com love.graphics.drawf e texturas pré-renderizadas.
Para projetos que exigem animação fluida da lua subindo e descendo no horizonte, o sistema de coordenadas polares é mais adequado do que mover a lua com funções lineares. Usar seno e cosseno com um ângulo que varia ao longo do tempo produz um arco natural que simula o movimento celeste de forma credível.
Download e próximos passos
O LÖVE é gratuito e open source. Você baixa em love2d.org/downloads e instala o runtime para seu sistema operacional. Os exemplos da comunidade incluem projetos de céu noturno que você pode usar como base. No GitHub, busque por "love2d night sky" ou "love2d stars" para encontrar templates prontos que já vêm com sistema de estrelas, lua e às vezes até aurora boreal. Se o seu objetivo é aprendizado, recomendo modificar o código base primeiro. Mude a quantidade de estrelas, ajuste a cor do fundo para um gradiente (pesquise por love.graphics.setGradient), e tente fazer a lua desaparecer gradualmente saindo da tela. Cada alteração ensina mais do que copiar um projeto pronto.
Se quiser algo mais avançado, dê uma olhada na documentação oficial em love2d.org/wiki. A seção de gráficos cobre todos os modos de desenho, blend modes e o sistema de imagens que você vai precisar quando começar a trabalhar com texturas reais em vez de formas geométricas básicas.
lua e estrelas desenho — resumo prático
O que funciona na prática é manter o código simples nos primeiros dias. Crie o main.lua, ajuste os valores numéricos até a cena ficar visualmente agradável, e só então comece a adicionar complexidade. A maior parte do tempo dos iniciantes é perdida tentando fazer coisas avançadas antes de dominar o básico do loop de renderização e do sistema de cores do LÖVE.