Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Configurações iniciais
- local tabuleiro = ""
- local jogador_posicao_x = 14 -- Linha do jogador (válido de 1 a 14, pois 0 e 15 são as bordas)
- local jogador_posicao_y = 7 -- Coluna do jogador (válido de 1 a 14)
- local porta_x, porta_y = nil, nil -- A porta só aparece após derrotar os inimigos
- local cenarios = {"🧱", "🏕️", "🏖️", "🏜️", "🏝️", "🏟️", "🏛️", "🌃", "🕌", "️🕋"} -- Símbolos das bordas
- local cenario_atual = 1
- local inimigos = {}
- local obstaculos = {} -- Agora serão preenchidos conforme padrão fixo
- local dificuldade = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50} -- Número de inimigos para cada cenário
- local monster = 0
- local pontuacao = 0
- local vida = 3 -- Internamente usamos um número; na exibição, serão mostrados os corações.
- local level = 1
- local mortes = {} -- Registra as posições dos inimigos derrotados
- ----------------------------------------------------------
- -- Padrão fixo para obstáculos (células interiores: linhas 1 a 14, colunas 1 a 14)
- -- Cada string tem 14 caracteres: "O" representa obstáculo, "." representa célula aberta.
- ----------------------------------------------------------
- local fixedPattern = {
- "..............", -- Linha 1
- "..O..O..O..O..", -- Linha 2
- "..............", -- Linha 3
- "..O..O..O..O..", -- Linha 4
- "..............", -- Linha 5
- "..O..O..O..O..", -- Linha 6
- "..............", -- Linha 7
- "..............", -- Linha 8
- "..O..O..O..O..", -- Linha 9
- "..............", -- Linha 10
- "..O..O..O..O..", -- Linha 11
- "..............", -- Linha 12
- "..O..O..O..O..", -- Linha 13
- ".............." -- Linha 14
- }
- ----------------------------------------------------------
- -- Preenche a tabela "obstaculos" usando o padrão fixo
- ----------------------------------------------------------
- function gerar_obstaculos()
- obstaculos = {}
- for i = 1, 14 do
- local row = fixedPattern[i]
- for j = 1, 14 do
- local ch = row:sub(j, j)
- if ch == "O" then
- table.insert(obstaculos, {x = i, y = j})
- end
- end
- end
- end
- ----------------------------------------------------------
- -- Função para verificar se há um obstáculo em uma dada posição
- ----------------------------------------------------------
- function is_obstaculo_at(x, y)
- for _, o in ipairs(obstaculos) do
- if o.x == x and o.y == y then
- return true
- end
- end
- return false
- end
- ----------------------------------------------------------
- -- Função para verificar se há um inimigo em uma dada posição (opcionalmente excluindo um índice)
- ----------------------------------------------------------
- function is_inimigo_at(x, y, excluir_index)
- for idx, inimigo in ipairs(inimigos) do
- if idx ~= excluir_index and inimigo.x == x and inimigo.y == y then
- return true
- end
- end
- return false
- end
- ----------------------------------------------------------
- -- Função para verificar se existe algum obstáculo entre duas posições (linha ou coluna)
- ----------------------------------------------------------
- function obstaculo_no_caminho(x1, y1, x2, y2)
- for _, o in ipairs(obstaculos) do
- if x1 == x2 and o.x == x1 and o.y > math.min(y1, y2) and o.y < math.max(y1, y2) then
- return true
- elseif y1 == y2 and o.y == y1 and o.x > math.min(x1, x2) and o.x < math.max(x1, x2) then
- return true
- end
- end
- return false
- end
- ----------------------------------------------------------
- -- Função para gerar inimigos aleatórios
- ----------------------------------------------------------
- function gerar_inimigos()
- inimigos = {}
- local quantidade = dificuldade[cenario_atual] or 50
- for i = 1, quantidade do
- local inimigo_x, inimigo_y
- repeat
- inimigo_x = math.random(1, 12) -- posições válidas de 1 a 14 (bordas em 0 e 15)
- inimigo_y = math.random(1, 12)
- until not (inimigo_x == jogador_posicao_x and inimigo_y == jogador_posicao_y)
- and not is_obstaculo_at(inimigo_x, inimigo_y)
- and not is_inimigo_at(inimigo_x, inimigo_y)
- table.insert(inimigos, {x = inimigo_x, y = inimigo_y})
- end
- porta_x, porta_y = nil, nil -- Esconde a porta até eliminar os inimigos
- end
- ----------------------------------------------------------
- -- Função para atualizar a porta (aparece quando todos os inimigos forem derrotados)
- ----------------------------------------------------------
- function atualizar_porta()
- if #inimigos == 0 and not porta_x then
- porta_x, porta_y = 8, 7 -- A porta é exibida na borda esquerda, coluna 7
- end
- end
- ----------------------------------------------------------
- -- Função para mover os inimigos
- -- Os inimigos se movem somente se estiverem alinhados com o jogador, não houver obstáculos no caminho,
- -- e não houver colisão com outro inimigo (exceto se for a primeira a ocupar a célula do jogador).
- ----------------------------------------------------------
- function mover_inimigos()
- for idx, inimigo in ipairs(inimigos) do
- if inimigo.x == jogador_posicao_x and not obstaculo_no_caminho(inimigo.x, inimigo.y, jogador_posicao_x, jogador_posicao_y) then
- local nova_y = inimigo.y
- if inimigo.y < jogador_posicao_y then
- nova_y = inimigo.y + 1
- elseif inimigo.y > jogador_posicao_y then
- nova_y = inimigo.y - 1
- end
- if nova_y == jogador_posicao_y then
- if not is_inimigo_at(inimigo.x, nova_y, idx) then
- inimigo.y = nova_y
- end
- else
- if not is_obstaculo_at(inimigo.x, nova_y) and not is_inimigo_at(inimigo.x, nova_y, idx) then
- inimigo.y = nova_y
- end
- end
- elseif inimigo.y == jogador_posicao_y and not obstaculo_no_caminho(inimigo.x, inimigo.y, jogador_posicao_x, jogador_posicao_y) then
- local nova_x = inimigo.x
- if inimigo.x < jogador_posicao_x then
- nova_x = inimigo.x + 1
- elseif inimigo.x > jogador_posicao_x then
- nova_x = inimigo.x - 1
- end
- if nova_x == jogador_posicao_x then
- if not is_inimigo_at(nova_x, inimigo.y, idx) then
- inimigo.x = nova_x
- end
- else
- if not is_obstaculo_at(nova_x, inimigo.y) and not is_inimigo_at(nova_x, inimigo.y, idx) then
- inimigo.x = nova_x
- end
- end
- end
- end
- end
- ----------------------------------------------------------
- -- Função para desenhar o tabuleiro
- ----------------------------------------------------------
- function desenhar_tabuleiro()
- tabuleiro = ""
- local cor = cenarios[cenario_atual]
- local shooting_trail = {}
- -- Define a trilha de disparo (5 ⚡) se houver um inimigo alinhado com o jogador, a distância for <= 5,
- -- e sem obstáculos no caminho
- for _, inimigo in ipairs(inimigos) do
- if inimigo.x == jogador_posicao_x then
- local distancia = math.abs(inimigo.y - jogador_posicao_y)
- if distancia <= 5 and not obstaculo_no_caminho(jogador_posicao_x, jogador_posicao_y, inimigo.x, inimigo.y) then
- local dir = (inimigo.y > jogador_posicao_y) and 1 or -1
- for i = 1, 5 do
- table.insert(shooting_trail, {x = jogador_posicao_x, y = jogador_posicao_y + i * dir})
- end
- break -- Usa o primeiro inimigo alinhado encontrado
- end
- elseif inimigo.y == jogador_posicao_y then
- local distancia = math.abs(inimigo.x - jogador_posicao_x)
- if distancia <= 5 and not obstaculo_no_caminho(jogador_posicao_x, jogador_posicao_y, inimigo.x, inimigo.y) then
- local dir = (inimigo.x > jogador_posicao_x) and 1 or -1
- for i = 1, 5 do
- table.insert(shooting_trail, {x = jogador_posicao_x + i * dir, y = jogador_posicao_y})
- end
- break
- end
- end
- end
- for i = 0, 15 do
- for j = 0, 15 do
- -- 1. Bordas
- if i == 0 or i == 15 or j == 0 or j == 15 then
- tabuleiro = tabuleiro .. cor
- -- 2. Posição do jogador
- elseif i == jogador_posicao_x and j == jogador_posicao_y then
- tabuleiro = tabuleiro .. "🧕"
- -- 3. Porta
- elseif porta_x and i == porta_x and j == porta_y then
- tabuleiro = tabuleiro .. "️🚩"
- else
- local especial = false
- -- 4. Se houver um inimigo na célula, exibe o inimigo
- for _, inimigo in ipairs(inimigos) do
- if i == inimigo.x and j == inimigo.y then
- tabuleiro = tabuleiro .. "👹"
- especial = true
- break
- end
- end
- if not especial then
- -- 5. Se a célula for um obstáculo fixo (do padrão), exibe 🗿
- if i >= 1 and i <= 14 and j >= 1 and j <= 14 then
- local row = fixedPattern[i]
- local ch = row:sub(j,j)
- if ch == "O" then
- tabuleiro = tabuleiro .. "🗿"
- else
- -- 6. Se a célula fizer parte da trilha de disparo, exibe ⚡
- if (function()
- for _, pos in ipairs(shooting_trail) do
- if pos.x == i and pos.y == j then
- return true
- end
- end
- return false
- end)() then
- tabuleiro = tabuleiro .. "⚡"
- else
- tabuleiro = tabuleiro .. "✔"
- end
- end
- else
- tabuleiro = tabuleiro .. "✔"
- end
- end
- end
- end
- tabuleiro = tabuleiro .. "\n"
- end
- return "Pontuação: " .. pontuacao .. " Nível: " .. level ..
- "\nInimigos Mortos: " .. monster .. " Vidas: " .. string.rep("❤️", vida) .. "\n" .. tabuleiro
- end
- ----------------------------------------------------------
- -- Função para atacar inimigos
- -- O ataque atinge o inimigo em linha reta (mesma linha ou coluna) que esteja mais próximo do jogador,
- -- desde que esteja a no máximo 5 espaços e sem obstáculos no caminho.
- ----------------------------------------------------------
- function atacar()
- local inimigo_alvo = nil
- local distancia_min = math.huge -- Inicializa com um número muito grande
- for _, inimigo in ipairs(inimigos) do
- if inimigo.x == jogador_posicao_x or inimigo.y == jogador_posicao_y then
- local distancia = math.abs(inimigo.x - jogador_posicao_x) + math.abs(inimigo.y - jogador_posicao_y)
- if distancia <= 5 then -- Verifica se o inimigo está no alcance (5 células)
- local bloqueado = false
- if jogador_posicao_x == inimigo.x then
- for _, obstaculo in ipairs(obstaculos) do
- if obstaculo.x == jogador_posicao_x and obstaculo.y > math.min(jogador_posicao_y, inimigo.y) and obstaculo.y < math.max(jogador_posicao_y, inimigo.y) then
- bloqueado = true
- break
- end
- end
- elseif jogador_posicao_y == inimigo.y then
- for _, obstaculo in ipairs(obstaculos) do
- if obstaculo.y == jogador_posicao_y and obstaculo.x > math.min(jogador_posicao_x, inimigo.x) and obstaculo.x < math.max(jogador_posicao_x, inimigo.x) then
- bloqueado = true
- break
- end
- end
- end
- if not bloqueado and distancia < distancia_min then
- distancia_min = distancia
- inimigo_alvo = inimigo
- end
- end
- end
- end
- if inimigo_alvo then
- table.insert(mortes, {x = inimigo_alvo.x, y = inimigo_alvo.y})
- for i = #inimigos, 1, -1 do
- if inimigos[i] == inimigo_alvo then
- table.remove(inimigos, i)
- break
- end
- end
- pontuacao = pontuacao + 150
- monster = monster + 1
- atualizar_porta()
- end
- end
- ----------------------------------------------------------
- -- Função para reiniciar o jogo
- ----------------------------------------------------------
- function resetar_jogo()
- local escolha = gg.choice({"🔄 Reiniciar Jogo", "❌ Sair"}, nil, "O jogo terminou! Deseja reiniciar?")
- if escolha == 1 then
- -- Reseta todas as variáveis do jogo
- jogador_posicao_x, jogador_posicao_y = 14, 7
- porta_x, porta_y = nil, nil
- cenario_atual = 1
- inimigos = {}
- obstaculos = {} -- Será refeito via fixed pattern
- dificuldade = {5, 10, 15, 20, 25, 30, 35, 50}
- monster = 0
- pontuacao = 0
- vida = 3
- mortes = {}
- level = 1
- gg.toast("Jogo reiniciado!")
- jogar() -- Inicia um novo jogo
- else
- gg.toast("Jogo encerrado.")
- end
- end
- ----------------------------------------------------------
- -- Função principal do jogo
- ----------------------------------------------------------
- function jogar()
- gerar_obstaculos() -- Preenche os obstáculos com o padrão fixo
- gerar_inimigos()
- while true do
- local tabuleiro_atual = desenhar_tabuleiro()
- local escolha = gg.choice(
- {
- " ⬆️ Cima\n",
- "\n⬅️ Esquerda\n",
- "\n ➡️ Direita\n",
- "\n ⬇️ Baixo\n",
- "\n 🏹 Atacar\n",
- "❌ Sair"
- },
- nil, tabuleiro_atual)
- -- Movimentação do jogador (não pode atravessar obstáculos fixos)
- if escolha == 1 and jogador_posicao_x > 1 and not is_obstaculo_at(jogador_posicao_x - 1, jogador_posicao_y) then
- jogador_posicao_x = jogador_posicao_x - 1 -- Cima
- elseif escolha == 2 and jogador_posicao_y > 1 and not is_obstaculo_at(jogador_posicao_x, jogador_posicao_y - 1) then
- jogador_posicao_y = jogador_posicao_y - 1 -- Esquerda
- elseif escolha == 3 and jogador_posicao_y < 14 and not is_obstaculo_at(jogador_posicao_x, jogador_posicao_y + 1) then
- jogador_posicao_y = jogador_posicao_y + 1 -- Direita
- elseif escolha == 4 and jogador_posicao_x < 14 and not is_obstaculo_at(jogador_posicao_x + 1, jogador_posicao_y) then
- jogador_posicao_x = jogador_posicao_x + 1 -- Baixo
- elseif escolha == 5 then
- atacar()
- elseif escolha == 6 or escolha == nil then
- gg.toast("Jogo encerrado.")
- break
- end
- mover_inimigos()
- -- Verifica se algum inimigo atingiu o jogador (se estiver na mesma célula)
- for _, inimigo in ipairs(inimigos) do
- if inimigo.x == jogador_posicao_x and inimigo.y == jogador_posicao_y then
- vida = vida - 1
- gg.toast("Você foi atingido! Vidas restantes: " .. string.rep("❤️", vida))
- if vida == 0 then
- gg.toast("Você foi derrotado pelos inimigos!")
- resetar_jogo()
- return
- end
- end
- end
- -- Verifica se o jogador entrou na porta para avançar de cenário
- if porta_x and jogador_posicao_x == porta_x and jogador_posicao_y == porta_y then
- if cenario_atual < #cenarios then
- cenario_atual = cenario_atual + 1
- level = cenario_atual
- jogador_posicao_x, jogador_posicao_y = 14, 7
- mortes = {}
- gerar_obstaculos()
- gerar_inimigos()
- gg.toast("Novo cenário!")
- else
- gg.toast("Você venceu o jogo!")
- resetar_jogo()
- return
- end
- end
- end
- end
- -- Iniciar o jogo
- jogar()
Add Comment
Please, Sign In to add comment