Pular para o conteúdo
Baixar

Jogos em Lua

Ao criar um projeto, você escolhe a linguagem do jogo: Lua ou C++. Em Lua o Play abre o jogo na hora, sem compilar e sem instalar mais nada. É o caminho recomendado para começar.

Cada objeto tem um script ao lado dele: o objeto Jogador usa objects/Jogador.lua. O script define os eventos do objeto como funções que recebem a instância, self:

function onSpawn(self)
self.vidas = 3
end
function onUpdate(self)
self.hspeed = axis("esquerda", "direita") * self.velocidade
if pressed("pular") and self:onGround() then self.vspeed = -4 end
if held("atirar") then spawn("Bala", self.x, self.y, "Instancias") end
end
  • O que é da instância usa self: os campos (self.x, self.hspeed, self.sprite) e os métodos (self:destroy(), self:onCollide(...), self:moveAndStop()).
  • O resto são funções soltas: spawn, count, held, pressed, axis, drawText, goTo, random, e as tabelas Audio, Save, Ui, camera.
  • Você pode guardar o que quiser em self (self.vidas = 3): cada instância tem o seu.
  • As variáveis criadas no Inspetor chegam como campos de self (self.velocidade), já com o valor de cada instância.
  • Uma função do script é chamada pelos outros objetos com dois-pontos: inimigo:levarDano(1).

Os nomes são os mesmos da Referência da API, que mostra os exemplos em C++. Para passar para Lua:

Em C++ Em Lua
hspeed = 2; self.hspeed = 2
destroy(); self:destroy()
spawn<Bala>(x, y, "Instancias"); spawn("Bala", self.x, self.y, "Instancias")
onCollide<Inimigo>([this](Inimigo& outro) { ... }); self:onCollide("Inimigo", function(outro) ... end)
after(60, [this] { ... }); self:after(60, function() ... end)
count<Moeda>() count("Moeda")
Audio::play("tiro", {.volume = 0.4f}); Audio.play("tiro", { volume = 0.4 })
Ui::get("Hud")["Vida"].setValue(0.5f); Ui.get("Hud")["Vida"]:setValue(0.5)
scene().camera.shake(3, 0.2f); camera.shake(3, 0.2)
Save::set("recorde", pontos); Save.set("recorde", pontos)
  • Sequências com espera. Uma ação que acontece aos poucos é escrita em linha reta. wait, waitSteps e waitUntil pausam só a sequência; o jogo continua:
self:run(function()
wait(2) -- 2 segundos
spawn("Chefe", 160, 40, "Instancias")
waitUntil(function() return not any("Chefe") end) -- até o chefe morrer
fadeTo("Vitoria")
end)
  • Tabelas no Save. Save.set("inventario", { "espada", "escudo" }) guarda uma tabela inteira, e Save.get("inventario", {}) devolve.
  • Listas de instâncias. all("Zumbi") devolve a lista, e each("Zumbi", function(z) ... end) passa por todas.
  • Código dividido em arquivos. local jogo = require("src.jogo") carrega src/jogo.lua, bom para o que vale no jogo inteiro (pontos, vidas).

Abrir código (no Inspetor do objeto) abre o script numa aba do próprio editor, com cores e autocompletar: ao digitar self., self: ou Audio. aparece a lista do que existe, com a forma de usar ao lado. Tab ou Enter aceitam a sugestão. O Play grava o que está aberto antes de rodar.

Um erro no script aparece na Saída com o arquivo e a linha; clicar nele leva até lá. O jogo não fecha: o resto continua rodando.

  • Um projeto é em Lua ou em C++: as duas não se misturam.
  • Lua é mais lento que C++ nas contas do próprio script. Num jogo comum isso não aparece: mil objetos com script ocupam cerca de 5% do tempo de um quadro. Só com vários milhares ao mesmo tempo passa a pesar.
  • Um jogo em Lua exportado leva os scripts junto, legíveis, na pasta data.
  • Para projetos em C++, o instalador precisa do Suporte a C++. Veja Instalação.