Advertisement
MasterCheats

Mini game Tnque de Batalha GG

Feb 6th, 2025
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 18.65 KB | Gaming | 0 0
  1. ----------------------------------------------------------------
  2. -- CONFIGURAÇÕES INICIAIS
  3. ----------------------------------------------------------------
  4. largura = 16
  5. altura = 16
  6. nivel = 1
  7. pontuacao = 0
  8. vidas = 3
  9. gameOver = false
  10.  
  11. -- Tabelas globais para obstáculos e para a base
  12. obstacles = {}    -- Obstáculos (tijolos destruíveis)
  13.  
  14. ----------------------------------------------------------------
  15. -- DEFINIÇÃO DA BASE PROTETORA
  16. -- A base tem o formato:
  17. --   🧱🧱🧱
  18. --   🧱🌟🧱
  19. --   🧱🧱🧱
  20. ----------------------------------------------------------------
  21. baseCenter = { x = math.floor(largura/2), y = math.floor(altura/2) }
  22. -- A tabela baseCells armazena todas as células que compõem a base.
  23. baseCells = {
  24.     {x = baseCenter.x - 1, y = baseCenter.y - 1},
  25.     {x = baseCenter.x,     y = baseCenter.y - 1},
  26.     {x = baseCenter.x + 1, y = baseCenter.y - 1},
  27.     {x = baseCenter.x - 1, y = baseCenter.y},
  28.     {x = baseCenter.x,     y = baseCenter.y},      -- Centro (🌟)
  29.     {x = baseCenter.x + 1, y = baseCenter.y},
  30.     {x = baseCenter.x - 1, y = baseCenter.y + 1},
  31.     {x = baseCenter.x,     y = baseCenter.y + 1},
  32.     {x = baseCenter.x + 1, y = baseCenter.y + 1}
  33. }
  34.  
  35. ----------------------------------------------------------------
  36. -- FUNÇÃO AUXILIAR: VERIFICA SE A POSIÇÃO (x,y) ESTÁ LIVRE
  37. -- (não ocupada por um obstáculo ou por uma célula da base)
  38. ----------------------------------------------------------------
  39. function posLivre(x, y)
  40.     for _, obs in ipairs(obstacles) do
  41.          if obs.x == x and obs.y == y then return false end
  42.     end
  43.     for _, cell in ipairs(baseCells) do
  44.          if cell.x == x and cell.y == y then return false end
  45.     end
  46.     return true
  47. end
  48.  
  49. ----------------------------------------------------------------
  50. -- FUNÇÃO AUXILIAR: VERIFICA SE A CÉLULA (x,y) FAZ PARTE DA BASE
  51. ----------------------------------------------------------------
  52. function baseContains(x, y)
  53.     for _, cell in ipairs(baseCells) do
  54.          if cell.x == x and cell.y == y then return true end
  55.     end
  56.     return false
  57. end
  58.  
  59. ----------------------------------------------------------------
  60. -- GERAÇÃO DE OBSTÁCULOS (tijolos destruíveis)
  61. ----------------------------------------------------------------
  62. function spawnObstaculos(qtd)
  63.     obstacles = {}
  64.     for i = 1, qtd do
  65.        local ox, oy
  66.        repeat
  67.          ox = math.random(2, largura-1)
  68.          oy = math.random(2, altura-1)
  69.        until posLivre(ox, oy)
  70.        table.insert(obstacles, {x = ox, y = oy})
  71.     end
  72. end
  73. spawnObstaculos(10)
  74.  
  75. ----------------------------------------------------------------
  76. -- DEFINIÇÃO DAS FORMAS DO TANQUE (6 quadrados)
  77. -- O "canhão" é o quadrado de índice 2.
  78. ----------------------------------------------------------------
  79. formas = {
  80.   Cima = {
  81.     {dx = -1, dy =  0},      -- Lado esquerdo
  82.     {dx =  0, dy = -1},      -- CANHÃO (frente)
  83.     {dx =  1, dy =  0},      -- Lado direito
  84.     {dx = -1, dy =  1},      -- Roda esquerda
  85.     {dx =  0, dy =  0},      -- Corpo central
  86.     {dx =  1, dy =  1}       -- Roda direita
  87.   },
  88.   Baixo = {
  89.     {dx =  1, dy =  0},
  90.     {dx =  0, dy =  1},      -- CANHÃO (frente para baixo)
  91.     {dx = -1, dy =  0},
  92.     {dx =  1, dy = -1},
  93.     {dx =  0, dy =  0},
  94.     {dx = -1, dy = -1}
  95.   },
  96.   Direita = {
  97.     {dx =  0, dy = -1},
  98.     {dx =  1, dy =  0},      -- CANHÃO à direita
  99.     {dx =  0, dy =  1},
  100.     {dx = -1, dy = -1},
  101.     {dx =  0, dy =  0},
  102.     {dx = -1, dy =  1}
  103.   },
  104.   Esquerda = {
  105.     {dx =  0, dy =  1},
  106.     {dx = -1, dy =  0},      -- CANHÃO à esquerda
  107.     {dx =  0, dy = -1},
  108.     {dx =  1, dy =  1},
  109.     {dx =  0, dy =  0},
  110.     {dx =  1, dy = -1}
  111.   }
  112. }
  113.  
  114. ----------------------------------------------------------------
  115. -- TANQUE DO JOGADOR (inicia na parte inferior central)
  116. ----------------------------------------------------------------
  117. tanque = {
  118.     pos = {x = math.floor(largura/2), y = altura - 2},
  119.     direcao = "Cima",
  120.     partes = {}
  121. }
  122.  
  123. function atualizarTanque(obj)
  124.   local t = obj or tanque
  125.   t.partes = {}
  126.   local offsets = formas[t.direcao]
  127.   for i, off in ipairs(offsets) do
  128.       table.insert(t.partes, {x = t.pos.x + off.dx, y = t.pos.y + off.dy})
  129.   end
  130. end
  131. atualizarTanque()
  132.  
  133. ----------------------------------------------------------------
  134. -- TANQUES INIMIGOS
  135. ----------------------------------------------------------------
  136. function criarTanqueInimigo(x, y)
  137.     local t = {
  138.         pos = {x = x, y = y},
  139.         direcao = "Cima",
  140.         partes = {}
  141.     }
  142.     atualizarTanque(t)
  143.     return t
  144. end
  145.  
  146. tanqueinimigos = {}
  147. function spawnInimigos(qtd)
  148.     tanqueinimigos = {}
  149.     for i = 1, qtd do
  150.         local ex, ey
  151.         repeat
  152.             ex = math.random(3, largura-3)
  153.             ey = math.random(2, math.floor(altura/2))
  154.         until posLivre(ex, ey)
  155.         table.insert(tanqueinimigos, criarTanqueInimigo(ex, ey))
  156.     end
  157. end
  158. spawnInimigos(nivel + 2)  -- Ex: nível 1 -> 3 inimigos
  159.  
  160. ----------------------------------------------------------------
  161. -- DESENHO DO TABULEIRO
  162. ----------------------------------------------------------------
  163. function desenharTabuleiro()
  164.     local board = ""
  165.     for y = 1, altura do
  166.         for x = 1, largura do
  167.             local celula = "⬛"  -- fundo padrão
  168.  
  169.             -- Se a célula faz parte da base
  170.             local isBase = false
  171.             for _, cell in ipairs(baseCells) do
  172.                 if cell.x == x and cell.y == y then
  173.                     if x == baseCenter.x and y == baseCenter.y then
  174.                         celula = "🌟"
  175.                     else
  176.                         celula = "🧱"
  177.                     end
  178.                     isBase = true
  179.                     break
  180.                 end
  181.             end
  182.  
  183.             if not isBase then
  184.               -- Verifica obstáculos
  185.               for _, obs in ipairs(obstacles) do
  186.                   if obs.x == x and obs.y == y then
  187.                       celula = "🧱"
  188.                       break
  189.                   end
  190.               end
  191.             end
  192.  
  193.             -- Sobrepõe com o jogador (prioridade máxima)
  194.             for _, parte in ipairs(tanque.partes) do
  195.                 if parte.x == x and parte.y == y then
  196.                     celula = "🟩"
  197.                     break
  198.                 end
  199.             end
  200.  
  201.             -- Sobrepõe com os inimigos
  202.             for _, inimigo in ipairs(tanqueinimigos) do
  203.                 for _, parte in ipairs(inimigo.partes) do
  204.                     if parte.x == x and parte.y == y then
  205.                         celula = "🟥"
  206.                         break
  207.                     end
  208.                 end
  209.             end
  210.  
  211.             board = board .. celula
  212.         end
  213.         board = board .. "\n"
  214.     end
  215.     board = board .. "\nVidas: " .. tostring(vidas) .. " | Pontuação: " .. tostring(pontuacao) .. " | Nível: " .. tostring(nivel)
  216.     return board
  217. end
  218.  
  219. ----------------------------------------------------------------
  220. -- FUNÇÃO scanShot: varredura do tiro
  221. -- A partir de (sx, sy) e com vetor (dx, dy) verifica obstáculos,
  222. -- a base e os alvos (inimigo ou jogador), retornando:
  223. --   "obstacle", índice  => tiro atinge obstáculo
  224. --   "base_protect", índice => tiro atinge um tijolo de proteção
  225. --   "base", índice      => tiro atinge o centro da base (se desprotegido)
  226. --   "enemy" ou "player", índice  => alvo atingido
  227. ----------------------------------------------------------------
  228. function scanShot(sx, sy, dx, dy, shooterType)
  229.     local x = sx
  230.     local y = sy
  231.     while x >= 1 and x <= largura and y >= 1 and y <= altura do
  232.          -- Obstáculos
  233.          for i, obs in ipairs(obstacles) do
  234.              if obs.x == x and obs.y == y then
  235.                  return "obstacle", i
  236.              end
  237.          end
  238.          -- Base
  239.          local isBaseCell = false
  240.          local baseIndex = nil
  241.          for j, cell in ipairs(baseCells) do
  242.              if cell.x == x and cell.y == y then
  243.                  isBaseCell = true
  244.                  baseIndex = j
  245.                  break
  246.              end
  247.          end
  248.          if isBaseCell then
  249.              if x == baseCenter.x and y == baseCenter.y then
  250.                  -- É o centro; só pode ser atingido se não houver proteção
  251.                  local protecaoRestante = false
  252.                  for j, cell in ipairs(baseCells) do
  253.                      if not (cell.x == baseCenter.x and cell.y == baseCenter.y) then
  254.                          protecaoRestante = true
  255.                          break
  256.                      end
  257.                  end
  258.                  if protecaoRestante then
  259.                      -- Retorna que atingiu uma proteção (mesmo que não tenha índice definido)
  260.                      return "base_protect", nil
  261.                  else
  262.                      return "base", baseIndex
  263.                  end
  264.              else
  265.                  -- É um tijolo de proteção
  266.                  return "base_protect", baseIndex
  267.              end
  268.          end
  269.          if shooterType == "player" then
  270.              for i, inimigo in ipairs(tanqueinimigos) do
  271.                  for j, parte in ipairs(inimigo.partes) do
  272.                      if parte.x == x and parte.y == y then
  273.                          return "enemy", i
  274.                      end
  275.                  end
  276.              end
  277.          elseif shooterType == "enemy" then
  278.              for j, parte in ipairs(tanque.partes) do
  279.                  if parte.x == x and parte.y == y then
  280.                      return "player", nil
  281.                  end
  282.              end
  283.          end
  284.          x = x + dx
  285.          y = y + dy
  286.     end
  287.     return "none", nil
  288. end
  289.  
  290. ----------------------------------------------------------------
  291. -- DISPARO DO JOGADOR
  292. ----------------------------------------------------------------
  293. function dispararJogador()
  294.     local canhao = tanque.partes[2]  -- o canhão (índice 2)
  295.     local dx, dy = 0, 0
  296.     if tanque.direcao == "Cima" then dx, dy = 0, -1
  297.     elseif tanque.direcao == "Baixo" then dx, dy = 0, 1
  298.     elseif tanque.direcao == "Direita" then dx, dy = 1, 0
  299.     elseif tanque.direcao == "Esquerda" then dx, dy = -1, 0
  300.     end
  301.     local target, index = scanShot(canhao.x, canhao.y, dx, dy, "player")
  302.     if target == "obstacle" then
  303.          table.remove(obstacles, index)
  304.     elseif target == "enemy" then
  305.          pontuacao = (pontuacao or 0) + 100
  306.          table.remove(tanqueinimigos, index)
  307.     elseif target == "base_protect" then
  308.          -- Remove o tijolo de proteção atingido
  309.          if index then
  310.              table.remove(baseCells, index)
  311.          else
  312.              -- Se não tiver índice, procura por algum tijolo (exceto o centro)
  313.              for j, cell in ipairs(baseCells) do
  314.                  if not (cell.x == baseCenter.x and cell.y == baseCenter.y) then
  315.                      table.remove(baseCells, j)
  316.                      break
  317.                  end
  318.              end
  319.          end
  320.     elseif target == "base" then
  321.          gg.alert("Você destruiu a base! Game Over.\nPontuação: " .. tostring(pontuacao))
  322.          os.exit()
  323.     end
  324. end
  325.  
  326. ----------------------------------------------------------------
  327. -- DISPARO DOS INIMIGOS
  328. ----------------------------------------------------------------
  329. function dispararInimigos()
  330.     for _, inimigo in ipairs(tanqueinimigos) do
  331.         local canhaoI = inimigo.partes[2]
  332.         local dx, dy = 0,0
  333.         if inimigo.direcao == "Cima" then dx, dy = 0, -1
  334.         elseif inimigo.direcao == "Baixo" then dx, dy = 0, 1
  335.         elseif inimigo.direcao == "Direita" then dx, dy = 1, 0
  336.         elseif inimigo.direcao == "Esquerda" then dx, dy = -1, 0
  337.         end
  338.         local target, index = scanShot(canhaoI.x, canhaoI.y, dx, dy, "enemy")
  339.         if target == "obstacle" then
  340.             table.remove(obstacles, index)
  341.         elseif target == "base_protect" then
  342.             if index then
  343.                 table.remove(baseCells, index)
  344.             else
  345.                 for j, cell in ipairs(baseCells) do
  346.                     if not (cell.x == baseCenter.x and cell.y == baseCenter.y) then
  347.                         table.remove(baseCells, j)
  348.                         break
  349.                     end
  350.                 end
  351.             end
  352.         elseif target == "base" then
  353.             gg.alert("A base protetora foi destruída! Game Over.\nPontuação: " .. tostring(pontuacao))
  354.             os.exit()
  355.         elseif target == "player" then
  356.             vidas = vidas - 1
  357.             if vidas <= 0 then
  358.                 gg.alert("Você perdeu todas as vidas! Game Over.\nPontuação: " .. tostring(pontuacao))
  359.                 os.exit()
  360.             end
  361.         end
  362.     end
  363. end
  364.  
  365. ----------------------------------------------------------------
  366. -- MOVIMENTAÇÃO DO JOGADOR (somente se todas as células futuras estiverem livres)
  367. ----------------------------------------------------------------
  368. function moverJogador(dx, dy)
  369.     local newPos = { x = tanque.pos.x + dx, y = tanque.pos.y + dy }
  370.     local offsets = formas[tanque.direcao]
  371.     for _, off in ipairs(offsets) do
  372.       local nx = newPos.x + off.dx
  373.       local ny = newPos.y + off.dy
  374.       if nx < 1 or nx > largura or ny < 1 or ny > altura or (not posLivre(nx, ny)) then
  375.          return  -- movimento bloqueado
  376.       end
  377.     end
  378.     tanque.pos = newPos
  379.     atualizarTanque()
  380. end
  381.  
  382. ----------------------------------------------------------------
  383. -- MOVIMENTAÇÃO DOS INIMIGOS (movimento aleatório, se destino estiver livre)
  384. ----------------------------------------------------------------
  385. function moverInimigos()
  386.     local opcoes = {"Cima", "Baixo", "Direita", "Esquerda"}
  387.     for _, inimigo in ipairs(tanqueinimigos) do
  388.        local dir = opcoes[math.random(1, #opcoes)]
  389.        inimigo.direcao = dir
  390.        local dx, dy = 0, 0
  391.        if dir == "Cima" then dy = -1
  392.        elseif dir == "Baixo" then dy = 1
  393.        elseif dir == "Direita" then dx = 1
  394.        elseif dir == "Esquerda" then dx = -1
  395.        end
  396.        local newPos = { x = inimigo.pos.x + dx, y = inimigo.pos.y + dy }
  397.        local canMove = true
  398.        for _, off in ipairs(formas[inimigo.direcao]) do
  399.             local nx = newPos.x + off.dx
  400.             local ny = newPos.y + off.dy
  401.             if nx < 1 or nx > largura or ny < 1 or ny > altura or (not posLivre(nx, ny)) then
  402.                 canMove = false
  403.                 break
  404.             end
  405.        end
  406.        if canMove then
  407.            inimigo.pos = newPos
  408.            atualizarTanque(inimigo)
  409.        end
  410.     end
  411. end
  412.  
  413. ----------------------------------------------------------------
  414. -- CHECA COLISÃO: Se alguma parte do jogador colide com um inimigo
  415. ----------------------------------------------------------------
  416. function checarColisoes()
  417.     for _, parteJ in ipairs(tanque.partes) do
  418.         for _, inimigo in ipairs(tanqueinimigos) do
  419.             for _, parteI in ipairs(inimigo.partes) do
  420.                 if parteJ.x == parteI.x and parteJ.y == parteI.y then
  421.                     return true
  422.                 end
  423.             end
  424.         end
  425.     end
  426.     return false
  427. end
  428.  
  429. ----------------------------------------------------------------
  430. -- MENU DE AÇÕES (via gg.choice)
  431. ----------------------------------------------------------------
  432. function menuAcoes()
  433.     local opcoes = {
  434.         "                              ⬆️ Cima",
  435.         "    ⬅️ Esquerda",
  436.         "                                                      ➡️ Direita",
  437.         "                              ⬇️ Baixo",
  438.         "                              💥 Disparar",
  439.         "                              ❌ Desistir!😪"
  440.     }
  441.     local texto = desenharTabuleiro() .. "\nEscolha uma ação:"
  442.     local escolha = gg.choice(opcoes, nil, texto)
  443.     if escolha == nil then
  444.         gg.setVisible(false)
  445.         return nil
  446.     end
  447.     return escolha
  448. end
  449.  
  450. ----------------------------------------------------------------
  451. -- LOOP PRINCIPAL DO JOGO
  452. ----------------------------------------------------------------
  453. function iniciarJogo()
  454.     while not gameOver do
  455.         -- Se não houver inimigos, o jogador deve proteger/pegar a base
  456.         if #tanqueinimigos == 0 then
  457.             -- A base já está desenhada; o jogador precisa alcançar o centro para avançar.
  458.             for _, parte in ipairs(tanque.partes) do
  459.                 if parte.x == baseCenter.x and parte.y == baseCenter.y then
  460.                     gg.alert("Nível " .. tostring(nivel) .. " concluído!")
  461.                     nivel = nivel + 1
  462.                     if nivel > 5 then
  463.                         gg.alert("Você completou todos os níveis! Parabéns!\nPontuação Final: " .. tostring(pontuacao))
  464.                         os.exit()
  465.                     end
  466.                     -- Reinicia para o novo nível:
  467.                     spawnInimigos(nivel + 2)
  468.                     spawnObstaculos(10)
  469.                     tanque.pos = { x = math.floor(largura/2), y = altura - 2 }
  470.                     atualizarTanque()
  471.                     -- Restaura a base completa
  472.                     baseCells = {
  473.                         {x = baseCenter.x - 1, y = baseCenter.y - 1},
  474.                         {x = baseCenter.x,     y = baseCenter.y - 1},
  475.                         {x = baseCenter.x + 1, y = baseCenter.y - 1},
  476.                         {x = baseCenter.x - 1, y = baseCenter.y},
  477.                         {x = baseCenter.x,     y = baseCenter.y},
  478.                         {x = baseCenter.x + 1, y = baseCenter.y},
  479.                         {x = baseCenter.x - 1, y = baseCenter.y + 1},
  480.                         {x = baseCenter.x,     y = baseCenter.y + 1},
  481.                         {x = baseCenter.x + 1, y = baseCenter.y + 1}
  482.                     }
  483.                     break
  484.                 end
  485.             end
  486.         end
  487.  
  488.         local acao = menuAcoes()
  489.         if acao == nil then break end
  490.         if acao == 1 then
  491.             tanque.direcao = "Cima"
  492.             moverJogador(0, -1)
  493.         elseif acao == 2 then
  494.             tanque.direcao = "Esquerda"
  495.             moverJogador(-1, 0)
  496.         elseif acao == 3 then
  497.             tanque.direcao = "Direita"
  498.             moverJogador(1, 0)
  499.         elseif acao == 4 then
  500.             tanque.direcao = "Baixo"
  501.             moverJogador(0, 1)
  502.         elseif acao == 5 then
  503.             dispararJogador()
  504.         elseif acao == 6 then
  505.             gg.alert("Jogo Finalizado. Pontuação: " .. tostring(pontuacao))
  506.             os.exit()
  507.         end
  508.  
  509.         moverInimigos()
  510.         dispararInimigos()
  511.  
  512.         if checarColisoes() then
  513.             gg.alert("Colisão! Você foi atingido. Game Over.\nPontuação: " .. tostring(pontuacao))
  514.             os.exit()
  515.         end
  516.  
  517.         gg.sleep(100)
  518.     end
  519. end
  520.  
  521. -- Inicia o jogo
  522. iniciarJogo()
  523.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement