<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mortes Aleatórias</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
* { box-sizing: border-box; }
body {
margin: 0;
background: #080b14;
color: white;
font-family: 'Press Start 2P', monospace;
text-align: center;
overflow-x: hidden;
}
header { padding: 22px 10px 12px; }
h1 {
font-size: clamp(20px, 5vw, 42px);
color: #ff3d58;
text-shadow: 4px 4px #751c3b;
margin: 12px 0;
}
header p { font-size: 9px; color: #929dbb; line-height: 2; }
.hud {
display: flex; justify-content: space-around; flex-wrap: wrap;
gap: 12px; padding: 15px; font-size: 10px; color: #f6d365;
}
#gamebox {
position: relative;
width: min(960px, 96vw);
margin: auto;
border: 5px solid #343e5b;
box-shadow: 0 0 30px #000;
background: #141b2c;
}
canvas {
display: block;
width: 100%;
height: auto;
image-rendering: pixelated;
}
#overlay {
position: absolute; inset: 0;
display: flex; align-items: center; justify-content: center;
flex-direction: column; gap: 20px;
background: #050813d9;
padding: 20px;
}
#overlay h2 { color: #ff405b; font-size: clamp(18px, 4vw, 32px); line-height: 1.7; }
#message { font-size: 10px; line-height: 2.5; max-width: 520px; color: #d7ddf2; }
button {
font-family: inherit; cursor: pointer;
background: #ff405b; color: white;
border: 0; padding: 17px 20px;
font-size: 11px;
box-shadow: 0 5px #9d243d;
}
button:hover { background: #ff7184; transform: translateY(-2px); }
button:active { transform: translateY(3px); box-shadow: none; }
.controls {
color: #9aa6c8; font-size: 9px; line-height: 2.5;
padding: 20px 8px 28px;
}
#toast {
min-height: 28px; color: #ffca62;
font-size: 10px; padding: 10px; line-height: 2;
}
.mobile {
display: flex; justify-content: center; gap: 12px;
margin: 0 auto 20px;
}
.mobile button { min-width: 68px; padding: 18px 12px; }
@media (min-width: 750px) { .mobile { display: none; } }
</style>
</head>
<body>
<header>
<h1>MORTES<br>ALEATÓRIAS</h1>
<p>AQUI, A MORTE VEM DO NADA...</p>
</header>
<div class="hud">
<span>☠ MORTES: <b id="deaths">0</b></span>
<span>⌛ TEMPO: <b id="time">0</b>s</span>
<span>★ RECORDE: <b id="record">0</b></span>
</div>
<div id="gamebox">
<canvas id="game" width="480" height="300"></canvas>
<div id="overlay">
<h2 id="title">SOBREVIVA!</h2>
<div id="message">Ande pelo mapa. Você nunca sabe como vai morrer...<br><br>Sobreviva o máximo que conseguir!</div>
<button id="start">▶ JOGAR</button>
</div>
</div>
<div id="toast">Prepare-se para o inesperado...</div>
<div class="mobile">
<button id="left">◀</button>
<button id="jump">▲</button>
<button id="right">▶</button>
</div>
<div class="controls">
A / D ou ← / → : ANDAR<br>
W / ↑ / ESPAÇO : PULAR<br>
OBJETIVO: NÃO MORRER 💀
</div>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
ctx.imageSmoothingEnabled = false;
const $ = id => document.getElementById(id);
let running = false, dead = false, deaths = 0, elapsed = 0;
let last = 0, eventTimer = 2, survival = 0;
let keys = {}, hazards = [], particles = [], toastTimer = 0;
let player = {
x: 60, y: 230, w: 14, h: 20,
vx: 0, vy: 0, grounded: false,
invuln: 0
};
const deathMessages = [
'VOCÊ FOI ATINGIDO POR UM METEORO!',
'UM RAIO CAIU NA SUA CABEÇA!',
'O CHÃO VIROU LAVA!',
'UMA BIGORNA CAIU DO CÉU!',
'VOCÊ PISOU NUMA ARMADILHA!',
'EXPLOSÃO INESPERADA!',
'UMA PAREDE TE ESMAGOU!',
'VOCÊ FOI ATACADO POR UM CUBO!',
'A GRAVIDADE TE TRAIU!',
'UMA CHUVA DE ESPINHOS!',
'VOCÊ FOI ATINGIDO POR UM LASER!',
'UM BLOCO CAIU NA SUA CABEÇA!'
];
const eventNames = [
'☄ METEORO DETECTADO!',
'⚡ TEMPESTADE ELÉTRICA!',
'🔥 A LAVA ESTÁ SUBINDO!',
'📦 CUIDADO COM AS BIGORNAS!',
'⚠ ARMADILHAS ATIVADAS!',
'💥 EXPLOSÕES ALEATÓRIAS!',
'🧱 BLOCO PERDIDO!',
'👾 CUBO ASSASSINO!',
'☠ A GRAVIDADE MUDOU!',
'🔺 CHUVA DE ESPINHOS!',
'🔴 LASER ATIVADO!',
'📦 CHUVA DE BLOCOS!'
];
let currentEvent = -1;
let floorY = 265;
let lavaY = 300;
function rand(a,b) { return Math.random()*(b-a)+a; }
function choose(a) { return a[Math.floor(Math.random()*a.length)]; }
function rect(x,y,w,h,color) {
ctx.fillStyle = color;
ctx.fillRect(Math.round(x),Math.round(y),w,h);
}
function text(str,x,y,size,color='#fff') {
ctx.fillStyle=color;
ctx.font=`${size}px monospace`;
ctx.fillText(str,x,y);
}
function reset() {
player={x:60,y:230,w:14,h:20,vx:0,vy:0,grounded:false,invuln:0};
hazards=[]; particles=[]; elapsed=0; survival=0;
eventTimer=2; lavaY=300; currentEvent=-1;
dead=false; running=true; last=performance.now();
$('overlay').style.display='none';
$('toast').textContent='SOBREVIVA A QUALQUER CUSTO!';
requestAnimationFrame(loop);
}
function showToast(s) {
$('toast').textContent=s;
toastTimer=2.5;
}
function spawnEvent() {
currentEvent=Math.floor(Math.random()*12);
showToast(choose(eventNames.filter((_,i)=>i===currentEvent)));
const type=currentEvent;
if(type===0 || type===3 || type===11) {
const x=rand(25,445);
hazards.push({
type:'fall', x, y:-25, vy:rand(90,150),
size:type===3?18:14, deadly:true
});
}
if(type===1) {
for(let i=0;i<3;i++)
hazards.push({type:'lightning',x:rand(25,440),y:0,t:rand(.2,.8),deadly:true});
}
if(type===2) {
lavaY=285;
hazards.push({type:'lava',y:lavaY,deadly:true});
}
if(type===4 || type===9) {
for(let i=0;i<7;i++)
hazards.push({type:'spike',x:rand(10,455),y:floorY-8,deadly:true});
}
if(type===5) {
hazards.push({type:'bomb',x:rand(60,420),y:floorY-10,t:1,deadly:true});
}
if(type===6) {
hazards.push({type:'wall',x:480,y:190,w:20,h:75,vx:-100,deadly:true});
}
if(type===7) {
hazards.push({type:'enemy',x:rand(200,450),y:floorY-18,w:16,h:18,vx:-70,deadly:true});
}
if(type===8) {
hazards.push({type:'gravity',t:2,deadly:false});
player.vy=-300;
}
if(type===10) {
hazards.push({type:'laser',x:0,y:rand(205,250),t:1.1,deadly:true});
}
}
function overlap(a,b) {
return a.x < b.x+b.w && a.x+a.w > b.x &&
a.y < b.y+b.h && a.y+a.h > b.y;
}
function die(message) {
if(dead) return;
dead=true; running=false; deaths++;
$('deaths').textContent=deaths;
let best=Number(localStorage.getItem('mortespixel_record')||0);
best=Math.max(best,Math.floor(elapsed));
localStorage.setItem('mortespixel_record',best);
$('record').textContent=best;
$('title').textContent='VOCÊ MORREU!';
$('message').innerHTML=message+'<br><br>TEMPO: '+Math.floor(elapsed)+' SEGUNDOS<br><br>💀 MORTES TOTAIS: '+deaths;
$('start').textContent='↻ JOGAR NOVAMENTE';
$('overlay').style.display='flex';
for(let i=0;i<20;i++) particles.push({
x:player.x+7,y:player.y+10,
vx:rand(-100,100),vy:rand(-150,50),t:1
});
draw();
}
function update(dt) {
elapsed+=dt; survival+=dt;
$('time').textContent=Math.floor(elapsed);
if(toastTimer>0) toastTimer-=dt;
eventTimer-=dt;
if(eventTimer<=0) {
spawnEvent();
eventTimer=rand(1.8,3.6);
}
player.invuln=Math.max(0,player.invuln-dt);
const speed=125;
if(keys.left) player.vx=-speed;
else if(keys.right) player.vx=speed;
else player.vx*=Math.pow(.001,dt);
player.x+=player.vx*dt;
player.x=Math.max(2,Math.min(464-player.w,player.x));
player.vy+=650*dt;
player.y+=player.vy*dt;
player.grounded=false;
if(player.y+player.h>=floorY) {
player.y=floorY-player.h;
player.vy=0;
player.grounded=true;
}
if(player.y<0) { player.y=0; player.vy=0; }
for(let i=hazards.length-1;i>=0;i--) {
const h=hazards[i];
if(h.type==='fall') {
h.y+=h.vy*dt;
if(h.y>310) { hazards.splice(i,1); continue; }
}
if(h.type==='lightning') {
h.t-=dt;
if(h.t<0) { hazards.splice(i,1); continue; }
}
if(h.type==='lava') {
h.y-=25*dt;
if(h.y<floorY-5) h.y=floorY-5;
lavaY=h.y;
}
if(h.type==='bomb') {
h.t-=dt;
if(h.t<=0) {
h.type='explosion'; h.t=.45;
h.x-=22; h.y-=22; h.w=60; h.h=60;
}
}
if(h.type==='explosion') {
h.t-=dt;
if(h.t<=0) { hazards.splice(i,1); continue; }
}
if(h.type==='wall') {
h.x+=h.vx*dt;
if(h.x<-30) { hazards.splice(i,1); continue; }
}
if(h.type==='enemy') {
h.x+=h.vx*dt;
if(h.x<-20) { hazards.splice(i,1); continue; }
}
if(h.type==='gravity') {
h.t-=dt;
if(h.t<=0) { hazards.splice(i,1); continue; }
}
if(h.type==='laser') {
h.t-=dt;
if(h.t<=0) { hazards.splice(i,1); continue; }
}
if(h.type==='spike') h.w=12,h.h=12;
if(h.type==='fall') h.w=h.h=h.size;
if(h.type==='lightning') h.w=22,h.h=260;
if(h.type==='lava') h.x=0,h.w=480,h.h=300-h.y;
if(h.type==='wall'||h.type==='enemy') {}
if(h.type==='laser') h.w=480,h.h=5;
if(h.deadly && overlap(player,h)) {
die(choose(deathMessages));
return;
}
}
if(player.y>300) { die('VOCÊ CAIU NO VAZIO!'); return; }
for(let i=particles.length-1;i>=0;i--) {
const p=particles[i];
p.x+=p.vx*dt; p.y+=p.vy*dt; p.vy+=250*dt; p.t-=dt;
if(p.t<=0) particles.splice(i,1);
}
}
function draw() {
ctx.clearRect(0,0,480,300);
rect(0,0,480,300,'#10182a');
// Fundo pixelado
for(let y=0;y<floorY;y+=20) {
for(let x=0;x<480;x+=20) {
rect(x,y,19,19,((x+y)/20)%2===0?'#19233a':'#151f34');
rect(x,y,19,1,'#27304a');
}
}
// Decoração
for(let x=20;x<480;x+=80) {
rect(x,20,18,18,'#343c59');
rect(x+4,24,10,10,'#f5bb55');
rect(x+6,26,6,6,'#ffe7a2');
}
// Plataformas
rect(0,floorY,480,35,'#333c57');
rect(0,floorY,480,4,'#77829e');
for(let x=0;x<480;x+=16) {
rect(x,floorY+8,14,2,'#1c263d');
rect(x+4,floorY+18,7,2,'#1c263d');
}
// Obstáculos
for(const h of hazards) {
if(h.type==='fall') {
rect(h.x,h.y,h.size,h.size,'#b3bdcf');
rect(h.x+3,h.y+3,h.size-6,h.size-6,'#727e9a');
rect(h.x+3,h.y+3,4,4,'#e6e9f2');
}
if(h.type==='lightning') {
rect(h.x+7,0,8,260,'#f8e879');
rect(h.x+3,0,16,260,'#f8e87955');
}
if(h.type==='lava') {
rect(0,h.y,480,300-h.y,'#e53c37');
for(let i=0;i<12;i++) rect(i*43,h.y+Math.sin(elapsed*5+i)*4,24,5,'#ffb53f');
}
if(h.type==='spike') {
rect(h.x,h.y,12,12,'#b9c5df');
rect(h.x+3,h.y+3,6,9,'#56617e');
rect(h.x+5,h.y+5,2,4,'#222c45');
}
if(h.type==='bomb') {
rect(h.x,h.y,16,16,'#e74751');
rect(h.x+4,h.y+4,8,8,'#34354c');
rect(h.x+6,h.y-4,4,4,'#ffc85c');
}
if(h.type==='explosion') {
rect(h.x,h.y,60,60,'#ff9b35');
rect(h.x+10,h.y+10,40,40,'#ffdf66');
rect(h.x+20,h.y+20,20,20,'#fff3b0');
}
if(h.type==='wall') {
rect(h.x,h.y,h.w,h.h,'#8d4967');
rect(h.x+4,h.y+4,h.w-8,h.h-8,'#d57d8f');
}
if(h.type==='enemy') {
rect(h.x,h.y,16,18,'#64bd70');
rect(h.x+2,h.y+3,4,4,'#f3f4e7');
rect(h.x+10,h.y+3,4,4,'#f3f4e7');
rect(h.x+3,h.y+4,2,2,'#25253a');
rect(h.x+11,h.y+4,2,2,'#25253a');
rect(h.x+4,h.y+12,8,3,'#263044');
}
if(h.type==='laser') {
rect(0,h.y,480,5,'#ff334f');
rect(0,h.y-2,480,2,'#ff9fa9');
}
}
// Personagem pixel art
if(!dead || Math.floor(elapsed*8)%2===0) {
const x=Math.round(player.x), y=Math.round(player.y);
// sombra
rect(x+1,floorY-2,13,3,'#080d18');
// cabelo
rect(x+3,y,9,5,'#332b46');
rect(x+2,y+2,11,4,'#4c3d60');
// rosto
rect(x+3,y+5,9,6,'#f0bd91');
rect(x+4,y+6,2,2,'#171d30');
rect(x+10,y+6,2,2,'#171d30');
// camiseta
rect(x+2,y+11,11,6,'#e74757');
rect(x,y+12,3,5,'#f0bd91');
rect(x+12,y+12,3,5,'#f0bd91');
// pernas
rect(x+3,y+17,4,3,'#536da6');
rect(x+9,y+17,4,3,'#536da6');
rect(x+2,y+19,5,2,'#dce4f8');
rect(x+9,y+19,5,2,'#dce4f8');
}
for(const p of particles) {
rect(p.x,p.y,4,4,'#ff405b');
}
// Barra de informação
rect(7,7,130,20,'#080d1dcc');
text('SOBREVIVA!',13,20,9,'#f5d577');
if(currentEvent>=0 && running) {
rect(300,7,173,20,'#080d1dcc');
text('PERIGO!',310,20,9,'#ff6177');
}
}
function loop(now) {
if(!running) return;
const dt=Math.min((now-last)/1000,.035);
last=now;
update(dt);
if(!dead) draw();
if(running) requestAnimationFrame(loop);
}
function jump() {
if(running && player.grounded) {
player.vy=-265;
player.grounded=false;
}
}
document.addEventListener('keydown',e=>{
const k=e.key.toLowerCase();
if(['arrowleft','arrowright','arrowup',' '].includes(k)) e.preventDefault();
if(k==='a'||k==='arrowleft') keys.left=true;
if(k==='d'||k==='arrowright') keys.right=true;
if(k==='w'||k==='arrowup'||k===' ') jump();
if(k==='enter'&&!running) reset();
});
document.addEventListener('keyup',e=>{
const k=e.key.toLowerCase();
if(k==='a'||k==='arrowleft') keys.left=false;
if(k==='d'||k==='arrowright') keys.right=false;
});
function hold(id,key) {
const b=$(id);
b.addEventListener('pointerdown',e=>{e.preventDefault();keys[key]=true;});
['pointerup','pointercancel','pointerleave'].forEach(ev=>
b.addEventListener(ev,()=>keys[key]=false));
}
hold('left','left'); hold('right','right');
$('jump').addEventListener('pointerdown',e=>{e.preventDefault();jump();});
$('start').onclick=reset;
$('record').textContent=Number(localStorage.getItem('mortespixel_record')||0);
draw();
</script>
</body>
</html>