🎮ArcadeLab

Lula: Uma Jornada Brasileira

by DriftOtter98
1574 lines59.4 KB
▶ Play
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<title>Lula: Uma Jornada Brasileira</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none; }
  html, body { width: 100%; height: 100%; overflow: hidden; background: #000; font-family: 'Segoe UI', 'Trebuchet MS', sans-serif; touch-action: none; }
  #gameContainer { position: relative; width: 100vw; height: 100vh; background: #1a1a2e; overflow: hidden; display: flex; align-items: center; justify-content: center; }
  canvas { display: block; image-rendering: pixelated; image-rendering: crisp-edges; box-shadow: 0 0 30px rgba(0,0,0,0.5); }
  #gameContainer::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
    background:
      radial-gradient(circle at 20% 30%, rgba(0,156,59,0.15) 0%, transparent 50%),
      radial-gradient(circle at 80% 70%, rgba(0,39,118,0.15) 0%, transparent 50%);
    pointer-events: none;
  }

  /* Tela inicial */
  #startScreen, #factScreen, #winScreen, #gameOverScreen, #levelIntro {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center; z-index: 100; padding: 20px;
  }
  #startScreen { background: linear-gradient(135deg, #009c3b 0%, #ffdf00 50%, #002776 100%); }
  #startScreen h1 { font-size: clamp(28px, 8vw, 64px); color: #fff; text-shadow: 3px 3px 0 #000, -1px -1px 0 #000; margin-bottom: 10px; font-weight: 900; letter-spacing: 2px; }
  #startScreen h2 { font-size: clamp(16px, 4vw, 28px); color: #fff; text-shadow: 2px 2px 0 #000; margin-bottom: 20px; }
  #startScreen p { font-size: clamp(12px, 3vw, 18px); color: #fff; text-shadow: 1px 1px 0 #000; max-width: 600px; margin-bottom: 30px; line-height: 1.6; }
  .btnStart { background: #fff; color: #002776; border: 4px solid #000; padding: 15px 40px; font-size: clamp(16px, 4vw, 24px); font-weight: 900; cursor: pointer; border-radius: 8px; box-shadow: 0 6px 0 #002776; transition: all 0.1s; }
  .btnStart:active { transform: translateY(4px); box-shadow: 0 2px 0 #002776; }

  #levelIntro { background: rgba(0,0,0,0.85); }
  #levelIntro h2 { font-size: clamp(20px, 5vw, 40px); color: #ffdf00; text-shadow: 2px 2px 0 #000; margin-bottom: 15px; }
  #levelIntro p { font-size: clamp(14px, 3.5vw, 20px); color: #fff; max-width: 600px; margin-bottom: 20px; line-height: 1.5; }
  #levelIntro .levelNumber { font-size: clamp(40px, 12vw, 80px); color: #009c3b; font-weight: 900; text-shadow: 3px 3px 0 #fff; }

  #factScreen { background: rgba(0,0,0,0.9); }
  .factBox { background: #ffdf00; border: 5px solid #002776; border-radius: 15px; padding: 25px; max-width: 90%; max-width: 500px; color: #000; box-shadow: 0 8px 0 #002776; }
  .factBox h3 { color: #009c3b; font-size: clamp(20px, 5vw, 32px); margin-bottom: 15px; text-shadow: 1px 1px 0 #000; }
  .factBox p { font-size: clamp(14px, 3.5vw, 18px); line-height: 1.6; margin-bottom: 20px; }
  .factBtn { background: #009c3b; color: #fff; border: 3px solid #000; padding: 12px 30px; font-size: clamp(14px, 3.5vw, 20px); font-weight: 900; border-radius: 8px; cursor: pointer; box-shadow: 0 4px 0 #005020; }
  .factBtn:active { transform: translateY(2px); box-shadow: 0 2px 0 #005020; }

  #winScreen { background: linear-gradient(135deg, #009c3b, #ffdf00, #002776); }
  #winScreen h1 { font-size: clamp(30px, 8vw, 60px); color: #fff; text-shadow: 3px 3px 0 #000; margin-bottom: 20px; }
  #winScreen p { font-size: clamp(14px, 3.5vw, 20px); color: #fff; text-shadow: 1px 1px 0 #000; max-width: 600px; margin-bottom: 25px; line-height: 1.6; }

  #gameOverScreen { background: rgba(0,0,0,0.9); }
  #gameOverScreen h1 { font-size: clamp(30px, 8vw, 60px); color: #ff3333; text-shadow: 3px 3px 0 #000; margin-bottom: 20px; }
  #gameOverScreen p { font-size: clamp(14px, 3.5vw, 20px); color: #fff; margin-bottom: 25px; }

  /* HUD */
  #hud { position: absolute; top: 10px; left: 0; right: 0; padding: 0 15px; display: flex; justify-content: space-between; align-items: center; z-index: 50; pointer-events: none; }
  .hudItem { background: rgba(0,0,0,0.6); color: #fff; padding: 6px 12px; border-radius: 6px; font-size: clamp(12px, 3vw, 16px); font-weight: bold; border: 2px solid #fff; }
  .hudItem.score { color: #ff5555; }

  /* Controles touch - aparecem só em telas pequenas ou dispositivos sem mouse */
  #touchControls { position: absolute; bottom: 0; left: 0; right: 0; height: 140px; display: none; z-index: 40; pointer-events: none; }
  @media (max-width: 900px) { #touchControls { display: block; } }
  @media (hover: none) and (pointer: coarse) { #touchControls { display: block; } }
  .touchBtn { position: absolute; bottom: 30px; width: 70px; height: 70px; border-radius: 50%; background: rgba(255,255,255,0.25); border: 3px solid rgba(255,255,255,0.7); color: #fff; font-size: 32px; font-weight: bold; display: flex; align-items: center; justify-content: center; pointer-events: auto; user-select: none; backdrop-filter: blur(2px); }
  .touchBtn:active { background: rgba(255,255,255,0.55); transform: scale(0.92); }
  #btnLeft { left: 20px; }
  #btnRight { left: 100px; }
  #btnJump { right: 20px; width: 88px; height: 88px; background: rgba(0,156,59,0.45); border-color: rgba(255,255,255,0.9); bottom: 25px; font-size: 38px; }

  /* Tela de girar celular - aparece em mobile portrait */
  #rotateHint {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    background: linear-gradient(135deg, #1a1a2e, #16213e);
    display: none; flex-direction: column; align-items: center; justify-content: center;
    z-index: 1000; text-align: center; padding: 30px; color: #fff;
  }
  #rotateHint .rotateIcon { font-size: 80px; animation: rotateIcon 2s ease-in-out infinite; }
  @keyframes rotateIcon { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(90deg); } }
  #rotateHint h2 { font-size: 22px; margin: 20px 0 10px; color: #ffdf00; }
  #rotateHint p { font-size: 14px; max-width: 300px; line-height: 1.5; opacity: 0.9; }
  @media (max-width: 768px) and (orientation: portrait) { #rotateHint { display: flex; } }
</style>
</head>
<body>
<div id="gameContainer">
  <canvas id="gameCanvas"></canvas>

  <div id="rotateHint">
    <div class="rotateIcon">📱</div>
    <h2>Gire seu celular</h2>
    <p>Para uma melhor experiência de jogo, gire seu aparelho para o modo paisagem (deitado).</p>
  </div>

  <div id="hud" style="display:none;">
    <div class="hudItem" id="levelDisplay">Fase 1</div>
    <div class="hudItem score" id="scoreDisplay">★ 0</div>
    <div class="hudItem" id="livesDisplay">❤ 3</div>
  </div>

  <div id="touchControls">
    <div class="touchBtn" id="btnLeft">◀</div>
    <div class="touchBtn" id="btnRight">▶</div>
    <div class="touchBtn" id="btnJump">↑</div>
  </div>

  <div id="startScreen">
    <h1>LULA</h1>
    <h2>Uma Jornada Brasileira</h2>
    <p>Viva a história de Luiz Inácio Lula da Silva — da infância no sertão de Pernambuco à Presidência da República. Colete estrelas, pule plataformas, enfrente desafios e aprenda fatos sobre um dos líderes mais influentes do Brasil!</p>
    <button class="btnStart" id="startBtn">▶ COMEÇAR</button>
    <p style="margin-top:20px; font-size: 12px; opacity:0.9;">Use as setas / espaço no teclado, ou os botões na tela do celular.</p>
  </div>

  <div id="levelIntro" style="display:none;">
    <div class="levelNumber" id="introNumber">1</div>
    <h2 id="introTitle">Caetés - Pernambuco</h2>
    <p id="introText"></p>
    <button class="btnStart" id="introBtn">COMEÇAR FASE</button>
  </div>

  <div id="factScreen" style="display:none;">
    <div class="factBox">
      <h3 id="factTitle">Você sabia?</h3>
      <p id="factText"></p>
      <button class="factBtn" id="factBtn">CONTINUAR ▶</button>
    </div>
  </div>

  <div id="gameOverScreen" style="display:none;">
    <h1>FIM DE JOGO</h1>
    <p id="gameOverText">Você perdeu todas as vidas. Tente novamente!</p>
    <button class="btnStart" id="retryBtn">↻ TENTAR DE NOVO</button>
  </div>

  <div id="winScreen" style="display:none;">
    <h1>PARABÉNS!</h1>
    <p id="winText"></p>
    <button class="btnStart" id="restartBtn">↻ JOGAR NOVAMENTE</button>
  </div>
</div>

<script>
// ============================================================
// LULA: UMA JORNADA BRASILEIRA - Jogo de plataforma HTML5
// ============================================================

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// Dimensões lógicas do jogo (mundo virtual)
const GAME_WIDTH = 800;
const GAME_HEIGHT = 450;
let scale = 1;
let offsetX = 0;
let offsetY = 0;

// Variáveis do jogo
const GRAVITY = 0.6;
const JUMP_POWER = -12;
const MOVE_SPEED = 3.5;
const FRICTION = 0.85;

let gameState = 'start'; // start, intro, playing, fact, gameover, win
let currentLevel = 0;
let score = 0;
let lives = 3;
let cameraX = 0;
let levelData = null;
let player = null;
let enemies = [];
let collectibles = [];
let platforms = [];
let npcs = [];
let goal = null;
let particles = [];
let collectedStars = 0;
let totalStarsInLevel = 0;
let factsShown = [];

// Controle de input
const keys = { left: false, right: false, jump: false };
let jumpJustPressed = false;

// ============== RESPONSIVE CANVAS ==============
function resize() {
  const container = document.getElementById('gameContainer');
  const w = container.clientWidth;
  const h = container.clientHeight;
  // Ajusta mantendo proporção 16:9
  const targetRatio = GAME_WIDTH / GAME_HEIGHT;
  const screenRatio = w / h;
  let canvasW, canvasH;
  if (screenRatio > targetRatio) {
    canvasH = h;
    canvasW = h * targetRatio;
  } else {
    canvasW = w;
    canvasH = w / targetRatio;
  }
  canvas.style.width = canvasW + 'px';
  canvas.style.height = canvasH + 'px';
  canvas.width = GAME_WIDTH;
  canvas.height = GAME_HEIGHT;
  ctx.imageSmoothingEnabled = false;
}
window.addEventListener('resize', resize);
resize();

// ============== LEVELS ==============
const levels = [
  {
    title: "Caetés - Pernambuco",
    subtitle: "1945 - A Infância no Sertão",
    intro: "Luiz Inácio da Silva nasceu em 27 de outubro de 1945, em Caetés (hoje Garanhuns), no agreste pernambucano. Sétimo de oito filhos, cresceu em profunda pobreza. Ajude o pequeno Lula a atravessar o sertão e coletar livros de escola!",
    bgColor: '#7EC8E3',
    groundColor: '#C19A6B',
    groundTop: '#8B7355',
    width: 3200,
    platforms: [
      {x:0, y:380, w:3200, h:70, type:'ground'},
      {x:300, y:310, w:90, h:20, type:'platform'},
      {x:450, y:280, w:80, h:20, type:'platform'},
      {x:600, y:310, w:80, h:20, type:'platform'},
      {x:750, y:280, w:80, h:20, type:'platform'},
      {x:900, y:300, w:100, h:20, type:'platform'},
      {x:1080, y:270, w:80, h:20, type:'platform'},
      {x:1230, y:300, w:80, h:20, type:'platform'},
      {x:1380, y:260, w:100, h:20, type:'platform'},
      {x:1560, y:300, w:80, h:20, type:'platform'},
      {x:1710, y:270, w:80, h:20, type:'platform'},
      {x:1860, y:300, w:100, h:20, type:'platform'},
      {x:2040, y:260, w:80, h:20, type:'platform'},
      {x:2190, y:300, w:80, h:20, type:'platform'},
      {x:2340, y:270, w:100, h:20, type:'platform'},
      {x:2520, y:300, w:80, h:20, type:'platform'},
      {x:2670, y:260, w:80, h:20, type:'platform'},
      {x:2820, y:300, w:80, h:20, type:'platform'},
      {x:2970, y:270, w:100, h:20, type:'platform'},
    ],
    enemies: [
      {x:500, y:350, range:[450,650], type:'cactus'},
      {x:1200, y:350, range:[1100,1300], type:'cactus'},
      {x:1900, y:350, range:[1800,2000], type:'cactus'},
      {x:2600, y:350, range:[2500,2750], type:'cactus'},
    ],
    collectibles: [
      {x:325, y:265, type:'star'}, {x:475, y:235, type:'star'},
      {x:625, y:265, type:'book'}, {x:775, y:235, type:'star'},
      {x:925, y:255, type:'star'}, {x:1105, y:225, type:'book'},
      {x:1255, y:255, type:'star'}, {x:1405, y:215, type:'book'},
      {x:1585, y:255, type:'star'}, {x:1735, y:225, type:'star'},
      {x:1885, y:255, type:'book'}, {x:2065, y:215, type:'star'},
      {x:2215, y:255, type:'star'}, {x:2365, y:225, type:'book'},
      {x:2545, y:255, type:'star'}, {x:2695, y:215, type:'star'},
      {x:2845, y:255, type:'book'}, {x:2995, y:225, type:'star'},
    ],
    npcs: [
      {x:300, y:340, type:'mother', text:"Mãe Lindu: 'Filho, não tenha vergonha de ser pobre. Trabalhe, leia o que puder, e nunca deixe de aprender com a vida!'"},
      {x:1500, y:340, type:'teacher', text:"Professora: 'A escola abre portas, mas o saber também vem das ruas, das fábricas e das conversas de quem vive.'"},
    ],
    facts: [
      "Lula nasceu em 27 de outubro de 1945 em Caetés, Pernambuco. Era o sétimo de oito filhos de Eurídice Ferreira de Melo (Dona Lindu) e Aristides Inácio da Silva.",
      "O apelido 'Lula' vem de 'Luís', como era chamado na infância. Mais tarde, ao registrar o nome para candidato, adotou oficialmente 'Lula' como parte do nome.",
      "Antes de aprender a ler, Lula vendia laranjas, amendoim e castanhas nas ruas para ajudar a família. Aprendeu muito cedo que o trabalho e a vivência ensinam o que nenhum livro ensina."
    ]
  },
  {
    title: "A Grande Viagem",
    subtitle: "1952 - Migração para São Paulo",
    intro: "Em 1952, com apenas 7 anos, Lula viajou com a mãe e os irmãos durante 23 dias de pau-de-arara até São Paulo, para reencontrar o pai. Atravesse os obstáculos dessa longa jornada!",
    bgColor: '#FFA07A',
    groundColor: '#8B4513',
    groundTop: '#CD853F',
    width: 3400,
    platforms: [
      {x:0, y:380, w:3400, h:70, type:'ground'},
      {x:280, y:310, w:80, h:20, type:'platform'},
      {x:430, y:280, w:80, h:20, type:'platform'},
      {x:580, y:310, w:80, h:20, type:'platform'},
      {x:730, y:270, w:80, h:20, type:'platform'},
      {x:880, y:300, w:80, h:20, type:'platform'},
      {x:1030, y:260, w:80, h:20, type:'platform'},
      {x:1180, y:300, w:100, h:20, type:'platform'},
      {x:1360, y:260, w:80, h:20, type:'platform'},
      {x:1510, y:300, w:80, h:20, type:'platform'},
      {x:1660, y:270, w:80, h:20, type:'platform'},
      {x:1810, y:300, w:100, h:20, type:'platform'},
      {x:1990, y:260, w:80, h:20, type:'platform'},
      {x:2140, y:300, w:80, h:20, type:'platform'},
      {x:2290, y:260, w:80, h:20, type:'platform'},
      {x:2440, y:300, w:100, h:20, type:'platform'},
      {x:2620, y:260, w:80, h:20, type:'platform'},
      {x:2770, y:300, w:80, h:20, type:'platform'},
      {x:2920, y:260, w:80, h:20, type:'platform'},
      {x:3070, y:300, w:100, h:20, type:'platform'},
      {x:3250, y:270, w:100, h:20, type:'platform'},
    ],
    enemies: [
      {x:550, y:350, range:[500,700], type:'truck'},
      {x:1300, y:350, range:[1250,1400], type:'truck'},
      {x:2200, y:350, range:[2150,2350], type:'truck'},
      {x:2900, y:350, range:[2850,3000], type:'truck'},
    ],
    collectibles: [
      {x:305, y:265, type:'star'}, {x:455, y:235, type:'star'},
      {x:605, y:265, type:'book'}, {x:755, y:225, type:'star'},
      {x:905, y:255, type:'star'}, {x:1055, y:215, type:'book'},
      {x:1205, y:255, type:'star'}, {x:1385, y:215, type:'book'},
      {x:1535, y:255, type:'star'}, {x:1685, y:225, type:'star'},
      {x:1835, y:255, type:'book'}, {x:2015, y:215, type:'star'},
      {x:2165, y:255, type:'star'}, {x:2315, y:215, type:'book'},
      {x:2465, y:255, type:'star'}, {x:2645, y:215, type:'star'},
      {x:2795, y:255, type:'book'}, {x:2945, y:215, type:'star'},
      {x:3095, y:255, type:'star'}, {x:3275, y:225, type:'book'},
    ],
    npcs: [
      {x:200, y:340, type:'mother', text:"Mãe Lindu: 'Vamos, filhos! Em São Paulo teremos uma vida melhor.'"},
      {x:1800, y:340, type:'driver', text:"Motorista: 'Pau-de-arava' - 23 dias de viagem até São Paulo!"},
    ],
    facts: [
      "Em dezembro de 1952, Lula, sua mãe Dona Lindu e os irmãos viajaram 23 dias no pau-de-arara (caminhão) de Pernambuco até o litoral de São Paulo.",
      "Dona Lindu decidiu migrar para reencontrar o marido Aristides, que havia saído de Pernambuco antes para trabalhar no litoral paulista.",
      "A família se instalou em Vicente de Carvalho, bairro pobre de Guarujá. Lula aprendeu a ler aos 10 anos e, desde cedo, somou estudo, trabalho e observação da vida ao seu redor."
    ]
  },
  {
    title: "O Metalúrgico",
    subtitle: "Anos 60 - Trabalho nas Fábricas",
    intro: "Em São Bernardo do Campo, Lula trabalhou como office-boy, engraxate e finalmente metalúrgico. Aos 19 anos, perdeu o dedo mínimo num acidente de trabalho. Colete ferramentas e evite os perigos da fábrica!",
    bgColor: '#708090',
    groundColor: '#696969',
    groundTop: '#A9A9A9',
    bgType: 'industrial',
    width: 3600,
    platforms: [
      {x:0, y:380, w:3600, h:70, type:'ground'},
      {x:280, y:310, w:90, h:20, type:'platform'},
      {x:430, y:280, w:80, h:20, type:'platform'},
      {x:580, y:310, w:80, h:20, type:'platform'},
      {x:730, y:270, w:80, h:20, type:'platform'},
      {x:880, y:300, w:90, h:20, type:'platform'},
      {x:1050, y:260, w:80, h:20, type:'platform'},
      {x:1200, y:300, w:80, h:20, type:'platform'},
      {x:1350, y:260, w:100, h:20, type:'platform'},
      {x:1530, y:300, w:80, h:20, type:'platform'},
      {x:1680, y:270, w:80, h:20, type:'platform'},
      {x:1830, y:300, w:100, h:20, type:'platform'},
      {x:2010, y:260, w:80, h:20, type:'platform'},
      {x:2160, y:300, w:80, h:20, type:'platform'},
      {x:2310, y:270, w:100, h:20, type:'platform'},
      {x:2490, y:300, w:80, h:20, type:'platform'},
      {x:2640, y:260, w:80, h:20, type:'platform'},
      {x:2790, y:300, w:80, h:20, type:'platform'},
      {x:2940, y:260, w:100, h:20, type:'platform'},
      {x:3120, y:300, w:80, h:20, type:'platform'},
      {x:3270, y:270, w:100, h:20, type:'platform'},
      {x:3450, y:300, w:100, h:20, type:'platform'},
    ],
    enemies: [
      {x:600, y:350, range:[550,750], type:'machine'},
      {x:1300, y:350, range:[1250,1400], type:'machine'},
      {x:2000, y:350, range:[1950,2150], type:'machine'},
      {x:2700, y:350, range:[2650,2850], type:'machine'},
      {x:3300, y:350, range:[3250,3450], type:'machine'},
    ],
    collectibles: [
      {x:310, y:265, type:'tool'}, {x:460, y:235, type:'star'},
      {x:610, y:265, type:'tool'}, {x:760, y:225, type:'star'},
      {x:910, y:255, type:'tool'}, {x:1080, y:215, type:'star'},
      {x:1230, y:255, type:'tool'}, {x:1380, y:215, type:'star'},
      {x:1555, y:255, type:'tool'}, {x:1705, y:225, type:'star'},
      {x:1855, y:255, type:'tool'}, {x:2035, y:215, type:'star'},
      {x:2185, y:255, type:'tool'}, {x:2335, y:225, type:'star'},
      {x:2515, y:255, type:'tool'}, {x:2665, y:215, type:'star'},
      {x:2815, y:255, type:'tool'}, {x:2965, y:215, type:'star'},
      {x:3145, y:255, type:'tool'}, {x:3295, y:225, type:'star'},
      {x:3475, y:255, type:'tool'},
    ],
    npcs: [
      {x:300, y:340, type:'worker', text:"Instrutor do SENAI: 'Aqui você aprende um ofício. Torneiro mecânico é ofício de quem trabalha com a mão e com a cabeça!'"},
      {x:2200, y:340, type:'doctor', text:"Médico: 'Em 1964, Lula perdeu o dedo mínimo num acidente na fábrica. Aquilo o marcou e o fez entender que o trabalhador precisava de direitos.'"},
    ],
    facts: [
      "Em São Bernardo do Campo, Lula trabalhou como engraxate, office-boy e aprendiz de torneiro mecânico. Formou-se torneiro mecânico pelo SENAI em 1963 — um curso técnico que abriu suas primeiras portas no mundo do trabalho.",
      "Sua formação política veio de leituras, conversas com colegas operários, sindicalistas e intelectuais que se aproximaram dele ao longo dos anos.",
      "Em 1964, aos 19 anos, Lula sofreu um acidente de trabalho que amputou seu dedo mínimo esquerdo. Sem proteção trabalhista, percebeu que só a organização coletiva poderia mudar isso."
    ]
  },
  {
    title: "Líder Sindical",
    subtitle: "1970s - As Grandes Greves do ABC",
    intro: "Nos anos 70, Lula liderou as maiores greves da história do Brasil, enfrentando a ditadura militar. Conduza o líder operário pelas fábricas e organize os trabalhadores!",
    bgColor: '#B0C4DE',
    groundColor: '#4A4A4A',
    groundTop: '#6B6B6B',
    bgType: 'industrial',
    width: 3800,
    platforms: [
      {x:0, y:380, w:3800, h:70, type:'ground'},
      {x:280, y:310, w:80, h:20, type:'platform'},
      {x:430, y:280, w:80, h:20, type:'platform'},
      {x:580, y:310, w:80, h:20, type:'platform'},
      {x:730, y:270, w:80, h:20, type:'platform'},
      {x:880, y:300, w:100, h:20, type:'platform'},
      {x:1060, y:260, w:80, h:20, type:'platform'},
      {x:1210, y:300, w:80, h:20, type:'platform'},
      {x:1360, y:260, w:100, h:20, type:'platform'},
      {x:1540, y:300, w:80, h:20, type:'platform'},
      {x:1690, y:270, w:80, h:20, type:'platform'},
      {x:1840, y:300, w:100, h:20, type:'platform'},
      {x:2020, y:260, w:80, h:20, type:'platform'},
      {x:2170, y:300, w:80, h:20, type:'platform'},
      {x:2320, y:270, w:100, h:20, type:'platform'},
      {x:2500, y:300, w:80, h:20, type:'platform'},
      {x:2650, y:260, w:80, h:20, type:'platform'},
      {x:2800, y:300, w:80, h:20, type:'platform'},
      {x:2950, y:260, w:100, h:20, type:'platform'},
      {x:3130, y:300, w:80, h:20, type:'platform'},
      {x:3280, y:270, w:80, h:20, type:'platform'},
      {x:3430, y:300, w:80, h:20, type:'platform'},
      {x:3580, y:270, w:140, h:20, type:'platform'},
    ],
    enemies: [
      {x:500, y:350, range:[450,600], type:'soldier'},
      {x:1100, y:350, range:[1050,1200], type:'soldier'},
      {x:1700, y:350, range:[1650,1850], type:'soldier'},
      {x:2300, y:350, range:[2250,2400], type:'soldier'},
      {x:2900, y:350, range:[2850,3000], type:'soldier'},
      {x:3400, y:350, range:[3350,3500], type:'soldier'},
    ],
    collectibles: [
      {x:305, y:265, type:'megaphone'}, {x:455, y:235, type:'star'},
      {x:605, y:265, type:'megaphone'}, {x:755, y:225, type:'star'},
      {x:905, y:255, type:'megaphone'}, {x:1090, y:215, type:'star'},
      {x:1240, y:255, type:'megaphone'}, {x:1390, y:215, type:'star'},
      {x:1565, y:255, type:'megaphone'}, {x:1715, y:225, type:'star'},
      {x:1865, y:255, type:'megaphone'}, {x:2045, y:215, type:'star'},
      {x:2195, y:255, type:'megaphone'}, {x:2345, y:225, type:'star'},
      {x:2525, y:255, type:'megaphone'}, {x:2675, y:215, type:'star'},
      {x:2825, y:255, type:'megaphone'}, {x:2975, y:215, type:'star'},
      {x:3155, y:255, type:'megaphone'}, {x:3305, y:225, type:'star'},
      {x:3455, y:255, type:'megaphone'}, {x:3605, y:225, type:'star'},
    ],
    npcs: [
      {x:250, y:340, type:'worker', text:"Operário: 'Lula, fale por nós! Não aguentamos mais!'"},
      {x:2400, y:340, type:'journalist', text:"Jornalista: 'Em 1979, 170 mil metalúrgicos pararam o ABC!'"},
    ],
    facts: [
      "Em 1975, Lula foi eleito presidente do Sindicato dos Metalúrgicos de São Bernardo do Campo e Diadema, com 92% dos votos.",
      "Lula estudava política, história e direito sindical por conta própria. Lia jornais, livros e debatia com intelectuais — sua outra universidade foi o movimento operário.",
      "Preso em 1980 pela Lei de Segurança Nacional, Lula ficou 31 dias detido. O movimento internacional pressionou o regime pela sua libertação."
    ]
  },
  {
    title: "Fundação do PT",
    subtitle: "1980 - O Partido dos Trabalhadores",
    intro: "Em 10 de fevereiro de 1980, Lula ajudou a fundar o Partido dos Trabalhadores (PT), unindo operários, intelectuais e movimentos sociais. Conduza o movimento pela democracia!",
    bgColor: '#FF6347',
    groundColor: '#8B4513',
    groundTop: '#D2691E',
    width: 4000,
    platforms: [
      {x:0, y:380, w:4000, h:70, type:'ground'},
      {x:280, y:310, w:90, h:20, type:'platform'},
      {x:430, y:280, w:80, h:20, type:'platform'},
      {x:580, y:310, w:80, h:20, type:'platform'},
      {x:730, y:270, w:80, h:20, type:'platform'},
      {x:880, y:300, w:90, h:20, type:'platform'},
      {x:1050, y:260, w:80, h:20, type:'platform'},
      {x:1200, y:300, w:80, h:20, type:'platform'},
      {x:1350, y:260, w:100, h:20, type:'platform'},
      {x:1530, y:300, w:80, h:20, type:'platform'},
      {x:1680, y:270, w:80, h:20, type:'platform'},
      {x:1830, y:300, w:100, h:20, type:'platform'},
      {x:2010, y:260, w:80, h:20, type:'platform'},
      {x:2160, y:300, w:80, h:20, type:'platform'},
      {x:2310, y:270, w:100, h:20, type:'platform'},
      {x:2490, y:300, w:80, h:20, type:'platform'},
      {x:2640, y:260, w:80, h:20, type:'platform'},
      {x:2790, y:300, w:80, h:20, type:'platform'},
      {x:2940, y:260, w:100, h:20, type:'platform'},
      {x:3120, y:300, w:80, h:20, type:'platform'},
      {x:3270, y:270, w:80, h:20, type:'platform'},
      {x:3420, y:300, w:80, h:20, type:'platform'},
      {x:3570, y:270, w:80, h:20, type:'platform'},
      {x:3720, y:300, w:140, h:20, type:'platform'},
    ],
    enemies: [
      {x:500, y:350, range:[450,600], type:'soldier'},
      {x:1100, y:350, range:[1050,1200], type:'soldier'},
      {x:1700, y:350, range:[1650,1850], type:'soldier'},
      {x:2400, y:350, range:[2350,2500], type:'soldier'},
      {x:3000, y:350, range:[2950,3100], type:'soldier'},
      {x:3500, y:350, range:[3450,3600], type:'soldier'},
    ],
    collectibles: [
      {x:310, y:265, type:'flag'}, {x:460, y:235, type:'star'},
      {x:610, y:265, type:'flag'}, {x:760, y:225, type:'star'},
      {x:910, y:255, type:'flag'}, {x:1080, y:215, type:'star'},
      {x:1230, y:255, type:'flag'}, {x:1380, y:215, type:'star'},
      {x:1555, y:255, type:'flag'}, {x:1705, y:225, type:'star'},
      {x:1855, y:255, type:'flag'}, {x:2035, y:215, type:'star'},
      {x:2185, y:255, type:'flag'}, {x:2335, y:225, type:'star'},
      {x:2515, y:255, type:'flag'}, {x:2665, y:215, type:'star'},
      {x:2815, y:255, type:'flag'}, {x:2965, y:215, type:'star'},
      {x:3145, y:255, type:'flag'}, {x:3295, y:225, type:'star'},
      {x:3445, y:255, type:'flag'}, {x:3595, y:225, type:'star'},
      {x:3745, y:255, type:'flag'},
    ],
    npcs: [
      {x:300, y:340, type:'intellectual', text:"Intelectual: 'Vamos criar um partido dos trabalhadores, sem patrões no comando!'"},
      {x:2500, y:340, type:'worker', text:"Operário: 'PT nasceu da luta real do povo brasileiro!'"},
    ],
    facts: [
      "Em 10 de fevereiro de 1980, cerca de 1,5 mil pessoas reunidas no Colégio Sion, em São Paulo, fundaram o Partido dos Trabalhadores (PT).",
      "O PT nasceu como partido de massas, unindo operários e intelectuais, sindicatos, movimentos sociais e cristãos progressistas ligados à Teologia da Libertação.",
      "Lula se candidatou a presidente em 1982, 1989, 1994, 1998, 2002, 2006, 2018 e 2022 — vencendo em 2002, 2006 e 2022."
    ]
  },
  {
    title: "Presidente do Brasil",
    subtitle: "2003 e 2023 - Liderando a Nação",
    intro: "Lula se tornou presidente do Brasil em 1º de janeiro de 2003 e novamente em 2023. Implementou programas como Bolsa Família, Fome Zero e Minha Casa Minha Vida. Leve o Brasil à bandeira final!",
    bgColor: '#87CEEB',
    groundColor: '#228B22',
    groundTop: '#32CD32',
    width: 4200,
    platforms: [
      {x:0, y:380, w:4200, h:70, type:'ground'},
      {x:280, y:310, w:100, h:20, type:'platform'},
      {x:430, y:280, w:80, h:20, type:'platform'},
      {x:580, y:310, w:80, h:20, type:'platform'},
      {x:730, y:270, w:80, h:20, type:'platform'},
      {x:880, y:300, w:100, h:20, type:'platform'},
      {x:1060, y:260, w:80, h:20, type:'platform'},
      {x:1210, y:300, w:80, h:20, type:'platform'},
      {x:1360, y:260, w:100, h:20, type:'platform'},
      {x:1540, y:300, w:80, h:20, type:'platform'},
      {x:1690, y:270, w:80, h:20, type:'platform'},
      {x:1840, y:300, w:100, h:20, type:'platform'},
      {x:2020, y:260, w:80, h:20, type:'platform'},
      {x:2170, y:300, w:80, h:20, type:'platform'},
      {x:2320, y:270, w:100, h:20, type:'platform'},
      {x:2500, y:300, w:80, h:20, type:'platform'},
      {x:2650, y:260, w:80, h:20, type:'platform'},
      {x:2800, y:300, w:80, h:20, type:'platform'},
      {x:2950, y:260, w:100, h:20, type:'platform'},
      {x:3130, y:300, w:80, h:20, type:'platform'},
      {x:3280, y:270, w:80, h:20, type:'platform'},
      {x:3430, y:300, w:80, h:20, type:'platform'},
      {x:3580, y:260, w:80, h:20, type:'platform'},
      {x:3730, y:290, w:80, h:20, type:'platform'},
      {x:3880, y:260, w:140, h:20, type:'platform'},
    ],
    enemies: [
      {x:500, y:350, range:[450,600], type:'corruption'},
      {x:1100, y:350, range:[1050,1200], type:'corruption'},
      {x:1700, y:350, range:[1650,1850], type:'corruption'},
      {x:2400, y:350, range:[2350,2500], type:'corruption'},
      {x:3000, y:350, range:[2950,3100], type:'corruption'},
      {x:3500, y:350, range:[3450,3600], type:'corruption'},
    ],
    collectibles: [
      {x:310, y:265, type:'house'}, {x:460, y:235, type:'star'},
      {x:610, y:265, type:'house'}, {x:760, y:225, type:'star'},
      {x:910, y:255, type:'bolsa'}, {x:1080, y:215, type:'star'},
      {x:1230, y:255, type:'house'}, {x:1380, y:215, type:'bolsa'},
      {x:1555, y:255, type:'star'}, {x:1705, y:225, type:'house'},
      {x:1855, y:255, type:'bolsa'}, {x:2035, y:215, type:'star'},
      {x:2185, y:255, type:'house'}, {x:2335, y:225, type:'bolsa'},
      {x:2515, y:255, type:'star'}, {x:2665, y:215, type:'house'},
      {x:2815, y:255, type:'bolsa'}, {x:2965, y:215, type:'star'},
      {x:3145, y:255, type:'house'}, {x:3295, y:225, type:'bolsa'},
      {x:3445, y:255, type:'star'}, {x:3595, y:215, type:'house'},
      {x:3745, y:245, type:'bolsa'}, {x:3900, y:215, type:'star'},
    ],
    npcs: [
      {x:300, y:340, type:'citizen', text:"Cidadã: 'Bolsa Família mudou minha vida! Meus filhos podem estudar!'"},
      {x:2500, y:340, type:'citizen', text:"Cidadão: 'Minha Casa Minha Vida me deu teto próprio!'"},
      {x:3800, y:340, type:'citizen', text:"Cidadão mundial: 'Lula é um símbolo global da luta contra a fome!'"},
    ],
    facts: [
      "Como presidente (2003-2010), Lula implementou o Fome Zero e o Bolsa Família, tirando milhões de brasileiros da miséria extrema.",
      "Sob o governo Lula, o Brasil criou o Minha Casa Minha Vida, o PROUNI e ampliou o acesso ao ensino superior — abrindo a universidade para os filhos dos trabalhadores.",
      "Em 2022, Lula se tornou o primeiro brasileiro eleito presidente por três vezes (2002, 2006 e 2022). Voltou ao cargo em 1º de janeiro de 2023."
    ]
  }
];

// ============== PLAYER ==============
function createPlayer(x, y) {
  return {
    x: x, y: y,
    vx: 0, vy: 0,
    width: 24, height: 36,
    onGround: false,
    facing: 1,
    animFrame: 0,
    animTimer: 0,
    invulnerable: 0,
  };
}

// ============== LEVEL LOADER ==============
function loadLevel(levelIndex) {
  currentLevel = levelIndex;
  const lv = levels[levelIndex];
  levelData = lv;
  cameraX = 0;
  factsShown = [];

  platforms = lv.platforms.map(p => ({...p}));
  enemies = lv.enemies.map(e => ({...e, alive: true, dir: 1, speed: 0.8 + Math.random() * 0.4}));
  collectibles = lv.collectibles.map(c => ({...c, collected: false}));
  npcs = lv.npcs.map(n => ({...n, talked: false}));
  goal = {x: lv.width - 180, y: 200, w: 80, h: 180};

  totalStarsInLevel = collectibles.length;
  collectedStars = 0;
  particles = [];
  floatingTexts = [];

  player = createPlayer(60, 300);

  document.getElementById('levelDisplay').textContent = 'Fase ' + (levelIndex + 1);
  document.getElementById('introNumber').textContent = levelIndex + 1;
  document.getElementById('introTitle').textContent = lv.title;
  document.getElementById('introText').textContent = lv.intro;
  showScreen('levelIntro');
}

// ============== SCREEN MANAGEMENT ==============
function showScreen(name) {
  ['startScreen', 'levelIntro', 'factScreen', 'winScreen', 'gameOverScreen'].forEach(s => {
    document.getElementById(s).style.display = 'none';
  });
  if (name !== 'game') {
    document.getElementById(name).style.display = 'flex';
    document.getElementById('hud').style.display = 'none';
  } else {
    document.getElementById('hud').style.display = 'flex';
  }
}

function showFact(index) {
  if (index >= levelData.facts.length) {
    // Todos os fatos foram exibidos — avança para próxima fase ou vitória
    if (currentLevel < levels.length - 1) {
      loadLevel(currentLevel + 1);
    } else {
      // Última fase concluída!
      gameState = 'win';
      document.getElementById('winText').textContent =
        'Você completou a jornada de Luiz Inácio Lula da Silva — da infância no sertão ' +
        'de Pernambuco à Presidência da República! Pontuação final: ' + score + '. ' +
        'Lula é um dos líderes mais influentes da história do Brasil, tendo sido eleito ' +
        'presidente por três vezes (2002, 2006 e 2022). Sua história mostra que o saber ' +
        'vem de muitas fontes: a escola, o trabalho manual, a leitura, a vivência sindical ' +
        'e a organização coletiva. Com coragem, persistência e diálogo, é possível ' +
        'transformar não apenas a própria vida, mas o país inteiro.';
      showScreen('winScreen');
    }
    return;
  }
  const isLast = index === levelData.facts.length - 1;
  document.getElementById('factTitle').textContent = 'Você sabia?';
  document.getElementById('factText').textContent = levelData.facts[index];
  document.getElementById('factBtn').textContent = isLast
    ? (currentLevel < levels.length - 1 ? 'PRÓXIMA FASE ▶' : 'CONCLUIR JORNADA ▶')
    : 'CONTINUAR ▶';
  document.getElementById('factBtn').onclick = () => {
    document.getElementById('factScreen').style.display = 'none';
    showFact(index + 1);
  };
  gameState = 'fact';
  document.getElementById('factScreen').style.display = 'flex';
  document.getElementById('hud').style.display = 'none';
}

// ============== INPUT ==============
document.addEventListener('keydown', e => {
  if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') keys.left = true;
  if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') keys.right = true;
  if (e.key === ' ' || e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W' || e.key === 'z' || e.key === 'Z') {
    if (!keys.jump) jumpJustPressed = true;
    keys.jump = true;
    e.preventDefault();
  }
});
document.addEventListener('keyup', e => {
  if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') keys.left = false;
  if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') keys.right = false;
  if (e.key === ' ' || e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W' || e.key === 'z' || e.key === 'Z') keys.jump = false;
});

// Touch controls
function bindTouch(elId, key) {
  const el = document.getElementById(elId);
  el.addEventListener('touchstart', e => { e.preventDefault(); keys[key] = true; if (key === 'jump') jumpJustPressed = true; }, {passive:false});
  el.addEventListener('touchend', e => { e.preventDefault(); keys[key] = false; }, {passive:false});
  el.addEventListener('touchcancel', e => { e.preventDefault(); keys[key] = false; }, {passive:false});
  el.addEventListener('mousedown', e => { e.preventDefault(); keys[key] = true; if (key === 'jump') jumpJustPressed = true; });
  el.addEventListener('mouseup', e => { e.preventDefault(); keys[key] = false; });
  el.addEventListener('mouseleave', e => { keys[key] = false; });
}
bindTouch('btnLeft', 'left');
bindTouch('btnRight', 'right');
bindTouch('btnJump', 'jump');

// ============== BUTTONS ==============
document.getElementById('startBtn').onclick = () => {
  score = 0;
  lives = 3;
  loadLevel(0);
};
document.getElementById('introBtn').onclick = () => {
  gameState = 'playing';
  showScreen('game');
  updateHUD();
};
document.getElementById('retryBtn').onclick = () => {
  lives = 3;
  score = 0;
  loadLevel(0);
};
document.getElementById('restartBtn').onclick = () => {
  lives = 3;
  score = 0;
  loadLevel(0);
};

// ============== UPDATE HUD ==============
function updateHUD() {
  document.getElementById('scoreDisplay').textContent = '★ ' + score;
  document.getElementById('livesDisplay').textContent = '❤ ' + lives;
  document.getElementById('levelDisplay').textContent = 'Fase ' + (currentLevel + 1);
}

// ============== PHYSICS & UPDATE ==============
function update() {
  if (gameState !== 'playing') return;

  // Player movement
  if (keys.left) { player.vx -= 0.5; player.facing = -1; }
  if (keys.right) { player.vx += 0.5; player.facing = 1; }
  player.vx *= FRICTION;
  if (Math.abs(player.vx) > MOVE_SPEED) player.vx = MOVE_SPEED * Math.sign(player.vx);
  if (Math.abs(player.vx) < 0.1) player.vx = 0;

  if (jumpJustPressed && player.onGround) {
    player.vy = JUMP_POWER;
    player.onGround = false;
  }
  jumpJustPressed = false;

  player.vy += GRAVITY;
  if (player.vy > 15) player.vy = 15;

  // Move X
  player.x += player.vx;
  if (player.x < 0) player.x = 0;
  if (player.x + player.width > levelData.width) player.x = levelData.width - player.width;

  // Collide X
  for (const p of platforms) {
    if (rectOverlap(player, p)) {
      if (player.vx > 0) player.x = p.x - player.width;
      else if (player.vx < 0) player.x = p.x + p.w;
      player.vx = 0;
    }
  }

  // Move Y
  player.y += player.vy;
  player.onGround = false;

  // Collide Y
  for (const p of platforms) {
    if (rectOverlap(player, p)) {
      if (player.vy > 0) {
        player.y = p.y - player.height;
        player.vy = 0;
        player.onGround = true;
      } else if (player.vy < 0) {
        player.y = p.y + p.h;
        player.vy = 0;
      }
    }
  }

  // Anim
  player.animTimer++;
  if (player.animTimer > 6) {
    player.animTimer = 0;
    player.animFrame = (player.animFrame + 1) % 4;
  }

  if (player.invulnerable > 0) player.invulnerable--;

  // Fall off the world
  if (player.y > GAME_HEIGHT + 100) {
    damagePlayer();
  }

  // Update enemies
  for (const e of enemies) {
    if (!e.alive) continue;
    e.x += e.dir * e.speed;
    if (e.x < e.range[0]) { e.x = e.range[0]; e.dir = 1; }
    if (e.x > e.range[1]) { e.x = e.range[1]; e.dir = -1; }

    // Collision with player
    const enemyRect = {x: e.x, y: e.y, w: 36, h: 36};
    if (player.invulnerable === 0 && rectOverlap(player, enemyRect)) {
      // Stomp check
      if (player.vy > 0 && player.y + player.height < e.y + 18) {
        e.alive = false;
        player.vy = JUMP_POWER * 0.6;
        score += 50;
        createParticles(e.x + 18, e.y + 18, '#ff0000', 12);
        createFloatingText(e.x + 18, e.y, '+50', '#ff3333');
        updateHUD();
      } else {
        damagePlayer();
      }
    }
  }

  // Collectibles
  for (const c of collectibles) {
    if (c.collected) continue;
    const cr = {x: c.x, y: c.y, w: 24, h: 24};
    if (rectOverlap(player, cr)) {
      c.collected = true;
      collectedStars++;
      const points = c.type === 'star' ? 10 : 25;
      score += points;
      createParticles(c.x + 12, c.y + 12, '#ff2020', 10);
      createFloatingText(c.x + 12, c.y, '+' + points, '#ff5555');
      updateHUD();
    }
  }

  // NPCs
  for (const n of npcs) {
    if (n.talked) continue;
    const nr = {x: n.x, y: n.y, w: 30, h: 40};
    if (rectOverlap(player, nr)) {
      n.talked = true;
      document.getElementById('factTitle').textContent = 'Conversa';
      document.getElementById('factText').textContent = n.text;
      document.getElementById('factBtn').onclick = () => {
        gameState = 'playing';
        document.getElementById('factScreen').style.display = 'none';
        document.getElementById('hud').style.display = 'flex';
      };
      gameState = 'fact';
      document.getElementById('factScreen').style.display = 'flex';
      document.getElementById('hud').style.display = 'none';
      return;
    }
  }

  // Goal reached
  if (rectOverlap(player, goal)) {
    // Show next fact (one per level completion)
    showFact(0);
    return;
  }

  // Camera follows player
  const targetCameraX = player.x - GAME_WIDTH / 2 + player.width / 2;
  cameraX += (targetCameraX - cameraX) * 0.1;
  if (cameraX < 0) cameraX = 0;
  if (cameraX > levelData.width - GAME_WIDTH) cameraX = levelData.width - GAME_WIDTH;

  // Update particles
  for (let i = particles.length - 1; i >= 0; i--) {
    const p = particles[i];
    p.x += p.vx;
    p.y += p.vy;
    p.vy += 0.2;
    p.life--;
    if (p.life <= 0) particles.splice(i, 1);
  }

  // Update floating texts
  for (let i = floatingTexts.length - 1; i >= 0; i--) {
    const t = floatingTexts[i];
    t.y += t.vy;
    t.vy *= 0.95;
    t.life--;
    if (t.life <= 0) floatingTexts.splice(i, 1);
  }
}

function rectOverlap(a, b) {
  return a.x < b.x + b.w && a.x + a.width > b.x && a.y < b.y + b.h && a.y + a.height > b.y;
}

function damagePlayer() {
  if (player.invulnerable > 0) return;
  lives--;
  player.invulnerable = 90;
  player.x = 60;
  player.y = 300;
  player.vx = 0;
  player.vy = 0;
  cameraX = 0;
  updateHUD();
  if (lives <= 0) {
    gameState = 'gameover';
    document.getElementById('gameOverText').textContent = 'Você perdeu todas as vidas. Tente novamente!';
    showScreen('gameOverScreen');
  }
}

function createParticles(x, y, color, count) {
  for (let i = 0; i < count; i++) {
    particles.push({
      x: x, y: y,
      vx: (Math.random() - 0.5) * 5,
      vy: -Math.random() * 4 - 1,
      life: 30 + Math.random() * 20,
      color: color,
      size: 2 + Math.random() * 3
    });
  }
}

let floatingTexts = [];
function createFloatingText(x, y, text, color) {
  floatingTexts.push({ x: x, y: y, text: text, color: color, life: 60, vy: -1 });
}

// ============== RENDERING ==============
function render() {
  ctx.fillStyle = levelData ? levelData.bgColor : '#5c94fc';
  ctx.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);

  if (!levelData) return;

  // Draw clouds/background elements
  drawBackground();

  ctx.save();
  ctx.translate(-Math.floor(cameraX), 0);

  // Draw platforms
  for (const p of platforms) {
    drawPlatform(p);
  }

  // Draw goal
  drawGoal();

  // Draw collectibles
  for (const c of collectibles) {
    if (!c.collected) drawCollectible(c);
  }

  // Draw NPCs
  for (const n of npcs) {
    drawNPC(n);
  }

  // Draw enemies
  for (const e of enemies) {
    if (e.alive) drawEnemy(e);
  }

  // Draw particles
  for (const p of particles) {
    ctx.fillStyle = p.color;
    ctx.fillRect(p.x - p.size/2, p.y - p.size/2, p.size, p.size);
  }

  // Draw player
  drawPlayer();

  // Draw floating texts (após o player, sobre tudo)
  ctx.font = 'bold 16px Arial';
  ctx.textAlign = 'center';
  for (const t of floatingTexts) {
    const alpha = Math.min(1, t.life / 30);
    ctx.fillStyle = `rgba(0,0,0,${alpha})`;
    ctx.fillText(t.text, t.x + 1, t.y + 1);
    ctx.fillStyle = t.color;
    ctx.globalAlpha = alpha;
    ctx.fillText(t.text, t.x, t.y);
    ctx.globalAlpha = 1;
  }
  ctx.textAlign = 'left';

  ctx.restore();
}

function drawBackground() {
  const bgType = levelData.bgType || 'tropical';

  // Camada 1: Morros/fábricas distantes (parallax lento)
  const farOffset = cameraX * 0.2;

  if (bgType === 'industrial') {
    // Fábricas ao fundo para a fase industrial
    ctx.fillStyle = 'rgba(80, 80, 90, 0.6)';
    for (let i = -1; i < 10; i++) {
      const hx = ((i * 380 - farOffset) % (levelData.width + 400) + (levelData.width + 400)) % (levelData.width + 400);
      drawHill(hx, 340, 220, 70);
    }
    // Fábricas
    const factoryOffset = cameraX * 0.25;
    for (let i = -1; i < 8; i++) {
      const fx = ((i * 480 - factoryOffset) % (levelData.width + 500) + (levelData.width + 500)) % (levelData.width + 500);
      drawFactory(fx, 380);
    }
  } else {
    // Morros verdes para as outras fases
    ctx.fillStyle = 'rgba(60, 130, 70, 0.55)';
    for (let i = -1; i < 16; i++) {
      const hx = ((i * 260 - farOffset) % (levelData.width + 400) + (levelData.width + 400)) % (levelData.width + 400);
      drawHill(hx, 340, 220, 90);
    }
    // Morros mais próximos (parallax médio)
    const nearHillOffset = cameraX * 0.4;
    ctx.fillStyle = 'rgba(40, 110, 50, 0.7)';
    for (let i = -1; i < 14; i++) {
      const hx = ((i * 280 - nearHillOffset) % (levelData.width + 300) + (levelData.width + 300)) % (levelData.width + 300);
      drawHill(hx, 360, 180, 60);
    }
    // Palmeiras/coqueiros decorativos ao longe (parallax médio)
    const treeOffset = cameraX * 0.5;
    for (let i = -1; i < 18; i++) {
      const tx = ((i * 200 - treeOffset) % (levelData.width + 200) + (levelData.width + 200)) % (levelData.width + 200);
      drawPalmTree(tx, 380);
    }
  }

  // Nuvens (parallax médio) - sempre presentes
  ctx.fillStyle = 'rgba(255,255,255,0.85)';
  const cloudOffset = cameraX * 0.3;
  for (let i = -1; i < 8; i++) {
    const cx = ((i * 400 - cloudOffset) % (levelData.width + 400) + (levelData.width + 400)) % (levelData.width + 400);
    const cy = 60 + (i % 3) * 30;
    drawCloud(cx, cy);
  }
}

function drawHill(x, y, w, h) {
  // Morro arredondado estilo Mata Atlântica / morros brasileiros
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.bezierCurveTo(x, y - h, x + w, y - h, x + w, y);
  ctx.fill();
}

function drawPalmTree(x, y) {
  // Tronco
  ctx.fillStyle = '#6b4423';
  ctx.fillRect(x + 8, y - 50, 4, 50);
  // Folhas (palmeira)
  ctx.fillStyle = '#1a6b1a';
  ctx.beginPath();
  ctx.ellipse(x + 10, y - 50, 18, 6, Math.PI / 4, 0, Math.PI * 2);
  ctx.ellipse(x + 10, y - 50, 18, 6, -Math.PI / 4, 0, Math.PI * 2);
  ctx.ellipse(x + 10, y - 50, 18, 6, 0, 0, Math.PI * 2);
  ctx.fill();
  // Cocôs
  ctx.fillStyle = '#5c3317';
  ctx.beginPath();
  ctx.arc(x + 6, y - 47, 2.5, 0, Math.PI * 2);
  ctx.arc(x + 14, y - 47, 2.5, 0, Math.PI * 2);
  ctx.fill();
}

// Fábricas industriais (para a fase 4 - ABC)
function drawFactory(x, y) {
  // Corpo da fábrica
  ctx.fillStyle = '#3a3a3a';
  ctx.fillRect(x, y - 60, 120, 60);
  // Telhado serrilhado
  ctx.fillStyle = '#2a2a2a';
  for (let i = 0; i < 6; i++) {
    ctx.beginPath();
    ctx.moveTo(x + i * 20, y - 60);
    ctx.lineTo(x + i * 20 + 10, y - 70);
    ctx.lineTo(x + i * 20 + 20, y - 60);
    ctx.fill();
  }
  // Chaminés
  ctx.fillStyle = '#1a1a1a';
  ctx.fillRect(x + 30, y - 100, 12, 40);
  ctx.fillRect(x + 70, y - 90, 10, 30);
  // Faixa branca nas chaminés
  ctx.fillStyle = '#fff';
  ctx.fillRect(x + 30, y - 90, 12, 3);
  ctx.fillRect(x + 70, y - 82, 10, 3);
  // Janelas iluminadas
  ctx.fillStyle = '#ffcc66';
  for (let i = 0; i < 4; i++) {
    ctx.fillRect(x + 10 + i * 28, y - 40, 12, 10);
  }
  // Fumaça saindo das chaminés
  ctx.fillStyle = 'rgba(180, 180, 180, 0.6)';
  const t = Date.now() / 1000;
  for (let i = 0; i < 3; i++) {
    const sy = y - 100 - 15 * i - Math.sin(t + i) * 5;
    ctx.beginPath();
    ctx.arc(x + 36 + Math.sin(t + i) * 4, sy, 8 + i * 3, 0, Math.PI * 2);
    ctx.fill();
  }
  for (let i = 0; i < 3; i++) {
    const sy = y - 90 - 15 * i - Math.sin(t + i + 1) * 5;
    ctx.beginPath();
    ctx.arc(x + 75 + Math.sin(t + i + 1) * 4, sy, 7 + i * 3, 0, Math.PI * 2);
    ctx.fill();
  }
}

function drawCloud(x, y) {
  // Desenha cada círculo como um path separado para evitar linhas de conexão
  ctx.beginPath();
  ctx.arc(x, y, 18, 0, Math.PI * 2);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(x + 20, y + 5, 22, 0, Math.PI * 2);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(x + 45, y, 16, 0, Math.PI * 2);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(x + 25, y - 12, 18, 0, Math.PI * 2);
  ctx.fill();
}

function drawPlatform(p) {
  if (p.type === 'ground') {
    ctx.fillStyle = levelData.groundColor;
    ctx.fillRect(p.x, p.y, p.w, p.h);
    ctx.fillStyle = levelData.groundTop;
    ctx.fillRect(p.x, p.y, p.w, 12);
    // Texture
    ctx.fillStyle = 'rgba(0,0,0,0.15)';
    for (let i = 0; i < p.w; i += 40) {
      ctx.fillRect(p.x + i, p.y + 20, 2, 20);
    }
  } else {
    ctx.fillStyle = levelData.groundColor;
    ctx.fillRect(p.x, p.y, p.w, p.h);
    ctx.fillStyle = levelData.groundTop;
    ctx.fillRect(p.x, p.y, p.w, 8);
    ctx.strokeStyle = 'rgba(0,0,0,0.3)';
    ctx.lineWidth = 1;
    ctx.strokeRect(p.x, p.y, p.w, p.h);
  }
}

function drawGoal() {
  // Bandeira do Brasil
  const gx = goal.x, gy = goal.y;
  // Mastro
  ctx.fillStyle = '#8B4513';
  ctx.fillRect(gx, gy, 6, goal.h);
  // Bandeira
  ctx.fillStyle = '#009c3b';
  ctx.fillRect(gx + 6, gy, 50, 35);
  ctx.fillStyle = '#ffdf00';
  ctx.beginPath();
  ctx.moveTo(gx + 6, gy + 17);
  ctx.lineTo(gx + 56, gy + 5);
  ctx.lineTo(gx + 56, gy + 30);
  ctx.lineTo(gx + 6, gy + 17);
  ctx.fill();
  ctx.fillStyle = '#002776';
  ctx.beginPath();
  ctx.arc(gx + 31, gy + 17, 7, 0, Math.PI * 2);
  ctx.fill();
  // Brilho
  const pulse = Math.sin(Date.now() / 200) * 0.5 + 0.5;
  ctx.strokeStyle = `rgba(255,255,255,${pulse})`;
  ctx.lineWidth = 3;
  ctx.strokeRect(gx - 5, gy - 5, 70, goal.h + 10);
}

function drawPlayer() {
  const p = player;
  if (p.invulnerable > 0 && Math.floor(p.invulnerable / 4) % 2 === 0) return;

  const x = Math.floor(p.x);
  const y = Math.floor(p.y);
  const fx = p.facing;

  // Sombra
  ctx.fillStyle = 'rgba(0,0,0,0.2)';
  ctx.beginPath();
  ctx.ellipse(x + 12, y + 36, 14, 4, 0, 0, Math.PI * 2);
  ctx.fill();

  // Corpo (camisa branca) - estilo pixel art
  ctx.fillStyle = '#ffffff';
  ctx.fillRect(x + 4, y + 18, 16, 14);
  // Calça (azul escuro)
  ctx.fillStyle = '#1a3a5c';
  if (p.onGround && Math.abs(p.vx) > 0.5) {
    // Pernas animadas
    if (p.animFrame === 0 || p.animFrame === 2) {
      ctx.fillRect(x + 4, y + 30, 7, 6);
      ctx.fillRect(x + 13, y + 30, 7, 6);
    } else if (p.animFrame === 1) {
      ctx.fillRect(x + 2, y + 30, 7, 6);
      ctx.fillRect(x + 15, y + 30, 7, 6);
    } else {
      ctx.fillRect(x + 6, y + 30, 7, 6);
      ctx.fillRect(x + 11, y + 30, 7, 6);
    }
  } else {
    ctx.fillRect(x + 4, y + 30, 7, 6);
    ctx.fillRect(x + 13, y + 30, 7, 6);
  }

  // Cabeça (pele)
  ctx.fillStyle = '#d4a373';
  ctx.fillRect(x + 5, y + 2, 14, 16);

  // Cabelo (cinza - Lula mais velho) ou preto
  ctx.fillStyle = '#3a3a3a';
  ctx.fillRect(x + 4, y, 16, 6);
  ctx.fillRect(x + 4, y + 4, 4, 4);
  ctx.fillRect(x + 16, y + 4, 4, 4);

  // Barba
  ctx.fillStyle = '#3a3a3a';
  ctx.fillRect(x + 5, y + 13, 14, 4);
  ctx.fillRect(x + 6, y + 17, 12, 2);

  // Olhos
  ctx.fillStyle = '#000';
  if (fx > 0) {
    ctx.fillRect(x + 13, y + 8, 2, 2);
    ctx.fillRect(x + 17, y + 8, 2, 2);
  } else {
    ctx.fillRect(x + 5, y + 8, 2, 2);
    ctx.fillRect(x + 9, y + 8, 2, 2);
  }

  // Boca (sorriso)
  ctx.fillStyle = '#000';
  ctx.fillRect(x + 9, y + 12, 6, 1);

  // Braços
  ctx.fillStyle = '#d4a373';
  if (fx > 0) {
    ctx.fillRect(x + 18, y + 20, 4, 10);
    ctx.fillRect(x + 2, y + 20, 4, 10);
  } else {
    ctx.fillRect(x + 2, y + 20, 4, 10);
    ctx.fillRect(x + 18, y + 20, 4, 10);
  }

  // Sapatos
  ctx.fillStyle = '#2a2a2a';
  ctx.fillRect(x + 3, y + 34, 8, 3);
  ctx.fillRect(x + 13, y + 34, 8, 3);
}

function drawEnemy(e) {
  const x = Math.floor(e.x), y = Math.floor(e.y);
  if (e.type === 'cactus') {
    // Cacto verde do sertão
    ctx.fillStyle = '#2d5016';
    ctx.fillRect(x + 12, y, 12, 36);
    ctx.fillStyle = '#3a6b1f';
    ctx.fillRect(x + 8, y + 10, 8, 14);
    ctx.fillRect(x + 20, y + 6, 8, 12);
    // Espinhos
    ctx.fillStyle = '#fff';
    for (let i = 0; i < 4; i++) {
      ctx.fillRect(x + 14, y + 4 + i * 8, 1, 2);
      ctx.fillRect(x + 21, y + 4 + i * 8, 1, 2);
    }
  } else if (e.type === 'truck') {
    // Caminhão (pau de arara)
    ctx.fillStyle = '#8b0000';
    ctx.fillRect(x, y + 10, 30, 26);
    ctx.fillStyle = '#5a0000';
    ctx.fillRect(x + 20, y + 4, 16, 32);
    ctx.fillStyle = '#aaa';
    ctx.fillRect(x + 22, y + 8, 12, 8);
    // Rodas
    ctx.fillStyle = '#000';
    ctx.beginPath();
    ctx.arc(x + 6, y + 36, 5, 0, Math.PI * 2);
    ctx.arc(x + 18, y + 36, 5, 0, Math.PI * 2);
    ctx.arc(x + 30, y + 36, 5, 0, Math.PI * 2);
    ctx.fill();
  } else if (e.type === 'machine') {
    // Máquina industrial
    ctx.fillStyle = '#666';
    ctx.fillRect(x, y + 4, 36, 32);
    ctx.fillStyle = '#444';
    ctx.fillRect(x + 4, y + 8, 8, 8);
    ctx.fillRect(x + 24, y + 8, 8, 8);
    ctx.fillStyle = '#ff0';
    ctx.fillRect(x + 6, y + 10, 4, 4);
    ctx.fillRect(x + 26, y + 10, 4, 4);
    // Engrenagens
    ctx.fillStyle = '#222';
    ctx.beginPath();
    ctx.arc(x + 18, y + 26, 6, 0, Math.PI * 2);
    ctx.fill();
    ctx.strokeStyle = '#888';
    ctx.lineWidth = 2;
    const ang = Date.now() / 200;
    for (let i = 0; i < 6; i++) {
      const a = ang + i * Math.PI / 3;
      ctx.beginPath();
      ctx.moveTo(x + 18, y + 26);
      ctx.lineTo(x + 18 + Math.cos(a) * 8, y + 26 + Math.sin(a) * 8);
      ctx.stroke();
    }
  } else if (e.type === 'soldier') {
    // Soldado (ditadura)
    ctx.fillStyle = '#4a5d23';
    ctx.fillRect(x + 8, y + 10, 20, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 12, y, 12, 12);
    // Capacete
    ctx.fillStyle = '#3a4a1c';
    ctx.fillRect(x + 10, y - 2, 16, 6);
    // Olhos
    ctx.fillStyle = '#000';
    if (e.dir > 0) {
      ctx.fillRect(x + 18, y + 5, 2, 2);
    } else {
      ctx.fillRect(x + 16, y + 5, 2, 2);
    }
    // Rifle
    ctx.fillStyle = '#222';
    ctx.fillRect(x + (e.dir > 0 ? 28 : 0), y + 16, 8, 2);
  } else if (e.type === 'corruption') {
    // Inimigo abstrato (corrupção - dinheirinho vermelho)
    ctx.fillStyle = '#cc0000';
    ctx.fillRect(x + 4, y, 28, 28);
    ctx.fillStyle = '#fff';
    ctx.font = 'bold 18px Arial';
    ctx.fillText('R$', x + 7, y + 20);
    // Olhos raivosos
    ctx.fillStyle = '#000';
    ctx.fillRect(x + 10, y + 8, 4, 4);
    ctx.fillRect(x + 22, y + 8, 4, 4);
  }
}

function drawCollectible(c) {
  const x = Math.floor(c.x), y = Math.floor(c.y);
  const bob = Math.sin(Date.now() / 300 + x * 0.01) * 3;
  const cy = y + bob;

  if (c.type === 'star') {
    drawStar(x + 12, cy + 12, 10, '#ff2020', '#8b0000');
  } else if (c.type === 'book') {
    ctx.fillStyle = '#1e3a8a';
    ctx.fillRect(x, cy, 24, 20);
    ctx.fillStyle = '#fff';
    ctx.fillRect(x + 2, cy + 3, 20, 2);
    ctx.fillRect(x + 2, cy + 7, 16, 2);
    ctx.fillRect(x + 2, cy + 11, 18, 2);
    ctx.fillRect(x + 2, cy + 15, 14, 2);
    ctx.fillStyle = '#ffdf00';
    ctx.fillRect(x, cy, 24, 3);
  } else if (c.type === 'tool') {
    // Chave de fenda
    ctx.fillStyle = '#888';
    ctx.fillRect(x + 10, cy, 4, 18);
    ctx.fillStyle = '#8b4513';
    ctx.fillRect(x + 8, cy + 14, 8, 10);
    ctx.fillStyle = '#ccc';
    ctx.fillRect(x + 11, cy + 2, 2, 14);
  } else if (c.type === 'megaphone') {
    // Megafone
    ctx.fillStyle = '#cc0000';
    ctx.beginPath();
    ctx.moveTo(x + 4, cy + 4);
    ctx.lineTo(x + 20, cy);
    ctx.lineTo(x + 20, cy + 20);
    ctx.lineTo(x + 4, cy + 16);
    ctx.closePath();
    ctx.fill();
    ctx.fillStyle = '#444';
    ctx.fillRect(x, cy + 6, 6, 8);
  } else if (c.type === 'flag') {
    // Bandeixinha do PT
    ctx.fillStyle = '#8B4513';
    ctx.fillRect(x + 2, cy, 2, 22);
    ctx.fillStyle = '#cc0000';
    ctx.fillRect(x + 4, cy, 18, 12);
    ctx.fillStyle = '#fff';
    ctx.font = 'bold 11px Arial';
    ctx.fillText('PT', x + 8, cy + 10);
  } else if (c.type === 'house') {
    // Casinha
    ctx.fillStyle = '#8b4513';
    ctx.fillRect(x + 2, cy + 10, 20, 12);
    ctx.fillStyle = '#cc0000';
    ctx.beginPath();
    ctx.moveTo(x, cy + 10);
    ctx.lineTo(x + 12, cy);
    ctx.lineTo(x + 24, cy + 10);
    ctx.closePath();
    ctx.fill();
    ctx.fillStyle = '#ffdf00';
    ctx.fillRect(x + 8, cy + 14, 8, 8);
  } else if (c.type === 'bolsa') {
    // Bolsa família
    ctx.fillStyle = '#009c3b';
    ctx.fillRect(x, cy, 24, 20);
    ctx.fillStyle = '#ffdf00';
    ctx.fillRect(x, cy, 24, 4);
    ctx.fillStyle = '#fff';
    ctx.font = 'bold 8px Arial';
    ctx.fillText('R$', x + 6, cy + 14);
    ctx.fillStyle = '#000';
    ctx.font = 'bold 8px Arial';
    ctx.fillText('$', x + 13, cy + 14);
  }
}

function drawStar(cx, cy, size, color1, color2) {
  ctx.save();
  ctx.translate(cx, cy);
  ctx.beginPath();
  for (let i = 0; i < 10; i++) {
    const angle = (Math.PI / 5) * i - Math.PI / 2;
    const r = i % 2 === 0 ? size : size / 2.5;
    const px = Math.cos(angle) * r;
    const py = Math.sin(angle) * r;
    if (i === 0) ctx.moveTo(px, py);
    else ctx.lineTo(px, py);
  }
  ctx.closePath();
  ctx.fillStyle = color1;
  ctx.fill();
  ctx.strokeStyle = color2;
  ctx.lineWidth = 1.5;
  ctx.stroke();
  ctx.restore();
}

function drawNPC(n) {
  const x = Math.floor(n.x), y = Math.floor(n.y);
  // Indicador de "fale comigo"
  if (!n.talked) {
    const pulse = Math.sin(Date.now() / 200) * 4;
    ctx.fillStyle = '#ffdf00';
    ctx.font = 'bold 20px Arial';
    ctx.fillText('!', x + 12, y - 10 + pulse);
  }

  // Corpo baseado no tipo
  if (n.type === 'mother') {
    // Mãe Lindu - vestido
    ctx.fillStyle = '#8b3a62';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    ctx.fillStyle = '#3a3a3a';
    ctx.fillRect(x + 7, y + 2, 16, 6);
    ctx.fillStyle = '#000';
    ctx.fillRect(x + 11, y + 7, 2, 2);
    ctx.fillRect(x + 17, y + 7, 2, 2);
  } else if (n.type === 'teacher') {
    // Professora
    ctx.fillStyle = '#2a4d8f';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    ctx.fillStyle = '#000';
    ctx.fillRect(x + 11, y + 7, 2, 2);
    ctx.fillRect(x + 17, y + 7, 2, 2);
    // Óculos
    ctx.strokeStyle = '#000';
    ctx.lineWidth = 1;
    ctx.strokeRect(x + 10, y + 6, 4, 4);
    ctx.strokeRect(x + 16, y + 6, 4, 4);
  } else if (n.type === 'worker') {
    // Operário
    ctx.fillStyle = '#ff8c00';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    ctx.fillStyle = '#8b4513';
    ctx.fillRect(x + 6, y + 6, 18, 4);
    // Capacete
    ctx.fillStyle = '#ffdf00';
    ctx.fillRect(x + 6, y, 18, 8);
  } else if (n.type === 'doctor') {
    // Médico - jaleco branco
    ctx.fillStyle = '#fff';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    ctx.fillStyle = '#000';
    ctx.fillRect(x + 11, y + 7, 2, 2);
    ctx.fillRect(x + 17, y + 7, 2, 2);
    // Cruz vermelha
    ctx.fillStyle = '#cc0000';
    ctx.fillRect(x + 13, y + 18, 4, 8);
    ctx.fillRect(x + 9, y + 20, 12, 4);
  } else if (n.type === 'driver') {
    // Motorista
    ctx.fillStyle = '#444';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    // Boné
    ctx.fillStyle = '#222';
    ctx.fillRect(x + 6, y + 2, 18, 4);
    ctx.fillRect(x + 8, y - 2, 14, 6);
  } else if (n.type === 'intellectual') {
    // Intelectual - óculos
    ctx.fillStyle = '#2a2a2a';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    ctx.fillStyle = '#3a3a3a';
    ctx.fillRect(x + 7, y + 2, 16, 6);
    ctx.strokeStyle = '#000';
    ctx.lineWidth = 1;
    ctx.strokeRect(x + 10, y + 6, 4, 4);
    ctx.strokeRect(x + 16, y + 6, 4, 4);
  } else if (n.type === 'journalist') {
    // Jornalista
    ctx.fillStyle = '#556b2f';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    ctx.fillStyle = '#8b4513';
    ctx.fillRect(x + 8, y + 16, 22, 3);
    // Caderno
    ctx.fillStyle = '#fff';
    ctx.fillRect(x + 6, y + 20, 20, 14);
    ctx.fillStyle = '#000';
    ctx.fillRect(x + 8, y + 23, 16, 1);
    ctx.fillRect(x + 8, y + 26, 16, 1);
    ctx.fillRect(x + 8, y + 29, 12, 1);
  } else if (n.type === 'citizen') {
    // Cidadão
    ctx.fillStyle = '#3a6b1f';
    ctx.fillRect(x + 4, y + 14, 22, 26);
    ctx.fillStyle = '#d4a373';
    ctx.fillRect(x + 8, y, 14, 16);
    ctx.fillStyle = '#000';
    ctx.fillRect(x + 11, y + 7, 2, 2);
    ctx.fillRect(x + 17, y + 7, 2, 2);
    // Sorriso
    ctx.fillRect(x + 12, y + 11, 6, 2);
  }
}

// ============== MAIN LOOP ==============
function gameLoop() {
  update();
  render();
  requestAnimationFrame(gameLoop);
}

// Start render loop (will be idle until level loaded)
gameLoop();

// Initial screen
showScreen('startScreen');
</script>
</body>
</html>

Game Source: Lula: Uma Jornada Brasileira

Creator: DriftOtter98

Libraries: none

Complexity: complex (1574 lines, 59.4 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: lula-uma-jornada-brasileira-driftotter98" to link back to the original. Then publish at arcadelab.ai/publish.