16 Jun
16Jun
<!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>
Comments
* The email will not be published on the website.