Deriva Axial: Jogo de Labirinto Físico Responsivo para Dispositivos Móveis

De Wikiprompt, a enciclopédia livre de prompts

loshu2000
Contribuído porloshu2000Fonte

17 de mai. de 2026

Deriva Axial: Jogo de Labirinto Físico Responsivo para Dispositivos Móveis Um prompt abrangente para gerar um jogo de labirinto em HTML5 de arquivo único com mecânicas de mudança de gravidade, controles de inclinação para dispositivos móveis e estilo visual Bauhaus.

Conteúdo do PromptSalvar

🌐
<!doctype html> <html lang="pt-BR"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <title>Axial Drift</title> <style> * { margin:0; padding:0; box-sizing:border-box; } html, body { width:100%; height:100%; overflow:hidden; background:#1a1a1a; font-family:'Arial Black', Arial, sans-serif; } #game-container { position:relative; width:100%; height:100%; display:flex; align-items:center; justify-content:center; } canvas { display:block; background:#f0f0f0; box-shadow:0 0 40px rgba(0,0,0,0.8); border:4px solid #000; } #ui-overlay { position:absolute; top:10px; left:10px; color:#000; font-size:14px; background:rgba(255,255,255,0.8); padding:8px 12px; border:2px solid #000; box-shadow:4px 4px 0 #000; pointer-events:none; } #ui-overlay span { font-weight:bold; } #win-screen { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); background:#ffcc00; border:4px solid #000; box-shadow:8px 8px 0 #000; padding:20px 40px; text-align:center; display:none; z-index:10; } #win-screen h1 { font-size:32px; margin-bottom:10px; } #win-screen button { background:#000; color:#fff; border:none; padding:10px 20px; font-size:16px; cursor:pointer; box-shadow:4px 4px 0 #ffcc00; } #win-screen button:hover { background:#333; } </style> </head> <body> <div id="game-container"> <canvas id="gameCanvas"></canvas> <div id="ui-overlay">Tempo: <span id="timer">0.0</span>s | Nível: <span id="level">1</span></div> <div id="win-screen"> <h1>VÓRTICE ALCANÇADO!</h1> <p>Tempo: <span id="final-time">0</span>s</p> <button onclick="restartGame()">JOGAR NOVAMENTE</button> </div> </div> <script> (function() { 'use strict'; // ===== CONFIGURAÇÕES ===== const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const uiTimer = document.getElementById('timer'); const uiLevel = document.getElementById('level'); const winScreen = document.getElementById('win-screen'); const finalTime = document.getElementById('final-time'); // Dimensões lógicas do jogo (escala fixa) const GAME_WIDTH = 800; const GAME_HEIGHT = 600; // Física const GRAVITY_MAX = 1500; // px/s² const FRICTION = 0.98; const DAMPING = 0.995; const MARBLE_RADIUS = 12; const VORTEX_RADIUS = 30; // Estado do jogo let marble = { x: 100, y: 100, vx: 0, vy: 0 }; let gravity = { x: 0, y: 800 }; // vetor gravidade inicial (aponta para baixo) let mazeWalls = []; let trapdoors = []; let vortex = { x: 700, y: 500 }; let level = 1; let startTime = 0; let elapsedTime = 0; let gameActive = true; let lastTimestamp = 0; // Controle de entrada let isDragging = false; let lastMouseX = 0, lastMouseY = 0; let deviceTiltX = 0, deviceTiltY = 0; let useDeviceOrientation = false; // ===== GERAÇÃO DO LABIRINTO ===== function generateMaze(levelNum) { mazeWalls = []; trapdoors = []; // Paredes externas mazeWalls.push({ x: 20, y: 20, w: 760, h: 10 }); mazeWalls.push({ x: 20, y: 570, w: 760, h: 10 }); mazeWalls.push({ x: 20, y: 20, w: 10, h: 560 }); mazeWalls.push({ x: 770, y: 20, w: 10, h: 560 }); // Paredes internas baseadas no nível if (levelNum === 1) { // Nível 1 - labirinto simples mazeWalls.push({ x: 200, y: 20, w: 10, h: 200 }); mazeWalls.push({ x: 200, y: 300, w: 10, h: 280 }); mazeWalls.push({ x: 400, y: 20, w: 10, h: 150 }); mazeWalls.push({ x: 400, y: 250, w: 10, h: 200 }); mazeWalls.push({ x: 600, y: 150, w: 10, h: 250 }); mazeWalls.push({ x: 600, y: 480, w: 10, h: 100 }); mazeWalls.push({ x: 300, y: 400, w: 200, h: 10 }); // Armadilhas trapdoors.push({ x: 350, y: 250, w: 60, h: 60, active: true, timer: 0, interval: 2.0 }); trapdoors.push({ x: 550, y: 350, w: 50, h: 50, active: true, timer: 1.0, interval: 1.5 }); // Vórtice vortex = { x: 700, y: 500 }; marble = { x: 100, y: 100, vx: 0, vy: 0 }; } else if (levelNum === 2) { // Nível 2 - mais complexo mazeWalls.push({ x: 150, y: 20, w: 10, h: 300 }); mazeWalls.push({ x: 150, y: 400, w: 10, h: 180 }); mazeWalls.push({ x: 300, y: 100, w: 10, h: 200 }); mazeWalls.push({ x: 300, y: 380, w: 10, h: 200 }); mazeWalls.push({ x: 450, y: 20, w: 10, h: 150 }); mazeWalls.push({ x: 450, y: 250, w: 10, h: 250 }); mazeWalls.push({ x: 600, y: 100, w: 10, h: 300 }); mazeWalls.push({ x: 600, y: 480, w: 10, h: 100 }); mazeWalls.push({ x: 250, y: 300, w: 150, h: 10 }); mazeWalls.push({ x: 500, y: 200, w: 150, h: 10 }); trapdoors.push({ x: 200, y: 200, w: 50, h: 50, active: true, timer: 0, interval: 1.5 }); trapdoors.push({ x: 400, y: 350, w: 60, h: 60, active: true, timer: 0.5, interval: 2.0 }); trapdoors.push({ x: 550, y: 150, w: 40, h: 40, active: true, timer: 1.5, interval: 1.0 }); vortex = { x: 700, y: 500 }; marble = { x: 100, y: 100, vx: 0, vy: 0 }; } else { // Nível 3+ - aleatório for (let i = 0; i < 8; i++) { let x = 50 + Math.random() * 650; let y = 50 + Math.random() * 450; let w = 80 + Math.random() * 120; let h = 10 + Math.random() * 20; mazeWalls.push({ x, y, w, h }); } for (let i = 0; i < 5; i++) { let x = 50 + Math.random() * 650; let y = 50 + Math.random() * 450; let w = 10 + Math.random() * 20; let h = 80 + Math.random() * 120; mazeWalls.push({ x, y, w, h }); } for (let i = 0; i < 4; i++) { trapdoors.push({ x: 50 + Math.random() * 650, y: 50 + Math.random() * 450, w: 40 + Math.random() * 30, h: 40 + Math.random() * 30, active: true, timer: Math.random() * 2, interval: 1.0 + Math.random() * 2 }); } vortex = { x: 700, y: 500 }; marble = { x: 100, y: 100, vx: 0, vy: 0 }; } } // ===== FÍSICA ===== function updatePhysics(dt) { if (!gameActive) return; // Aplica gravidade marble.vx += gravity.x * dt; marble.vy += gravity.y * dt; // Amortecimento e fricção marble.vx *= (FRICTION * DAMPING); marble.vy *= (FRICTION * DAMPING); // Atualiza posição marble.x += marble.vx * dt; marble.y += marble.vy * dt; // Colisão com paredes for (let wall of mazeWalls) { // Colisão horizontal if (marble.x + MARBLE_RADIUS > wall.x && marble.x - MARBLE_RADIUS < wall.x + wall.w && marble.y + MARBLE_RADIUS > wall.y && marble.y - MARBLE_RADIUS < wall.y + wall.h) { // Determina lado da colisão let overlapLeft = (marble.x + MARBLE_RADIUS) - wall.x; let overlapRight = (wall.x + wall.w) - (marble.x - MARBLE_RADIUS); let overlapTop = (marble.y + MARBLE_RADIUS) - wall.y; let overlapBottom = (wall.y + wall.h) - (marble.y - MARBLE_RADIUS); let minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom); if (minOverlap === overlapLeft) { marble.x = wall.x - MARBLE_RADIUS; marble.vx *= -0.3; } else if (minOverlap === overlapRight) { marble.x = wall.x + wall.w + MARBLE_RADIUS; marble.vx *= -0.3; } else if (minOverlap === overlapTop) { marble.y = wall.y - MARBLE_RADIUS; marble.vy *= -0.3; } else { marble.y = wall.y + wall.h + MARBLE_RADIUS; marble.vy *= -0.3; } } } // Limites do canvas if (marble.x < MARBLE_RADIUS) { marble.x = MARBLE_RADIUS; marble.vx *= -0.5; } if (marble.x > GAME_WIDTH - MARBLE_RADIUS) { marble.x = GAME_WIDTH - MARBLE_RADIUS; marble.vx *= -0.5; } if (marble.y < MARBLE_RADIUS) { marble.y = MARBLE_RADIUS; marble.vy *= -0.5; } if (marble.y > GAME_HEIGHT - MARBLE_RADIUS) { marble.y = GAME_HEIGHT - MARBLE_RADIUS; marble.vy *= -0.5; } // Atualiza armadilhas for (let trap of trapdoors) { trap.timer += dt; if (trap.timer >= trap.interval) { trap.active = !trap.active; trap.timer = 0; } // Colisão com armadilha ativa if (trap.active) { if (marble.x + MARBLE_RADIUS > trap.x && marble.x - MARBLE_RADIUS < trap.x + trap.w && marble.y + MARBLE_RADIUS > trap.y && marble.y - MARBLE_RADIUS < trap.y + trap.h) { // Reinicia posição marble.x = 100; marble.y = 100; marble.vx = 0; marble.vy = 0; } } } // Verifica vórtice (vitória) let dx = marble.x - vortex.x; let dy = marble.y - vortex.y; let dist = Math.sqrt(dx*dx + dy*dy); if (dist < VORTEX_RADIUS) { gameActive = false; elapsedTime = (performance.now() - startTime) / 1000; finalTime.textContent = elapsedTime.toFixed(1); winScreen.style.display = 'block'; } } // ===== RENDERIZAÇÃO ===== function render() { ctx.clearRect(0, 0, GAME_WIDTH, GAME_HEIGHT); // Fundo ctx.fillStyle = '#f0f0f0'; ctx.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); // Sombra projetada ctx.shadowColor = 'rgba(0,0,0,0.3)'; ctx.shadowBlur = 15; ctx.shadowOffsetX = 5; ctx.shadowOffsetY = 5; // Paredes (estilo Bauhaus) for (let wall of mazeWalls) { ctx.fillStyle = '#e63946'; // vermelho ctx.fillRect(wall.x, wall.y, wall.w, wall.h); ctx.strokeStyle = '#000'; ctx.lineWidth = 3; ctx.strokeRect(wall.x, wall.y, wall.w, wall.h); } // Armadilhas for (let trap of trapdoors) { if (trap.active) { ctx.fillStyle = '#2a9d8f'; // verde ctx.fillRect(trap.x, trap.y, trap.w, trap.h); ctx.strokeStyle = '#000'; ctx.lineWidth = 3; ctx.strokeRect(trap.x, trap.y, trap.w, trap.h); // Padrão de perigo ctx.fillStyle = '#000'; ctx.font = 'bold 20px Arial'; ctx.fillText('!', trap.x + trap.w/2 - 8, trap.y + trap.h/2 + 7); } else { ctx.fillStyle = '#264653'; // azul escuro ctx.fillRect(trap.x, trap.y, trap.w, trap.h); ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.strokeRect(trap.x, trap.y, trap.w, trap.h); } } // Vórtice ctx.shadowBlur = 20; ctx.fillStyle = '#f4a261'; // laranja ctx.beginPath(); ctx.arc(vortex.x, vortex.y, VORTEX_RADIUS, 0, Math.PI * 2); ctx.fill(); ctx.strokeStyle = '#000'; ctx.lineWidth = 4; ctx.stroke(); ctx.fillStyle = '#000'; ctx.font = 'bold 16px Arial'; ctx.fillText('V', vortex.x - 8, vortex.y + 6); // Mármore ctx.shadowBlur = 25; ctx.fillStyle = '#264653'; ctx.beginPath(); ctx.arc(marble.x, marble.y, MARBLE_RADIUS, 0, Math.PI * 2); ctx.fill(); ctx.strokeStyle = '#000'; ctx.lineWidth = 3; ctx.stroke(); // Brilho ctx.fillStyle = 'rgba(255,255,255,0.3)'; ctx.beginPath(); ctx.arc(marble.x - 3, marble.y - 3, MARBLE_RADIUS * 0.4, 0, Math.PI * 2); ctx.fill(); // Reset sombra ctx.shadowBlur = 0; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; // Vetor de gravidade (indicador) ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(GAME_WIDTH - 80, 50); ctx.lineTo(GAME_WIDTH - 80 + gravity.x * 0.03, 50 + gravity.y * 0.03); ctx.stroke(); ctx.fillStyle = '#000'; ctx.beginPath(); ctx.arc(GAME_WIDTH - 80 + gravity.x * 0.03, 50 + gravity.y * 0.03, 5, 0, Math.PI * 2); ctx.fill(); ctx.font = '12px Arial'; ctx.fillText('GRAV', GAME_WIDTH - 110, 40); } // ===== LOOP PRINCIPAL ===== function gameLoop(timestamp) { let dt = (timestamp - lastTimestamp) / 1000; if (dt > 0.1) dt = 0.1; // proteção contra saltos lastTimestamp = timestamp; if (gameActive) { elapsedTime = (timestamp - startTime) / 1000; uiTimer.textContent = elapsedTime.toFixed(1); } updatePhysics(dt); render(); requestAnimationFrame(gameLoop); } // ===== CONTROLES ===== function handleMouseDown(e) { isDragging = true; lastMouseX = e.clientX; lastMouseY = e.clientY; } function handleMouseMove(e) { if (!isDragging) return; let dx = e.clientX - lastMouseX; let dy = e.clientY - lastMouseY; // Ajusta gravidade baseado no arrasto gravity.x = dx * 15; gravity.y = dy * 15; // Limita magnitude let mag = Math.sqrt(gravity.x * gravity.x + gravity.y * gravity.y); if (mag > GRAVITY_MAX) { gravity.x = (gravity.x / mag) * GRAVITY_MAX; gravity.y = (gravity.y / mag) * GRAVITY_MAX; } lastMouseX = e.clientX; lastMouseY = e.clientY; } function handleMouseUp() { isDragging = false; gravity.x = 0; gravity.y = 800; // volta ao padrão } // Suporte a orientação do dispositivo function handleOrientation(e) { if (!useDeviceOrientation) return; // gamma: inclinação esquerda/direita (-90 a 90) // beta: inclinação frente/trás (-180 a 180) let gamma = e.gamma || 0; let beta = e.beta || 0; // Converte para gravidade gravity.x = (gamma / 90) * GRAVITY_MAX; gravity.y = (beta / 90) * GRAVITY_MAX; // Limita let mag = Math.sqrt(gravity.x * gravity.x + gravity.y * gravity.y); if (mag > GRAVITY_MAX) { gravity.x = (gravity.x / mag) * GRAVITY_MAX; gravity.y = (gravity.y / mag) * GRAVITY_MAX; } } // ===== INICIALIZAÇÃO ===== function resizeCanvas() { let container = document.getElementById('game-container'); let containerWidth = container.clientWidth; let containerHeight = container.clientHeight; let scale = Math.min(containerWidth / GAME_WIDTH, containerHeight / GAME_HEIGHT); canvas.width = GAME_WIDTH; canvas.height = GAME_HEIGHT; canvas.style.width = (GAME_WIDTH * scale) + 'px'; canvas.style.height = (GAME_HEIGHT * scale) + 'px'; } function restartGame() { winScreen.style.display = 'none'; level = 1; uiLevel.textContent = level; generateMaze(level); gameActive = true; startTime = performance.now(); elapsedTime = 0; gravity = { x: 0, y: 800 }; } // Eventos canvas.addEventListener('mousedown', handleMouseDown); canvas.addEventListener('mousemove', handleMouseMove); canvas.addEventListener('mouseup', handleMouseUp); canvas.addEventListener('mouseleave', handleMouseUp); // Touch support canvas.addEventListener('touchstart', (e) => { e.preventDefault(); let touch = e.touches[0]; handleMouseDown({ clientX: touch.clientX, clientY: touch.clientY }); }); canvas.addEventListener('touchmove', (e) => { e.preventDefault(); let touch = e.touches[0]; handleMouseMove({ clientX: touch.clientX, clientY: touch.clientY }); }); canvas.addEventListener('touchend', (e) => { e.preventDefault(); handleMouseUp(); }); // Device orientation if (window.DeviceOrientationEvent) { window.addEventListener('deviceorientation', handleOrientation); useDeviceOrientation = true; } window.addEventListener('resize', resizeCanvas); // Inicia resizeCanvas(); generateMaze(level); startTime = performance.now(); lastTimestamp = performance.now(); requestAnimationFrame(gameLoop); // Expor função de reinício window.restartGame = restartGame; })(); </script> </body> </html>

Entre para ver o prompt completo

Continuar com:

Ao entrar, você concorda com nossos Termos de uso e Política de privacidade

Uso

Este prompt foi projetado para uso com coding. Copie o conteúdo acima e cole na sua ferramenta de IA preferida.

Para melhores resultados, personalize os marcadores (indicados por colchetes ou maiúsculas) com seus requisitos específicos.

Referências

Categorias:coding| prompts.chat| game-development| html5

Discussão

0 comentários