<!DOCTYPE html><html lang="pt-BR"><head><meta charset="UTF-8"><title>Teaser - Nave Retro com Som</title><style> body { margin: 0; overflow: hidden; background: black; } canvas { display: block; margin: 0 auto; }</style></head><body><canvas id="gameCanvas"></canvas><script>const canvas = document.getElementById("gameCanvas");const ctx = canvas.getContext("2d");canvas.width = 800;canvas.height = 600;
// Web Audio API para sons retrôconst audioCtx = new (window.AudioContext || window.webkitAudioContext)();function playSound(frequency, type, duration, volume=0.2) { const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.type = type; oscillator.frequency.setValueAtTime(frequency, audioCtx.currentTime); gainNode.gain.setValueAtTime(volume, audioCtx.currentTime); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.start(); oscillator.stop(audioCtx.currentTime + duration);}// sons específicosfunction shootSound(){ playSound(600,"square",0.1,0.2); }function explosionSound(){ playSound(80,"sawtooth",0.3,0.3); }
// Naveconst player = { x: canvas.width/2 - 20, y: canvas.height - 100, width: 40, height: 60, color: "#ff0", bullets: []};
// Inimigoslet enemies = [];const enemyTypes = [ {color: "#f00", size: 30}, {color: "#0f0", size: 40}, {color: "#0ff", size: 50}];
// Explosõeslet explosions = [];
// Fundo estreladolet stars = [];for(let i=0;i<200;i++){ stars.push({x: Math.random()*canvas.width, y: Math.random()*canvas.height, size: Math.random()*2+1});}
// Criar inimigosfunction spawnEnemy() { const type = enemyTypes[Math.floor(Math.random() * enemyTypes.length)]; enemies.push({ x: Math.random() * (canvas.width - type.size), y: -type.size, width: type.size, height: type.size, color: type.color, speed: 2 + Math.random() * 2 });}
// Explosãofunction createExplosion(x,y,color){ explosionSound(); for(let i=0;i<15;i++){ explosions.push({ x:x, y:y, dx:(Math.random()-0.5)*4, dy:(Math.random()-0.5)*4, life:20, color:color }); }}
// Atualizaçãolet frame = 0;function update() { frame++;
// Movimento automático player.x = 400 + Math.sin(frame/40)*300;
// Atira sozinho if(frame % 20 === 0) { player.bullets.push({x: player.x + player.width/2 - 5, y: player.y, width: 10, height: 20, color:"#ff0"}); shootSound(); }
// Balas player.bullets.forEach((b,i)=>{ b.y -= 10; if(b.y + b.height < 0) player.bullets.splice(i,1); });
// Inimigos enemies.forEach((e,i)=>{ e.y += e.speed; if(e.y > canvas.height) enemies.splice(i,1);
player.bullets.forEach((b,j)=>{ if(b.x < e.x+e.width && b.x+b.width > e.x && b.y < e.y+e.height && b.y+b.height > e.y){ createExplosion(e.x+e.width/2, e.y+e.height/2, e.color); enemies.splice(i,1); player.bullets.splice(j,1); } }); });
// Explosões explosions.forEach((ex,i)=>{ ex.x += ex.dx; ex.y += ex.dy; ex.life--; if(ex.life<=0) explosions.splice(i,1); });
// Estrelas stars.forEach(s=>{ s.y += 2; if(s.y > canvas.height) s.y = 0; });}
// Desenharfunction draw() { ctx.clearRect(0,0,canvas.width,canvas.height);
// Fundo ctx.fillStyle = "white"; stars.forEach(s=>ctx.fillRect(s.x,s.y,s.size,s.size));
// Nave ctx.fillStyle = player.color; ctx.beginPath(); ctx.moveTo(player.x, player.y + player.height); ctx.lineTo(player.x + player.width/2, player.y); ctx.lineTo(player.x + player.width, player.y + player.height); ctx.closePath(); ctx.fill();
// Balas player.bullets.forEach(b=>{ ctx.fillStyle = b.color; ctx.fillRect(b.x,b.y,b.width,b.height); });
// Inimigos enemies.forEach(e=>{ ctx.fillStyle = e.color; ctx.fillRect(e.x,e.y,e.width,e.height); });
// Explosões explosions.forEach(ex=>{ ctx.fillStyle = ex.color; ctx.fillRect(ex.x, ex.y, 4,4); });}
// Looplet enemyTimer = 0;let duration = 0;function loop(){ update(); draw(); enemyTimer++; duration++;
if(enemyTimer % 30 === 0) spawnEnemy();
if(duration < 900){ // 15s requestAnimationFrame(loop); } else { ctx.fillStyle = "#fff"; ctx.font = "40px monospace"; ctx.fillText("VIAGEM VINTAGE!", 220, 300); }}
// Ativar áudio só após interação (exigência do navegador)document.body.addEventListener("click", ()=>{ if(audioCtx.state === "suspended") audioCtx.resume();}, {once:true});
loop();</script></body></html>