Liveloop

Uma timeline interativa para redes sociais. Cada post é um app minúsculo que você pode jogar, salvar e remixar.

Produto

  • Feed
  • Jogos
  • Criar
  • Plugin do Claude Code
  • Blog

Jurídico

  • Política de Privacidade
  • Termos de Serviço
  • Política de Cookies
  • DMCA

Projeto

  • Templates
© 2026 Liveloop. Todos os direitos reservados.
LiveloopHistórico de versões

v5Atual

@joaobarrosfranca · 8/12/2026, 4:04:26 PM

Diferença em relação à v4.

<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><style>
*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden;background:#80d3df;font-family:system-ui,sans-serif;touch-action:none}canvas{position:fixed;inset:0;width:100%;height:100%;z-index:0}.hud{position:fixed;z-index:3;top:0;left:0;right:0;padding:17px;display:flex;justify-content:space-between;color:#fff;text-shadow:0 2px 5px #175d72;pointer-events:none}.lab{font-size:10px;font-weight:1000;letter-spacing:1.8px}.num{font-size:28px;font-weight:1000}.r{text-align:right}.lives{font-size:18px;letter-spacing:2px;color:#ffdf62}#boss{position:fixed;z-index:3;top:70px;left:17%;right:17%;display:none;text-align:center;color:#fff;font-size:10px;font-weight:1000;letter-spacing:2px;text-shadow:0 2px 5px #175d72}.bar{height:9px;border:2px solid #fff;background:#593145;border-radius:5px;overflow:hidden;margin-top:5px}.bar i{display:block;height:100%;width:100%;background:linear-gradient(90deg,#ffdd57,#ff4d69)}.controls{position:fixed;z-index:4;bottom:17px;left:0;right:0;padding:0 14px;display:flex;justify-content:space-between;align-items:end}.group{display:flex;gap:8px}.controls button{border:2px solid #fff;color:#fff;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer}.move{width:52px;height:52px;border-radius:15px;background:#1785a3;font-size:22px}.action{width:62px;height:62px;border-radius:50%;font-size:10px}.jump{background:#8655cd}.shoot{background:#e87542}.controls button:active{transform:scale(.94)}#overlay{position:fixed;z-index:8;inset:0;display:grid;place-items:center;padding:27px;text-align:center;color:#fff;background:linear-gradient(155deg,#006c8ce9,#1964a4df 47%,#f47a4bc6)}#card{max-width:325px}.tag{font-size:11px;letter-spacing:4px;font-weight:1000;color:#fff0a3}.title{font-size:56px;line-height:.78;letter-spacing:-4px;font-weight:1000;margin:18px;text-shadow:4px 4px #075775}.title span{color:#ffdd61}.copy{font-size:16px;line-height:1.5;color:#effdff}.start{border:3px solid #fff0a3;border-radius:5px;background:#ef7245;color:#fff;padding:15px 28px;font-weight:1000;font-size:14px;letter-spacing:1px;box-shadow:0 5px #9b3d3f;cursor:pointer}.tip{font-size:12px;color:#eaffff;margin-top:18px}
-</style></head><body><canvas id="game"></canvas><div class="hud"><div><div class="lab">CHIPS</div><div id="chips" class="num">0 / 8</div></div><div class="r"><div class="lab">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON WARDEN<div class="bar"><i id="bossFill"></i></div></div><div class="controls"><div class="group"><button id="left" class="move">←</button><button id="right" class="move">→</button></div><div class="group"><button id="jump" class="action jump">JUMP</button><button id="shoot" class="action shoot">BLAST</button></div></div><div id="overlay"><div id="card"><div class="tag">2D RUN & BLAST</div><div class="title">BOLT<br><span>RUNNER</span></div><p id="copy" class="copy">Walk through the Skyworks, jump between platforms, collect energy chips, and blast the Iron Warden.</p><button id="start" class="start">POWER UP</button><div class="tip">A / D move · W jumps · Space fires</div></div></div>
+</style></head><body><canvas id="game"></canvas><div class="hud"><div><div class="lab">CHIPS</div><div id="chips" class="num">0 / 8</div></div><div class="r"><div class="lab">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON WARDEN<div class="bar"><i id="bossFill"></i></div></div><div class="controls"><div class="group"><button id="moveLeft" class="move">←</button><button id="moveRight" class="move">→</button></div><div class="group"><button id="jumpButton" class="action jump">JUMP</button><button id="shootButton" class="action shoot">BLAST</button></div></div><div id="overlay"><div id="card"><div class="tag">2D RUN & BLAST</div><div class="title">BOLT<br><span>RUNNER</span></div><p id="copy" class="copy">Walk through the Skyworks, jump between platforms, collect energy chips, and blast the Iron Warden.</p><button id="start" class="start">POWER UP</button><div class="tip">A / D move · W jumps · Space fires</div></div></div>
<script>
-const cv=document.getElementById("game"),ctx=cv.getContext("2d"),el={chips:document.getElementById("chips"),lives:document.getElementById("lives"),boss:document.getElementById("boss"),fill:document.getElementById("bossFill"),overlay:document.getElementById("overlay"),copy:document.getElementById("copy"),start:document.getElementById("start")};let W,H,keys={},run=false,last=0,player,plats,enemies,shots,chips,cam=0,lives=3,boss=null,fireAt=0;
-function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight}addEventListener("resize",resize);resize();
-function stage(){plats=[{x:-100,w:4700,y:0},{x:370,w:180,y:120},{x:700,w:150,y:190},{x:1030,w:180,y:125},{x:1420,w:170,y:205},{x:1740,w:210,y:135},{x:2150,w:190,y:205},{x:2550,w:160,y:130},{x:2940,w:220,y:185},{x:3360,w:230,y:125}];chips=[{x:260,y:45},{x:420,y:170},{x:760,y:240},{x:1080,y:175},{x:1490,y:255},{x:1820,y:185},{x:2215,y:255},{x:3020,y:235}];enemies=[{x:540,y:35,hp:2},{x:900,y:35,hp:2},{x:1260,y:35,hp:2},{x:1640,y:35,hp:2},{x:2030,y:35,hp:2},{x:2420,y:35,hp:2},{x:2800,y:35,hp:2}];shots=[]}
-function reset(){stage();player={x:90,y:70,vx:0,vy:0,w:30,h:48,ground:false,dir:1,inv:0,score:0};cam=0;lives=3;boss=null;run=true;el.chips.textContent="0 / 8";el.lives.textContent="● ● ●";el.boss.style.display="none";el.overlay.style.display="none";last=0}
-function platformAt(x,bottom,oldBottom){for(const p of plats)if(x+12>p.x&&x-12<p.x+p.w&&oldBottom>=p.y&&bottom<=p.y)return p;return null}
-function damage(){if(player.inv>0)return;lives--;player.inv=1100;el.lives.textContent=Array(lives).fill("●").join(" ")||"—";if(lives<=0){run=false;el.copy.innerHTML="The Skyworks shut Bolt down.<br>Try the route again.";el.start.textContent="REBOOT";el.overlay.style.display="grid";el.boss.style.display="none"}}
-function shot(x,y,vx,enemy=false){shots.push({x,y,vx,enemy,w:enemy?8:12})}function shoot(){if(run)shot(player.x+player.dir*20,player.y+31,player.dir*8)}
+const canvas=document.getElementById("game"),ctx=canvas.getContext("2d");
+const dom={chips:document.getElementById("chips"),lives:document.getElementById("lives"),boss:document.getElementById("boss"),fill:document.getElementById("bossFill"),overlay:document.getElementById("overlay"),copy:document.getElementById("copy"),start:document.getElementById("start"),left:document.getElementById("moveLeft"),right:document.getElementById("moveRight"),jump:document.getElementById("jumpButton"),shoot:document.getElementById("shootButton")};
+let W=0,H=0,run=false,last=0,held={left:false,right:false,fire:false},hero=null,platforms=[],chips=[],drones=[],bullets=[],boss=null,camera=0,lives=3,nextFire=0;
+function resize(){W=canvas.width=innerWidth;H=canvas.height=innerHeight}addEventListener("resize",resize);resize();
+function startStage(){platforms=[{x:-100,w:3000,y:0},{x:310,w:180,y:100},{x:650,w:170,y:170},{x:1010,w:180,y:110},{x:1370,w:170,y:190},{x:1740,w:220,y:110},{x:2100,w:220,y:170},{x:2480,w:240,y:115}];chips=[{x:190,y:35},{x:370,y:145},{x:710,y:215},{x:1065,y:155},{x:1430,y:235},{x:1810,y:155},{x:2170,y:215},{x:2550,y:160}];drones=[420,560,870,1220,1600,2000,2360].map(x=>({x,y:38,hp:2,dead:false,next:0}));bullets=[]}
+function reset(){startStage();hero={x:80,y:0,vy:0,dir:1,ground:true,inv:0,collected:0};camera=0;lives=3;boss=null;run=true;dom.chips.textContent="0 / 8";dom.lives.textContent="● ● ●";dom.boss.style.display="none";dom.overlay.style.display="none";last=0}
+function screenY(y){return H-80-y}function floorAt(x,bottom,previous){for(const p of platforms){if(x+13>p.x&&x-13<p.x+p.w&&previous>=p.y&&bottom<=p.y)return p.y}return null}
+function hurt(){if(hero.inv>0)return;lives--;hero.inv=1000;dom.lives.textContent=Array(lives).fill("●").join(" ")||"—";if(lives<=0){run=false;dom.copy.innerHTML="The Skyworks shut Bolt down.<br>Restart the mission and try a new route.";dom.start.textContent="REBOOT";dom.overlay.style.display="grid";dom.boss.style.display="none"}}
</script></body></html>

v5Atual

@joaobarrosfranca · 8/12/2026, 4:04:26 PM

Diferença em relação à v4.

<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><style>
*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden;background:#80d3df;font-family:system-ui,sans-serif;touch-action:none}canvas{position:fixed;inset:0;width:100%;height:100%;z-index:0}.hud{position:fixed;z-index:3;top:0;left:0;right:0;padding:17px;display:flex;justify-content:space-between;color:#fff;text-shadow:0 2px 5px #175d72;pointer-events:none}.lab{font-size:10px;font-weight:1000;letter-spacing:1.8px}.num{font-size:28px;font-weight:1000}.r{text-align:right}.lives{font-size:18px;letter-spacing:2px;color:#ffdf62}#boss{position:fixed;z-index:3;top:70px;left:17%;right:17%;display:none;text-align:center;color:#fff;font-size:10px;font-weight:1000;letter-spacing:2px;text-shadow:0 2px 5px #175d72}.bar{height:9px;border:2px solid #fff;background:#593145;border-radius:5px;overflow:hidden;margin-top:5px}.bar i{display:block;height:100%;width:100%;background:linear-gradient(90deg,#ffdd57,#ff4d69)}.controls{position:fixed;z-index:4;bottom:17px;left:0;right:0;padding:0 14px;display:flex;justify-content:space-between;align-items:end}.group{display:flex;gap:8px}.controls button{border:2px solid #fff;color:#fff;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer}.move{width:52px;height:52px;border-radius:15px;background:#1785a3;font-size:22px}.action{width:62px;height:62px;border-radius:50%;font-size:10px}.jump{background:#8655cd}.shoot{background:#e87542}.controls button:active{transform:scale(.94)}#overlay{position:fixed;z-index:8;inset:0;display:grid;place-items:center;padding:27px;text-align:center;color:#fff;background:linear-gradient(155deg,#006c8ce9,#1964a4df 47%,#f47a4bc6)}#card{max-width:325px}.tag{font-size:11px;letter-spacing:4px;font-weight:1000;color:#fff0a3}.title{font-size:56px;line-height:.78;letter-spacing:-4px;font-weight:1000;margin:18px;text-shadow:4px 4px #075775}.title span{color:#ffdd61}.copy{font-size:16px;line-height:1.5;color:#effdff}.start{border:3px solid #fff0a3;border-radius:5px;background:#ef7245;color:#fff;padding:15px 28px;font-weight:1000;font-size:14px;letter-spacing:1px;box-shadow:0 5px #9b3d3f;cursor:pointer}.tip{font-size:12px;color:#eaffff;margin-top:18px}
-</style></head><body><canvas id="game"></canvas><div class="hud"><div><div class="lab">CHIPS</div><div id="chips" class="num">0 / 8</div></div><div class="r"><div class="lab">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON WARDEN<div class="bar"><i id="bossFill"></i></div></div><div class="controls"><div class="group"><button id="left" class="move">←</button><button id="right" class="move">→</button></div><div class="group"><button id="jump" class="action jump">JUMP</button><button id="shoot" class="action shoot">BLAST</button></div></div><div id="overlay"><div id="card"><div class="tag">2D RUN & BLAST</div><div class="title">BOLT<br><span>RUNNER</span></div><p id="copy" class="copy">Walk through the Skyworks, jump between platforms, collect energy chips, and blast the Iron Warden.</p><button id="start" class="start">POWER UP</button><div class="tip">A / D move · W jumps · Space fires</div></div></div>
+</style></head><body><canvas id="game"></canvas><div class="hud"><div><div class="lab">CHIPS</div><div id="chips" class="num">0 / 8</div></div><div class="r"><div class="lab">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON WARDEN<div class="bar"><i id="bossFill"></i></div></div><div class="controls"><div class="group"><button id="moveLeft" class="move">←</button><button id="moveRight" class="move">→</button></div><div class="group"><button id="jumpButton" class="action jump">JUMP</button><button id="shootButton" class="action shoot">BLAST</button></div></div><div id="overlay"><div id="card"><div class="tag">2D RUN & BLAST</div><div class="title">BOLT<br><span>RUNNER</span></div><p id="copy" class="copy">Walk through the Skyworks, jump between platforms, collect energy chips, and blast the Iron Warden.</p><button id="start" class="start">POWER UP</button><div class="tip">A / D move · W jumps · Space fires</div></div></div>
<script>
-const cv=document.getElementById("game"),ctx=cv.getContext("2d"),el={chips:document.getElementById("chips"),lives:document.getElementById("lives"),boss:document.getElementById("boss"),fill:document.getElementById("bossFill"),overlay:document.getElementById("overlay"),copy:document.getElementById("copy"),start:document.getElementById("start")};let W,H,keys={},run=false,last=0,player,plats,enemies,shots,chips,cam=0,lives=3,boss=null,fireAt=0;
-function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight}addEventListener("resize",resize);resize();
-function stage(){plats=[{x:-100,w:4700,y:0},{x:370,w:180,y:120},{x:700,w:150,y:190},{x:1030,w:180,y:125},{x:1420,w:170,y:205},{x:1740,w:210,y:135},{x:2150,w:190,y:205},{x:2550,w:160,y:130},{x:2940,w:220,y:185},{x:3360,w:230,y:125}];chips=[{x:260,y:45},{x:420,y:170},{x:760,y:240},{x:1080,y:175},{x:1490,y:255},{x:1820,y:185},{x:2215,y:255},{x:3020,y:235}];enemies=[{x:540,y:35,hp:2},{x:900,y:35,hp:2},{x:1260,y:35,hp:2},{x:1640,y:35,hp:2},{x:2030,y:35,hp:2},{x:2420,y:35,hp:2},{x:2800,y:35,hp:2}];shots=[]}
-function reset(){stage();player={x:90,y:70,vx:0,vy:0,w:30,h:48,ground:false,dir:1,inv:0,score:0};cam=0;lives=3;boss=null;run=true;el.chips.textContent="0 / 8";el.lives.textContent="● ● ●";el.boss.style.display="none";el.overlay.style.display="none";last=0}
-function platformAt(x,bottom,oldBottom){for(const p of plats)if(x+12>p.x&&x-12<p.x+p.w&&oldBottom>=p.y&&bottom<=p.y)return p;return null}
-function damage(){if(player.inv>0)return;lives--;player.inv=1100;el.lives.textContent=Array(lives).fill("●").join(" ")||"—";if(lives<=0){run=false;el.copy.innerHTML="The Skyworks shut Bolt down.<br>Try the route again.";el.start.textContent="REBOOT";el.overlay.style.display="grid";el.boss.style.display="none"}}
-function shot(x,y,vx,enemy=false){shots.push({x,y,vx,enemy,w:enemy?8:12})}function shoot(){if(run)shot(player.x+player.dir*20,player.y+31,player.dir*8)}
+const canvas=document.getElementById("game"),ctx=canvas.getContext("2d");
+const dom={chips:document.getElementById("chips"),lives:document.getElementById("lives"),boss:document.getElementById("boss"),fill:document.getElementById("bossFill"),overlay:document.getElementById("overlay"),copy:document.getElementById("copy"),start:document.getElementById("start"),left:document.getElementById("moveLeft"),right:document.getElementById("moveRight"),jump:document.getElementById("jumpButton"),shoot:document.getElementById("shootButton")};
+let W=0,H=0,run=false,last=0,held={left:false,right:false,fire:false},hero=null,platforms=[],chips=[],drones=[],bullets=[],boss=null,camera=0,lives=3,nextFire=0;
+function resize(){W=canvas.width=innerWidth;H=canvas.height=innerHeight}addEventListener("resize",resize);resize();
+function startStage(){platforms=[{x:-100,w:3000,y:0},{x:310,w:180,y:100},{x:650,w:170,y:170},{x:1010,w:180,y:110},{x:1370,w:170,y:190},{x:1740,w:220,y:110},{x:2100,w:220,y:170},{x:2480,w:240,y:115}];chips=[{x:190,y:35},{x:370,y:145},{x:710,y:215},{x:1065,y:155},{x:1430,y:235},{x:1810,y:155},{x:2170,y:215},{x:2550,y:160}];drones=[420,560,870,1220,1600,2000,2360].map(x=>({x,y:38,hp:2,dead:false,next:0}));bullets=[]}
+function reset(){startStage();hero={x:80,y:0,vy:0,dir:1,ground:true,inv:0,collected:0};camera=0;lives=3;boss=null;run=true;dom.chips.textContent="0 / 8";dom.lives.textContent="● ● ●";dom.boss.style.display="none";dom.overlay.style.display="none";last=0}
+function screenY(y){return H-80-y}function floorAt(x,bottom,previous){for(const p of platforms){if(x+13>p.x&&x-13<p.x+p.w&&previous>=p.y&&bottom<=p.y)return p.y}return null}
+function hurt(){if(hero.inv>0)return;lives--;hero.inv=1000;dom.lives.textContent=Array(lives).fill("●").join(" ")||"—";if(lives<=0){run=false;dom.copy.innerHTML="The Skyworks shut Bolt down.<br>Restart the mission and try a new route.";dom.start.textContent="REBOOT";dom.overlay.style.display="grid";dom.boss.style.display="none"}}
</script></body></html>
-
-
function spawnBoss(){boss={x:3850,y:60,hp:42,max:42,vx:0,shot:0};el.boss.style.display="block";el.fill.style.width="100%"}
function spawnBoss(){boss={x:3850,y:60,hp:42,max:42,vx:0,shot:0};el.boss.style.display="block";el.fill.style.width="100%"}
-function end(){run=false;el.copy.innerHTML="<b>Skyworks cleared!</b><br>You defeated the Iron Warden and recovered the core.";el.start.textContent="PLAY AGAIN";el.overlay.style.display="grid";el.boss.style.display="none"}
-function end(){run=false;el.copy.innerHTML="<b>Skyworks cleared!</b><br>You defeated the Iron Warden and recovered the core.";el.start.textContent="PLAY AGAIN";el.overlay.style.display="grid";el.boss.style.display="none"}
-function collides(a,b){return Math.abs(a.x-b.x)<(a.w||28)/2+(b.w||28)/2&&Math.abs(a.y-b.y)<(a.h||30)/2+(b.h||30)/2}
-function collides(a,b){return Math.abs(a.x-b.x)<(a.w||28)/2+(b.w||28)/2&&Math.abs(a.y-b.y)<(a.h||30)/2+(b.h||30)/2}
-function drawRobot(x,y,dir,enemy=false,big=1){ctx.save();ctx.translate(x-cam,y);ctx.scale(dir*big,big);ctx.fillStyle=enemy?"#f36563":"#46cfc3";ctx.fillRect(-13,-30,26,30);ctx.fillRect(-11,-49,22,18);ctx.fillStyle=enemy?"#3a274b":"#1c4c69";ctx.fillRect(-8,-44,16,6);ctx.fillStyle=enemy?"#ffdf63":"#ffcc57";ctx.fillRect(12,-28,18,10);ctx.fillRect(-10,0,7,15);ctx.fillRect(4,0,7,15);ctx.restore()}
-function drawRobot(x,y,dir,enemy=false,big=1){ctx.save();ctx.translate(x-cam,y);ctx.scale(dir*big,big);ctx.fillStyle=enemy?"#f36563":"#46cfc3";ctx.fillRect(-13,-30,26,30);ctx.fillRect(-11,-49,22,18);ctx.fillStyle=enemy?"#3a274b":"#1c4c69";ctx.fillRect(-8,-44,16,6);ctx.fillStyle=enemy?"#ffdf63":"#ffcc57";ctx.fillRect(12,-28,18,10);ctx.fillRect(-10,0,7,15);ctx.fillRect(4,0,7,15);ctx.restore()}
-function loop(t){requestAnimationFrame(loop);let dt=Math.min(35,last?t-last:16);last=t;ctx.fillStyle="#80d3df";ctx.fillRect(0,0,W,H);let horizon=H*.55;ctx.fillStyle="#eff6ce";ctx.fillRect(0,horizon,W,H-horizon);for(let i=0;i<18;i++){let x=(i*310-cam*.22)% (W+310)-140;ctx.fillStyle=i%2?"#3d7e9a":"#2b6f8b";ctx.fillRect(x,horizon-60-(i%4)*35,80,60+(i%4)*35);ctx.fillStyle="#ffce5d";ctx.fillRect(x+12,horizon-40-(i%4)*35,14,6)}if(run){let dx=(keys.l?-1:0)+(keys.r?1:0);player.vx=dx*3.5;player.dir=dx||player.dir;let oldBottom=player.y;player.vy-=.00085*dt;player.y+=player.vy*dt;player.x+=player.vx*dt*.065;let landed=platformAt(player.x,player.y,oldBottom);if(landed&&player.vy<=0){player.y=landed.y;player.vy=0;player.ground=true}else player.ground=false;if(player.y<-120){player.y=70;player.x=Math.max(80,player.x-100);damage()}player.x=Math.max(30,Math.min(4200,player.x));cam+=((player.x-W*.35)-cam)*.08;cam=Math.max(0,Math.min(3800-W*.5,cam));player.inv=Math.max(0,player.inv-dt);if(keys.fire&&t>fireAt){shoot();fireAt=t+230}if(!boss&&player.x>3650&&chips.length===0)spawnBoss();for(const e of enemies){if(!e.dead&&Math.abs(player.x-e.x)<240&&t>(e.next||0)){shot(e.x,e.y+25,-3.8,true);e.next=t+1250}if(!e.dead&&Math.abs(player.x-e.x)<31&&Math.abs(player.y-e.y)<45)damage()}if(boss){boss.y=50+Math.sin(t*.002)*30;boss.x=3850+Math.sin(t*.001)*120;boss.shot-=dt;if(boss.shot<0){shot(boss.x,boss.y+20,-4.5,true);boss.shot=650}if(Math.abs(player.x-boss.x)<55&&Math.abs(player.y-boss.y)<70)damage()}for(let i=shots.length-1;i>=0;i--){let q=shots[i];q.x+=q.vx*dt*.06;let remove=q.x<cam-50||q.x>cam+W+50;if(!q.enemy){for(const e of enemies)if(!e.dead&&Math.abs(q.x-e.x)<28&&Math.abs(q.y-e.y-5)<32){e.hp--;remove=true;if(e.hp<=0)e.dead=true}if(boss&&Math.abs(q.x-boss.x)<55&&Math.abs(q.y-boss.y)<70){boss.hp--;remove=true;el.fill.style.width=boss.hp/boss.max*100+"%";if(boss.hp<=0)end()}}else if(Math.abs(q.x-player.x)<20&&Math.abs(q.y-player.y-23)<34){remove=true;damage()}if(remove)shots.splice(i,1)}for(let i=chips.length-1;i>=0;i--){let p=chips[i];if(Math.abs(player.x-p.x)<26&&Math.abs(player.y-p.y)<45){chips.splice(i,1);player.score++;el.chips.textContent=player.score+" / 8"}}}for(const p of plats){let x=p.x-cam;if(x+p.w<0||x>W)continue;ctx.fillStyle=p.y===0?"#276f79":"#7250a1";ctx.fillRect(x,H-(p.y+18),p.w,18);ctx.fillStyle="#ffd35f";ctx.fillRect(x,H-(p.y+18),p.w,4)}for(const chip of chips){ctx.fillStyle="#ffe35c";ctx.beginPath();ctx.arc(chip.x-cam,H-chip.y-20,9,0,7);ctx.fill()}for(const e of enemies)if(!e.dead)drawRobot(e.x,H-e.y-18,-1,true,.85);if(boss)drawRobot(boss.x,H-boss.y-18,-1,true,2.3);for(const q of shots){ctx.fillStyle=q.enemy?"#ff5a87":"#fff28a";ctx.fillRect(q.x-cam-5,H-q.y-23,10,4)}if(player&&(player.inv<=0||Math.floor(t/90)%2))drawRobot(player.x,H-player.y-18,player.dir);requestAnimationFrame(loop)}
-function loop(t){requestAnimationFrame(loop);let dt=Math.min(35,last?t-last:16);last=t;ctx.fillStyle="#80d3df";ctx.fillRect(0,0,W,H);let horizon=H*.55;ctx.fillStyle="#eff6ce";ctx.fillRect(0,horizon,W,H-horizon);for(let i=0;i<18;i++){let x=(i*310-cam*.22)% (W+310)-140;ctx.fillStyle=i%2?"#3d7e9a":"#2b6f8b";ctx.fillRect(x,horizon-60-(i%4)*35,80,60+(i%4)*35);ctx.fillStyle="#ffce5d";ctx.fillRect(x+12,horizon-40-(i%4)*35,14,6)}if(run){let dx=(keys.l?-1:0)+(keys.r?1:0);player.vx=dx*3.5;player.dir=dx||player.dir;let oldBottom=player.y;player.vy-=.00085*dt;player.y+=player.vy*dt;player.x+=player.vx*dt*.065;let landed=platformAt(player.x,player.y,oldBottom);if(landed&&player.vy<=0){player.y=landed.y;player.vy=0;player.ground=true}else player.ground=false;if(player.y<-120){player.y=70;player.x=Math.max(80,player.x-100);damage()}player.x=Math.max(30,Math.min(4200,player.x));cam+=((player.x-W*.35)-cam)*.08;cam=Math.max(0,Math.min(3800-W*.5,cam));player.inv=Math.max(0,player.inv-dt);if(keys.fire&&t>fireAt){shoot();fireAt=t+230}if(!boss&&player.x>3650&&chips.length===0)spawnBoss();for(const e of enemies){if(!e.dead&&Math.abs(player.x-e.x)<240&&t>(e.next||0)){shot(e.x,e.y+25,-3.8,true);e.next=t+1250}if(!e.dead&&Math.abs(player.x-e.x)<31&&Math.abs(player.y-e.y)<45)damage()}if(boss){boss.y=50+Math.sin(t*.002)*30;boss.x=3850+Math.sin(t*.001)*120;boss.shot-=dt;if(boss.shot<0){shot(boss.x,boss.y+20,-4.5,true);boss.shot=650}if(Math.abs(player.x-boss.x)<55&&Math.abs(player.y-boss.y)<70)damage()}for(let i=shots.length-1;i>=0;i--){let q=shots[i];q.x+=q.vx*dt*.06;let remove=q.x<cam-50||q.x>cam+W+50;if(!q.enemy){for(const e of enemies)if(!e.dead&&Math.abs(q.x-e.x)<28&&Math.abs(q.y-e.y-5)<32){e.hp--;remove=true;if(e.hp<=0)e.dead=true}if(boss&&Math.abs(q.x-boss.x)<55&&Math.abs(q.y-boss.y)<70){boss.hp--;remove=true;el.fill.style.width=boss.hp/boss.max*100+"%";if(boss.hp<=0)end()}}else if(Math.abs(q.x-player.x)<20&&Math.abs(q.y-player.y-23)<34){remove=true;damage()}if(remove)shots.splice(i,1)}for(let i=chips.length-1;i>=0;i--){let p=chips[i];if(Math.abs(player.x-p.x)<26&&Math.abs(player.y-p.y)<45){chips.splice(i,1);player.score++;el.chips.textContent=player.score+" / 8"}}}for(const p of plats){let x=p.x-cam;if(x+p.w<0||x>W)continue;ctx.fillStyle=p.y===0?"#276f79":"#7250a1";ctx.fillRect(x,H-(p.y+18),p.w,18);ctx.fillStyle="#ffd35f";ctx.fillRect(x,H-(p.y+18),p.w,4)}for(const chip of chips){ctx.fillStyle="#ffe35c";ctx.beginPath();ctx.arc(chip.x-cam,H-chip.y-20,9,0,7);ctx.fill()}for(const e of enemies)if(!e.dead)drawRobot(e.x,H-e.y-18,-1,true,.85);if(boss)drawRobot(boss.x,H-boss.y-18,-1,true,2.3);for(const q of shots){ctx.fillStyle=q.enemy?"#ff5a87":"#fff28a";ctx.fillRect(q.x-cam-5,H-q.y-23,10,4)}if(player&&(player.inv<=0||Math.floor(t/90)%2))drawRobot(player.x,H-player.y-18,player.dir);requestAnimationFrame(loop)}
-document.getElementById("left").addEventListener("pointerdown",()=>keys.l=true);document.getElementById("right").addEventListener("pointerdown",()=>keys.r=true);["pointerup","pointerleave","pointercancel"].forEach(t=>{left.addEventListener(t,()=>keys.l=false);right.addEventListener(t,()=>keys.r=false)});document.getElementById("jump").addEventListener("click",()=>{if(run&&player.ground)player.vy=.52});document.getElementById("shoot").addEventListener("pointerdown",()=>keys.fire=true);["pointerup","pointerleave","pointercancel"].forEach(t=>shoot.addEventListener(t,()=>keys.fire=false));el.start.addEventListener("click",reset);addEventListener("keydown",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")keys.l=true;if(k==="d"||k==="arrowright")keys.r=true;if((k==="w"||k==="arrowup")&&player&&player.ground)player.vy=.52;if(k===" ")keys.fire=true;if(k==="enter"&&!run)reset()});addEventListener("keyup",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")keys.l=false;if(k==="d"||k==="arrowright")keys.r=false;if(k===" ")keys.fire=false});loop(0);
-document.getElementById("left").addEventListener("pointerdown",()=>keys.l=true);document.getElementById("right").addEventListener("pointerdown",()=>keys.r=true);["pointerup","pointerleave","pointercancel"].forEach(t=>{left.addEventListener(t,()=>keys.l=false);right.addEventListener(t,()=>keys.r=false)});document.getElementById("jump").addEventListener("click",()=>{if(run&&player.ground)player.vy=.52});document.getElementById("shoot").addEventListener("pointerdown",()=>keys.fire=true);["pointerup","pointerleave","pointercancel"].forEach(t=>shoot.addEventListener(t,()=>keys.fire=false));el.start.addEventListener("click",reset);addEventListener("keydown",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")keys.l=true;if(k==="d"||k==="arrowright")keys.r=true;if((k==="w"||k==="arrowup")&&player&&player.ground)player.vy=.52;if(k===" ")keys.fire=true;if(k==="enter"&&!run)reset()});addEventListener("keyup",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")keys.l=false;if(k==="d"||k==="arrowright")keys.r=false;if(k===" ")keys.fire=false});loop(0);
+function addBullet(x,y,vx,enemy){bullets.push({x,y,vx,enemy})}function fireHero(){if(run)addBullet(hero.x+hero.dir*22,hero.y+30,hero.dir*8,false)}
+function addBullet(x,y,vx,enemy){bullets.push({x,y,vx,enemy})}function fireHero(){if(run)addBullet(hero.x+hero.dir*22,hero.y+30,hero.dir*8,false)}
+function createBoss(){boss={x:2730,y:75,hp:42,max:42,next:0};dom.boss.style.display="block";dom.fill.style.width="100%"}
+function createBoss(){boss={x:2730,y:75,hp:42,max:42,next:0};dom.boss.style.display="block";dom.fill.style.width="100%"}
+function win(){run=false;dom.copy.innerHTML="<b>Skyworks cleared!</b><br>You defeated the Iron Warden and recovered the core.";dom.start.textContent="PLAY AGAIN";dom.overlay.style.display="grid";dom.boss.style.display="none"}
+function win(){run=false;dom.copy.innerHTML="<b>Skyworks cleared!</b><br>You defeated the Iron Warden and recovered the core.";dom.start.textContent="PLAY AGAIN";dom.overlay.style.display="grid";dom.boss.style.display="none"}
+function drawBot(x,y,dir,enemy,scale=1){ctx.save();ctx.translate(x-camera,screenY(y));ctx.scale(dir*scale,scale);ctx.fillStyle=enemy?"#f36563":"#46cfc3";ctx.fillRect(-13,-30,26,30);ctx.fillRect(-11,-49,22,18);ctx.fillStyle=enemy?"#382747":"#1c4c69";ctx.fillRect(-8,-44,16,6);ctx.fillStyle=enemy?"#ffdf63":"#ffcc57";ctx.fillRect(12,-28,18,10);ctx.fillRect(-10,0,7,15);ctx.fillRect(4,0,7,15);ctx.restore()}
+function drawBot(x,y,dir,enemy,scale=1){ctx.save();ctx.translate(x-camera,screenY(y));ctx.scale(dir*scale,scale);ctx.fillStyle=enemy?"#f36563":"#46cfc3";ctx.fillRect(-13,-30,26,30);ctx.fillRect(-11,-49,22,18);ctx.fillStyle=enemy?"#382747":"#1c4c69";ctx.fillRect(-8,-44,16,6);ctx.fillStyle=enemy?"#ffdf63":"#ffcc57";ctx.fillRect(12,-28,18,10);ctx.fillRect(-10,0,7,15);ctx.fillRect(4,0,7,15);ctx.restore()}
+function loop(t){requestAnimationFrame(loop);const dt=Math.min(35,last?t-last:16);last=t;ctx.fillStyle="#80d3df";ctx.fillRect(0,0,W,H);const skyline=H*.56;ctx.fillStyle="#eff7d2";ctx.fillRect(0,skyline,W,H-skyline);for(let n=0;n<17;n++){const x=(n*300-camera*.22)%(W+300)-140,h=55+(n%4)*38;ctx.fillStyle=n%2?"#3d7e9a":"#286e8a";ctx.fillRect(x,skyline-h,88,h);ctx.fillStyle="#ffd05c";ctx.fillRect(x+14,skyline-h+20,15,6)}
+function loop(t){requestAnimationFrame(loop);const dt=Math.min(35,last?t-last:16);last=t;ctx.fillStyle="#80d3df";ctx.fillRect(0,0,W,H);const skyline=H*.56;ctx.fillStyle="#eff7d2";ctx.fillRect(0,skyline,W,H-skyline);for(let n=0;n<17;n++){const x=(n*300-camera*.22)%(W+300)-140,h=55+(n%4)*38;ctx.fillStyle=n%2?"#3d7e9a":"#286e8a";ctx.fillRect(x,skyline-h,88,h);ctx.fillStyle="#ffd05c";ctx.fillRect(x+14,skyline-h+20,15,6)}
+if(run){const dir=(held.left?-1:0)+(held.right?1:0);hero.x=Math.max(30,Math.min(2860,hero.x+dir*dt*.22));if(dir)hero.dir=dir;const old=hero.y;hero.vy-=dt*.00085;hero.y+=hero.vy*dt;const landing=floorAt(hero.x,hero.y,old);if(landing!==null&&hero.vy<=0){hero.y=landing;hero.vy=0;hero.ground=true}else hero.ground=false;if(hero.y<-100){hero.x=Math.max(70,hero.x-80);hero.y=0;hero.vy=0;hurt()}hero.inv=Math.max(0,hero.inv-dt);camera+=(hero.x-W*.35-camera)*.08;camera=Math.max(0,Math.min(2400, camera));if(held.fire&&t>nextFire){fireHero();nextFire=t+220}if(!boss&&hero.collected===8&&hero.x>2600)createBoss();
+if(run){const dir=(held.left?-1:0)+(held.right?1:0);hero.x=Math.max(30,Math.min(2860,hero.x+dir*dt*.22));if(dir)hero.dir=dir;const old=hero.y;hero.vy-=dt*.00085;hero.y+=hero.vy*dt;const landing=floorAt(hero.x,hero.y,old);if(landing!==null&&hero.vy<=0){hero.y=landing;hero.vy=0;hero.ground=true}else hero.ground=false;if(hero.y<-100){hero.x=Math.max(70,hero.x-80);hero.y=0;hero.vy=0;hurt()}hero.inv=Math.max(0,hero.inv-dt);camera+=(hero.x-W*.35-camera)*.08;camera=Math.max(0,Math.min(2400, camera));if(held.fire&&t>nextFire){fireHero();nextFire=t+220}if(!boss&&hero.collected===8&&hero.x>2600)createBoss();
+for(const d of drones){if(!d.dead&&Math.abs(hero.x-d.x)<35&&Math.abs(hero.y-d.y)<45)hurt();if(!d.dead&&Math.abs(hero.x-d.x)<300&&t>d.next){addBullet(d.x,d.y+24,-3.8,true);d.next=t+1250}}if(boss){boss.y=70+Math.sin(t*.002)*25;if(t>boss.next){addBullet(boss.x,boss.y+22,-4.8,true);boss.next=t+650}if(Math.abs(hero.x-boss.x)<65&&Math.abs(hero.y-boss.y)<65)hurt()}
+for(const d of drones){if(!d.dead&&Math.abs(hero.x-d.x)<35&&Math.abs(hero.y-d.y)<45)hurt();if(!d.dead&&Math.abs(hero.x-d.x)<300&&t>d.next){addBullet(d.x,d.y+24,-3.8,true);d.next=t+1250}}if(boss){boss.y=70+Math.sin(t*.002)*25;if(t>boss.next){addBullet(boss.x,boss.y+22,-4.8,true);boss.next=t+650}if(Math.abs(hero.x-boss.x)<65&&Math.abs(hero.y-boss.y)<65)hurt()}
+for(let i=bullets.length-1;i>=0;i--){const b=bullets[i];b.x+=b.vx*dt*.06;let remove=b.x<camera-60||b.x>camera+W+60;if(!b.enemy){for(const d of drones)if(!d.dead&&Math.abs(b.x-d.x)<26&&Math.abs(b.y-d.y)<30){d.hp--;remove=true;if(d.hp<=0)d.dead=true}if(boss&&Math.abs(b.x-boss.x)<56&&Math.abs(b.y-boss.y)<70){boss.hp--;remove=true;dom.fill.style.width=(boss.hp/boss.max*100)+"%";if(boss.hp<=0)win()}}else if(Math.abs(b.x-hero.x)<20&&Math.abs(b.y-(hero.y+25))<35){remove=true;hurt()}if(remove)bullets.splice(i,1)}
+for(let i=bullets.length-1;i>=0;i--){const b=bullets[i];b.x+=b.vx*dt*.06;let remove=b.x<camera-60||b.x>camera+W+60;if(!b.enemy){for(const d of drones)if(!d.dead&&Math.abs(b.x-d.x)<26&&Math.abs(b.y-d.y)<30){d.hp--;remove=true;if(d.hp<=0)d.dead=true}if(boss&&Math.abs(b.x-boss.x)<56&&Math.abs(b.y-boss.y)<70){boss.hp--;remove=true;dom.fill.style.width=(boss.hp/boss.max*100)+"%";if(boss.hp<=0)win()}}else if(Math.abs(b.x-hero.x)<20&&Math.abs(b.y-(hero.y+25))<35){remove=true;hurt()}if(remove)bullets.splice(i,1)}
+for(let i=chips.length-1;i>=0;i--){const p=chips[i];if(Math.abs(hero.x-p.x)<26&&Math.abs(hero.y-p.y)<45){chips.splice(i,1);hero.collected++;dom.chips.textContent=hero.collected+" / 8"}}}
+for(let i=chips.length-1;i>=0;i--){const p=chips[i];if(Math.abs(hero.x-p.x)<26&&Math.abs(hero.y-p.y)<45){chips.splice(i,1);hero.collected++;dom.chips.textContent=hero.collected+" / 8"}}}
+for(const p of platforms){const x=p.x-camera;if(x+p.w<0||x>W)continue;ctx.fillStyle=p.y===0?"#276f79":"#7050a2";ctx.fillRect(x,screenY(p.y)-18,p.w,18);ctx.fillStyle="#ffd35f";ctx.fillRect(x,screenY(p.y)-18,p.w,4)}for(const p of chips){ctx.fillStyle="#ffe35c";ctx.beginPath();ctx.arc(p.x-camera,screenY(p.y+25),9,0,Math.PI*2);ctx.fill()}for(const d of drones)if(!d.dead)drawBot(d.x,d.y,-1,true,.85);if(boss)drawBot(boss.x,boss.y,-1,true,2.25);for(const b of bullets){ctx.fillStyle=b.enemy?"#ff5a87":"#fff28a";ctx.fillRect(b.x-camera-5,screenY(b.y+25),10,4)}if(hero&&(hero.inv<=0||Math.floor(t/90)%2))drawBot(hero.x,hero.y,hero.dir,false);ctx.fillStyle="#fff";ctx.font="11px system-ui";if(run&&hero&&hero.collected<8)ctx.fillText("Collect all 8 energy chips",16,H-125)}
+for(const p of platforms){const x=p.x-camera;if(x+p.w<0||x>W)continue;ctx.fillStyle=p.y===0?"#276f79":"#7050a2";ctx.fillRect(x,screenY(p.y)-18,p.w,18);ctx.fillStyle="#ffd35f";ctx.fillRect(x,screenY(p.y)-18,p.w,4)}for(const p of chips){ctx.fillStyle="#ffe35c";ctx.beginPath();ctx.arc(p.x-camera,screenY(p.y+25),9,0,Math.PI*2);ctx.fill()}for(const d of drones)if(!d.dead)drawBot(d.x,d.y,-1,true,.85);if(boss)drawBot(boss.x,boss.y,-1,true,2.25);for(const b of bullets){ctx.fillStyle=b.enemy?"#ff5a87":"#fff28a";ctx.fillRect(b.x-camera-5,screenY(b.y+25),10,4)}if(hero&&(hero.inv<=0||Math.floor(t/90)%2))drawBot(hero.x,hero.y,hero.dir,false);ctx.fillStyle="#fff";ctx.font="11px system-ui";if(run&&hero&&hero.collected<8)ctx.fillText("Collect all 8 energy chips",16,H-125)}
+function hold(button,key){button.addEventListener("pointerdown",e=>{e.preventDefault();held[key]=true});["pointerup","pointerleave","pointercancel"].forEach(type=>button.addEventListener(type,()=>held[key]=false))}hold(dom.left,"left");hold(dom.right,"right");hold(dom.shoot,"fire");dom.jump.addEventListener("click",()=>{if(run&&hero.ground)hero.vy=.52});dom.start.addEventListener("click",reset);
+function hold(button,key){button.addEventListener("pointerdown",e=>{e.preventDefault();held[key]=true});["pointerup","pointerleave","pointercancel"].forEach(type=>button.addEventListener(type,()=>held[key]=false))}hold(dom.left,"left");hold(dom.right,"right");hold(dom.shoot,"fire");dom.jump.addEventListener("click",()=>{if(run&&hero.ground)hero.vy=.52});dom.start.addEventListener("click",reset);
+addEventListener("keydown",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")held.left=true;if(k==="d"||k==="arrowright")held.right=true;if((k==="w"||k==="arrowup")&&hero&&hero.ground)hero.vy=.52;if(k===" ")held.fire=true;if(k==="enter"&&!run)reset()});addEventListener("keyup",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")held.left=false;if(k==="d"||k==="arrowright")held.right=false;if(k===" ")held.fire=false});loop(0);
+addEventListener("keydown",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")held.left=true;if(k==="d"||k==="arrowright")held.right=true;if((k==="w"||k==="arrowup")&&hero&&hero.ground)hero.vy=.52;if(k===" ")held.fire=true;if(k==="enter"&&!run)reset()});addEventListener("keyup",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")held.left=false;if(k==="d"||k==="arrowright")held.right=false;if(k===" ")held.fire=false});loop(0);
← Histórico de versões