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

v4

@joaobarrosfranca · 8/12/2026, 4:01:36 PM

Diferença em relação à v3.

<!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:#76cddd;font-family:system-ui,sans-serif;touch-action:none}canvas{display:block}#hud{position:fixed;z-index:3;top:0;left:0;right:0;padding:18px;color:#fff;display:flex;justify-content:space-between;text-shadow:0 2px 6px #155a6d;pointer-events:none}.lab{font-size:10px;font-weight:1000;letter-spacing:1.8px}.num{font-size:28px;font-weight:1000}.lives{color:#ffdf66;font-size:19px;letter-spacing:2px}#boss{position:fixed;z-index:3;top:69px;left:18%;right:18%;display:none;text-align:center;color:white;font-size:10px;font-weight:1000;letter-spacing:2px}#meter{height:9px;border:2px solid white;background:#5b2337;border-radius:5px;overflow:hidden;margin-top:5px}#meter i{display:block;height:100%;background:linear-gradient(90deg,#ffdd50,#ff4d68);width:100%}.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:9px}.controls button{border:2px solid white;color:white;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer}.group button{width:53px;height:53px;border-radius:15px;background:#1687a4ce;font-size:23px}.group.action button{width:62px;height:62px;border-radius:50%;font-size:11px}.j{background:#8e55ce!important}.f{background:#ee7543!important}.controls button:active{transform:scale(.94)}#cover{position:fixed;z-index:9;inset:0;display:grid;place-items:center;padding:27px;text-align:center;color:white;background:linear-gradient(155deg,#006e8ee8,#1765a3df 48%,#f47b4cc4)}#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 0 21px;text-shadow:4px 4px 0 #075775}.title span{color:#ffdd61}.copy{font-size:16px;line-height:1.5;color:#effdff;margin:0 0 27px}#start{border:3px solid #fff0a3;border-radius:5px;background:#ef7245;color:white;padding:15px 28px;font-weight:1000;font-size:14px;letter-spacing:1px;box-shadow:0 5px 0 #9b3d3f;cursor:pointer}.hint{font-size:12px;color:#eaffff;margin-top:18px}
-</style></head><body>
-<div id="hud"><div><div class="lab">SECTOR</div><div class="num">01</div></div><div style="text-align:right"><div class="lab">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON COLOSSUS<div id="meter"><i id="bossFill"></i></div></div>
-<div class="controls"><div class="group"><button id="moveLeft">←</button><button id="moveRight">→</button></div><div class="group action"><button id="jumpButton" class="j">JUMP</button><button id="fireButton" class="f">BLAST</button></div></div>
-<div id="cover"><div id="card"><div class="tag">3D RUN & BLAST</div><div class="title">BOLT<br><span>RUNNER</span></div><p id="copy" class="copy">Dash through the skyworks, leap over danger, and blast the machines guarding the core.</p><button id="start">POWER UP</button><div class="hint">Move, jump and blast · Keyboard: A/D, W, Space</div></div></div>
-<script type="module">
-import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js";
-const scene=new THREE.Scene();scene.background=new THREE.Color(0x7bd1e1);scene.fog=new THREE.Fog(0x7bd1e1,18,68);
-const camera=new THREE.PerspectiveCamera(55,innerWidth/innerHeight,.1,140);camera.position.set(2,3.3,10);camera.lookAt(2,1,0);
-const renderer=new THREE.WebGLRenderer({antialias:true});renderer.setPixelRatio(Math.min(devicePixelRatio,2));renderer.setSize(innerWidth,innerHeight);renderer.outputColorSpace=THREE.SRGBColorSpace;document.body.appendChild(renderer.domElement);
-scene.add(new THREE.HemisphereLight(0xffffff,0x236a85,2.7));const sun=new THREE.DirectionalLight(0xffecae,2.4);sun.position.set(-10,15,8);scene.add(sun);
-const floor=new THREE.Mesh(new THREE.BoxGeometry(150,.45,5),new THREE.MeshStandardMaterial({color:0x216c77,roughness:.8}));floor.position.set(45,-.27,0);scene.add(floor);for(let n=0;n<43;n++){const h=2+Math.random()*8,b=new THREE.Mesh(new THREE.BoxGeometry(1.5,h,1.7),new THREE.MeshStandardMaterial({color:n%2?0x207b95:0x415f9b,roughness:.7}));b.position.set(-8+n*3.2,h/2,-5);scene.add(b)}
-function robot(){const g=new THREE.Group(),turq=new THREE.MeshStandardMaterial({color:0x46cfc3}),gold=new THREE.MeshStandardMaterial({color:0xffcb57}),dark=new THREE.MeshStandardMaterial({color:0x1b4867});let m=new THREE.Mesh(new THREE.BoxGeometry(.65,.82,.34),turq);m.position.y=1.1;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.62,.54,.5),turq);m.position.y=1.78;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.48,.16,.03),dark);m.position.set(0,1.8,-.27);g.add(m);[-1,1].forEach(s=>{const leg=new THREE.Mesh(new THREE.BoxGeometry(.2,.58,.24),turq);leg.position.set(s*.19,.38,0);g.add(leg)});m=new THREE.Mesh(new THREE.CylinderGeometry(.16,.19,.68,10),gold);m.rotation.z=Math.PI/2;m.position.set(.58,1.22,0);g.add(m);return g}
-const player=robot();player.position.set(0,.02,0);scene.add(player);
-const platforms=[];function makePlatform(x,y,w){const m=new THREE.Mesh(new THREE.BoxGeometry(w,.24,2.2),new THREE.MeshStandardMaterial({color:0x694da1,roughness:.6}));m.position.set(x,y,0);scene.add(m);platforms.push({x,y,w})}[[9,1.5,3],[17,2.2,3.5],[27,1.5,4],[37,2.5,3.4]].forEach(a=>makePlatform(a[0],a[1],a[2]));
-const enemies=[],bolts=[];function makeDrone(x){const g=new THREE.Group(),red=new THREE.MeshStandardMaterial({color:0xf46561}),dark=new THREE.MeshStandardMaterial({color:0x332646});let m=new THREE.Mesh(new THREE.SphereGeometry(.42,12,9),red);m.scale.z=.65;g.add(m);m=new THREE.Mesh(new THREE.SphereGeometry(.13,8,6),new THREE.MeshBasicMaterial({color:0xffff89}));m.position.z=-.28;g.add(m);[-1,1].forEach(s=>{const w=new THREE.Mesh(new THREE.BoxGeometry(.65,.09,.24),dark);w.position.set(s*.43,0,.03);g.add(w)});g.position.set(x,.66,0);scene.add(g);enemies.push({g,hp:3,boss:false,next:0})}
-function makeBoss(){const g=new THREE.Group(),red=new THREE.MeshStandardMaterial({color:0x92355b}),dark=new THREE.MeshStandardMaterial({color:0x33213e});let m=new THREE.Mesh(new THREE.BoxGeometry(1.8,2.1,.7),red);m.position.y=1.16;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(1.35,.7,.7),dark);m.position.y=2.52;g.add(m);[-1,1].forEach(s=>{const a=new THREE.Mesh(new THREE.BoxGeometry(.52,1.35,.6),red);a.position.set(s*1.15,1.2,0);g.add(a)});g.position.set(52,.02,0);scene.add(g);enemies.push({g,hp:35,max:35,boss:true,next:0});bossOn=true;el.boss.style.display="block";el.fill.style.width="100%"}[6,13,21,32,41].forEach(makeDrone);
-function makeBolt(isPlayer,x,y){const m=new THREE.Mesh(new THREE.BoxGeometry(.5,.1,.1),new THREE.MeshBasicMaterial({color:isPlayer?0xfff18a:0xff5a84}));m.position.set(x,y,0);scene.add(m);bolts.push({m,player:isPlayer})}
-const el={lives:document.getElementById("lives"),cover:document.getElementById("cover"),copy:document.getElementById("copy"),start:document.getElementById("start"),boss:document.getElementById("boss"),fill:document.getElementById("bossFill"),left:document.getElementById("moveLeft"),right:document.getElementById("moveRight"),jump:document.getElementById("jumpButton"),fire:document.getElementById("fireButton")};
-let running=false,lives=3,dir=0,velocity=0,firing=false,nextShot=0,last=0,bossOn=false;
-function showLives(){el.lives.textContent=Array(lives).fill("●").join(" ")||"—"}function damage(){lives--;showLives();if(lives<=0){running=false;el.copy.innerHTML="The skyworks pushed back.<br>Recharge and clear the sector!";el.start.textContent="REBOOT";el.cover.style.display="grid";el.boss.style.display="none"}}function doJump(){if(running&&Math.abs(velocity)<.002&&player.position.y<.04)velocity=.011}
-function removeEnemy(i){const e=enemies[i];scene.remove(e.g);enemies.splice(i,1);if(e.boss){running=false;el.copy.innerHTML="<b>Sector cleared!</b><br>You defeated the Iron Colossus.";el.start.textContent="PLAY AGAIN";el.cover.style.display="grid";el.boss.style.display="none"}}
-function hold(button,value){button.addEventListener("pointerdown",e=>{e.preventDefault();dir=value});["pointerup","pointerleave","pointercancel"].forEach(t=>button.addEventListener(t,()=>dir=0))}hold(el.left,-1);hold(el.right,1);el.jump.addEventListener("click",doJump);el.fire.addEventListener("pointerdown",e=>{e.preventDefault();firing=true});["pointerup","pointerleave","pointercancel"].forEach(t=>el.fire.addEventListener(t,()=>firing=false));el.start.addEventListener("click",()=>{lives=3;showLives();running=true;el.cover.style.display="none";last=0});
-addEventListener("keydown",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")dir=-1;if(k==="d"||k==="arrowright")dir=1;if(k==="w"||k==="arrowup")doJump();if(k===" ")firing=true;if(k==="enter"&&!running)el.start.click()});addEventListener("keyup",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft"||k==="d"||k==="arrowright")dir=0;if(k===" ")firing=false});
-function loop(t){requestAnimationFrame(loop);const dt=Math.min(35,last?t-last:16);last=t;if(running){player.position.x=Math.max(-4,Math.min(53,player.position.x+dir*dt*.005));const oldY=player.position.y;velocity-=dt*.000035;player.position.y+=velocity*dt;if(player.position.y<=.02){player.position.y=.02;velocity=0}for(const p of platforms){if(velocity<=0&&Math.abs(player.position.x-p.x)<p.w/2-.12&&oldY>=p.y+.17&&player.position.y<=p.y+.17){player.position.y=p.y+.17;velocity=0}}if(!bossOn&&player.position.x>45&&enemies.length===0)makeBoss();if(firing&&t>nextShot){makeBolt(true,player.position.x+.9,player.position.y+1.25);nextShot=t+220}for(const e of enemies){if(player.position.x>e.g.position.x-6&&t>e.next){makeBolt(false,e.g.position.x-.8,e.g.position.y+1);e.next=t+(e.boss?700:1500)}}for(let i=bolts.length-1;i>=0;i--){const b=bolts[i];b.m.position.x+=b.player?dt*.045:-dt*.03;if(b.player){for(let j=enemies.length-1;j>=0;j--){const e=enemies[j];if(Math.abs(b.m.position.x-e.g.position.x)<(e.boss?1.45:.55)&&Math.abs(b.m.position.y-e.g.position.y-1)<(e.boss?1.5:.65)){e.hp--;scene.remove(b.m);bolts.splice(i,1);if(e.boss)el.fill.style.width=e.hp/e.max*100+"%";if(e.hp<=0)removeEnemy(j);break}}}else if(Math.abs(b.m.position.x-player.position.x)<.5&&Math.abs(b.m.position.y-player.position.y-1)<.65){scene.remove(b.m);bolts.splice(i,1);damage();continue}if(b.m.position.x>62||b.m.position.x<-7){scene.remove(b.m);bolts.splice(i,1)}}camera.position.x+=(player.position.x+2-camera.position.x)*.06;camera.lookAt(player.position.x+3,1.2,0)}renderer.render(scene,camera)}
-addEventListener("resize",()=>{camera.aspect=innerWidth/innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth,innerHeight)});showLives();loop(0);
+*{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>
</script></body></html>

v4

@joaobarrosfranca · 8/12/2026, 4:01:36 PM

Diferença em relação à v3.

<!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:#76cddd;font-family:system-ui,sans-serif;touch-action:none}canvas{display:block}#hud{position:fixed;z-index:3;top:0;left:0;right:0;padding:18px;color:#fff;display:flex;justify-content:space-between;text-shadow:0 2px 6px #155a6d;pointer-events:none}.lab{font-size:10px;font-weight:1000;letter-spacing:1.8px}.num{font-size:28px;font-weight:1000}.lives{color:#ffdf66;font-size:19px;letter-spacing:2px}#boss{position:fixed;z-index:3;top:69px;left:18%;right:18%;display:none;text-align:center;color:white;font-size:10px;font-weight:1000;letter-spacing:2px}#meter{height:9px;border:2px solid white;background:#5b2337;border-radius:5px;overflow:hidden;margin-top:5px}#meter i{display:block;height:100%;background:linear-gradient(90deg,#ffdd50,#ff4d68);width:100%}.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:9px}.controls button{border:2px solid white;color:white;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer}.group button{width:53px;height:53px;border-radius:15px;background:#1687a4ce;font-size:23px}.group.action button{width:62px;height:62px;border-radius:50%;font-size:11px}.j{background:#8e55ce!important}.f{background:#ee7543!important}.controls button:active{transform:scale(.94)}#cover{position:fixed;z-index:9;inset:0;display:grid;place-items:center;padding:27px;text-align:center;color:white;background:linear-gradient(155deg,#006e8ee8,#1765a3df 48%,#f47b4cc4)}#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 0 21px;text-shadow:4px 4px 0 #075775}.title span{color:#ffdd61}.copy{font-size:16px;line-height:1.5;color:#effdff;margin:0 0 27px}#start{border:3px solid #fff0a3;border-radius:5px;background:#ef7245;color:white;padding:15px 28px;font-weight:1000;font-size:14px;letter-spacing:1px;box-shadow:0 5px 0 #9b3d3f;cursor:pointer}.hint{font-size:12px;color:#eaffff;margin-top:18px}
-</style></head><body>
-<div id="hud"><div><div class="lab">SECTOR</div><div class="num">01</div></div><div style="text-align:right"><div class="lab">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON COLOSSUS<div id="meter"><i id="bossFill"></i></div></div>
-<div class="controls"><div class="group"><button id="moveLeft">←</button><button id="moveRight">→</button></div><div class="group action"><button id="jumpButton" class="j">JUMP</button><button id="fireButton" class="f">BLAST</button></div></div>
-<div id="cover"><div id="card"><div class="tag">3D RUN & BLAST</div><div class="title">BOLT<br><span>RUNNER</span></div><p id="copy" class="copy">Dash through the skyworks, leap over danger, and blast the machines guarding the core.</p><button id="start">POWER UP</button><div class="hint">Move, jump and blast · Keyboard: A/D, W, Space</div></div></div>
-<script type="module">
-import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js";
-const scene=new THREE.Scene();scene.background=new THREE.Color(0x7bd1e1);scene.fog=new THREE.Fog(0x7bd1e1,18,68);
-const camera=new THREE.PerspectiveCamera(55,innerWidth/innerHeight,.1,140);camera.position.set(2,3.3,10);camera.lookAt(2,1,0);
-const renderer=new THREE.WebGLRenderer({antialias:true});renderer.setPixelRatio(Math.min(devicePixelRatio,2));renderer.setSize(innerWidth,innerHeight);renderer.outputColorSpace=THREE.SRGBColorSpace;document.body.appendChild(renderer.domElement);
-scene.add(new THREE.HemisphereLight(0xffffff,0x236a85,2.7));const sun=new THREE.DirectionalLight(0xffecae,2.4);sun.position.set(-10,15,8);scene.add(sun);
-const floor=new THREE.Mesh(new THREE.BoxGeometry(150,.45,5),new THREE.MeshStandardMaterial({color:0x216c77,roughness:.8}));floor.position.set(45,-.27,0);scene.add(floor);for(let n=0;n<43;n++){const h=2+Math.random()*8,b=new THREE.Mesh(new THREE.BoxGeometry(1.5,h,1.7),new THREE.MeshStandardMaterial({color:n%2?0x207b95:0x415f9b,roughness:.7}));b.position.set(-8+n*3.2,h/2,-5);scene.add(b)}
-function robot(){const g=new THREE.Group(),turq=new THREE.MeshStandardMaterial({color:0x46cfc3}),gold=new THREE.MeshStandardMaterial({color:0xffcb57}),dark=new THREE.MeshStandardMaterial({color:0x1b4867});let m=new THREE.Mesh(new THREE.BoxGeometry(.65,.82,.34),turq);m.position.y=1.1;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.62,.54,.5),turq);m.position.y=1.78;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.48,.16,.03),dark);m.position.set(0,1.8,-.27);g.add(m);[-1,1].forEach(s=>{const leg=new THREE.Mesh(new THREE.BoxGeometry(.2,.58,.24),turq);leg.position.set(s*.19,.38,0);g.add(leg)});m=new THREE.Mesh(new THREE.CylinderGeometry(.16,.19,.68,10),gold);m.rotation.z=Math.PI/2;m.position.set(.58,1.22,0);g.add(m);return g}
-const player=robot();player.position.set(0,.02,0);scene.add(player);
-const platforms=[];function makePlatform(x,y,w){const m=new THREE.Mesh(new THREE.BoxGeometry(w,.24,2.2),new THREE.MeshStandardMaterial({color:0x694da1,roughness:.6}));m.position.set(x,y,0);scene.add(m);platforms.push({x,y,w})}[[9,1.5,3],[17,2.2,3.5],[27,1.5,4],[37,2.5,3.4]].forEach(a=>makePlatform(a[0],a[1],a[2]));
-const enemies=[],bolts=[];function makeDrone(x){const g=new THREE.Group(),red=new THREE.MeshStandardMaterial({color:0xf46561}),dark=new THREE.MeshStandardMaterial({color:0x332646});let m=new THREE.Mesh(new THREE.SphereGeometry(.42,12,9),red);m.scale.z=.65;g.add(m);m=new THREE.Mesh(new THREE.SphereGeometry(.13,8,6),new THREE.MeshBasicMaterial({color:0xffff89}));m.position.z=-.28;g.add(m);[-1,1].forEach(s=>{const w=new THREE.Mesh(new THREE.BoxGeometry(.65,.09,.24),dark);w.position.set(s*.43,0,.03);g.add(w)});g.position.set(x,.66,0);scene.add(g);enemies.push({g,hp:3,boss:false,next:0})}
-function makeBoss(){const g=new THREE.Group(),red=new THREE.MeshStandardMaterial({color:0x92355b}),dark=new THREE.MeshStandardMaterial({color:0x33213e});let m=new THREE.Mesh(new THREE.BoxGeometry(1.8,2.1,.7),red);m.position.y=1.16;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(1.35,.7,.7),dark);m.position.y=2.52;g.add(m);[-1,1].forEach(s=>{const a=new THREE.Mesh(new THREE.BoxGeometry(.52,1.35,.6),red);a.position.set(s*1.15,1.2,0);g.add(a)});g.position.set(52,.02,0);scene.add(g);enemies.push({g,hp:35,max:35,boss:true,next:0});bossOn=true;el.boss.style.display="block";el.fill.style.width="100%"}[6,13,21,32,41].forEach(makeDrone);
-function makeBolt(isPlayer,x,y){const m=new THREE.Mesh(new THREE.BoxGeometry(.5,.1,.1),new THREE.MeshBasicMaterial({color:isPlayer?0xfff18a:0xff5a84}));m.position.set(x,y,0);scene.add(m);bolts.push({m,player:isPlayer})}
-const el={lives:document.getElementById("lives"),cover:document.getElementById("cover"),copy:document.getElementById("copy"),start:document.getElementById("start"),boss:document.getElementById("boss"),fill:document.getElementById("bossFill"),left:document.getElementById("moveLeft"),right:document.getElementById("moveRight"),jump:document.getElementById("jumpButton"),fire:document.getElementById("fireButton")};
-let running=false,lives=3,dir=0,velocity=0,firing=false,nextShot=0,last=0,bossOn=false;
-function showLives(){el.lives.textContent=Array(lives).fill("●").join(" ")||"—"}function damage(){lives--;showLives();if(lives<=0){running=false;el.copy.innerHTML="The skyworks pushed back.<br>Recharge and clear the sector!";el.start.textContent="REBOOT";el.cover.style.display="grid";el.boss.style.display="none"}}function doJump(){if(running&&Math.abs(velocity)<.002&&player.position.y<.04)velocity=.011}
-function removeEnemy(i){const e=enemies[i];scene.remove(e.g);enemies.splice(i,1);if(e.boss){running=false;el.copy.innerHTML="<b>Sector cleared!</b><br>You defeated the Iron Colossus.";el.start.textContent="PLAY AGAIN";el.cover.style.display="grid";el.boss.style.display="none"}}
-function hold(button,value){button.addEventListener("pointerdown",e=>{e.preventDefault();dir=value});["pointerup","pointerleave","pointercancel"].forEach(t=>button.addEventListener(t,()=>dir=0))}hold(el.left,-1);hold(el.right,1);el.jump.addEventListener("click",doJump);el.fire.addEventListener("pointerdown",e=>{e.preventDefault();firing=true});["pointerup","pointerleave","pointercancel"].forEach(t=>el.fire.addEventListener(t,()=>firing=false));el.start.addEventListener("click",()=>{lives=3;showLives();running=true;el.cover.style.display="none";last=0});
-addEventListener("keydown",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")dir=-1;if(k==="d"||k==="arrowright")dir=1;if(k==="w"||k==="arrowup")doJump();if(k===" ")firing=true;if(k==="enter"&&!running)el.start.click()});addEventListener("keyup",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft"||k==="d"||k==="arrowright")dir=0;if(k===" ")firing=false});
-function loop(t){requestAnimationFrame(loop);const dt=Math.min(35,last?t-last:16);last=t;if(running){player.position.x=Math.max(-4,Math.min(53,player.position.x+dir*dt*.005));const oldY=player.position.y;velocity-=dt*.000035;player.position.y+=velocity*dt;if(player.position.y<=.02){player.position.y=.02;velocity=0}for(const p of platforms){if(velocity<=0&&Math.abs(player.position.x-p.x)<p.w/2-.12&&oldY>=p.y+.17&&player.position.y<=p.y+.17){player.position.y=p.y+.17;velocity=0}}if(!bossOn&&player.position.x>45&&enemies.length===0)makeBoss();if(firing&&t>nextShot){makeBolt(true,player.position.x+.9,player.position.y+1.25);nextShot=t+220}for(const e of enemies){if(player.position.x>e.g.position.x-6&&t>e.next){makeBolt(false,e.g.position.x-.8,e.g.position.y+1);e.next=t+(e.boss?700:1500)}}for(let i=bolts.length-1;i>=0;i--){const b=bolts[i];b.m.position.x+=b.player?dt*.045:-dt*.03;if(b.player){for(let j=enemies.length-1;j>=0;j--){const e=enemies[j];if(Math.abs(b.m.position.x-e.g.position.x)<(e.boss?1.45:.55)&&Math.abs(b.m.position.y-e.g.position.y-1)<(e.boss?1.5:.65)){e.hp--;scene.remove(b.m);bolts.splice(i,1);if(e.boss)el.fill.style.width=e.hp/e.max*100+"%";if(e.hp<=0)removeEnemy(j);break}}}else if(Math.abs(b.m.position.x-player.position.x)<.5&&Math.abs(b.m.position.y-player.position.y-1)<.65){scene.remove(b.m);bolts.splice(i,1);damage();continue}if(b.m.position.x>62||b.m.position.x<-7){scene.remove(b.m);bolts.splice(i,1)}}camera.position.x+=(player.position.x+2-camera.position.x)*.06;camera.lookAt(player.position.x+3,1.2,0)}renderer.render(scene,camera)}
-addEventListener("resize",()=>{camera.aspect=innerWidth/innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth,innerHeight)});showLives();loop(0);
+*{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>
</script></body></html>
+<script>
+<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;
+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 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 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 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 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 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)}
+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)}
+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);
← Histórico de versões