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

v2

@joaobarrosfranca · 8/12/2026, 3:42:31 PM

Diferença em relação à v1.

-<!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"><title>Bolt Runner 3D</title>
-<style>
-*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden;background:#76cddd;font-family:system-ui,-apple-system,sans-serif;touch-action:none}canvas{display:block}#hud{position:fixed;z-index:5;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}.label{font-size:10px;font-weight:1000;letter-spacing:1.8px}.value{font-size:28px;line-height:1;font-weight:1000}.right{text-align:right}.lives{font-size:19px;color:#ffdf66;letter-spacing:2px}#bossHud{position:fixed;z-index:5;top:71px;left:18%;right:18%;display:none;text-align:center;font-size:10px;letter-spacing:2px;font-weight:1000;color:white;text-shadow:0 2px 5px #155a6d}.bar{height:9px;background:#5b2337;border:2px solid #fff;border-radius:5px;overflow:hidden;margin-top:5px}.fill{height:100%;background:linear-gradient(90deg,#ffdd50,#ff4d68);width:100%;transition:width .1s}.controls{position:fixed;z-index:6;left:0;right:0;bottom:17px;padding:0 14px;display:flex;justify-content:space-between;align-items:end}.move,.action{display:flex;gap:9px}.controls button{border:2px solid #fff;color:#fff;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer;user-select:none}.move button{width:53px;height:53px;border-radius:15px;background:#1687a4ce;font-size:23px}.action button{width:62px;height:62px;border-radius:50%;font-size:11px;letter-spacing:.3px}.jump{background:#8e55ce}.blast{background:#ee7543}.controls button:active{transform:scale(.94);filter:brightness(1.2)}#cover{position:fixed;z-index:10;inset:0;display:grid;place-items:center;padding:27px;text-align:center;color:#fff;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:#fff;padding:15px 28px;font-weight:1000;font-size:14px;letter-spacing:1px;box-shadow:0 5px 0 #9b3d3f;cursor:pointer}#start:active{transform:translateY(3px);box-shadow:0 2px 0 #9b3d3f}.hint{font-size:12px;color:#eaffff;margin-top:18px}
-</style></head><body>
-<div id="hud"><div><div class="label">SECTOR</div><div id="sector" class="value">01</div></div><div class="right"><div class="label">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="bossHud">IRON COLOSSUS<div class="bar"><div id="bossFill" class="fill"></div></div></div>
-<div class="controls"><div class="move"><button id="left">←</button><button id="right">→</button></div><div class="action"><button id="jump" class="jump">JUMP</button><button id="blast" class="blast">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" type="button">POWER UP</button><div class="hint">Move, jump and blast · Keyboard: A/D, W, Space</div></div></div>
+<!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}.label{font-size:10px;font-weight:1000;letter-spacing:1.8px}.value{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;text-shadow:0 2px 5px #155a6d}#bar{height:9px;border:2px solid white;background:#5b2337;border-radius:5px;overflow:hidden;margin-top:5px}#fill{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}.controls button{border:2px solid white;color:white;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer}.move,.action{display:flex;gap:9px}.move button{width:53px;height:53px;border-radius:15px;background:#1687a4ce;font-size:23px}.action button{width:62px;height:62px;border-radius:50%;font-size:11px}.jump{background:#8e55ce}.blast{background:#ee7543}.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="label">SECTOR</div><div class="value">01</div></div><div style="text-align:right"><div class="label">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON COLOSSUS<div id="bar"><div id="fill"></div></div></div><div class="controls"><div class="move"><button id="left">←</button><button id="right">→</button></div><div class="action"><button id="jump" class="jump">JUMP</button><button id="blast" class="blast">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;renderer.shadowMap.enabled=true;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);sun.castShadow=true;scene.add(sun);
-const ground=new THREE.Mesh(new THREE.BoxGeometry(150,.45,5),new THREE.MeshStandardMaterial({color:0x216c77,roughness:.8}));ground.position.set(45,-.27,0);ground.receiveShadow=true;scene.add(ground);
-const trimMat=new THREE.MeshStandardMaterial({color:0xffc855,emissive:0xb26318,emissiveIntensity:.6});for(let x=-20;x<120;x+=3){const t=new THREE.Mesh(new THREE.BoxGeometry(1.2,.1,5.05),trimMat);t.position.set(x,.01,0);scene.add(t)}
-for(let i=0;i<45;i++){const h=2+Math.random()*8,w=1+Math.random()*2;const building=new THREE.Mesh(new THREE.BoxGeometry(w,h,1.7),new THREE.MeshStandardMaterial({color:Math.random()<.5?0x207b95:0x415f9b,roughness:.7}));building.position.set(-9+i*3.2,h/2,-4-Math.random()*5);scene.add(building);const light=new THREE.Mesh(new THREE.BoxGeometry(w*.58,.12,.04),new THREE.MeshBasicMaterial({color:Math.random()<.5?0xffd160:0xa1ffff}));light.position.set(building.position.x,h*.62,building.position.z+.9);scene.add(light)}
-function makeRobot(){const g=new THREE.Group(),suit=new THREE.MeshStandardMaterial({color:0x46cfc3,roughness:.42,metalness:.12}),accent=new THREE.MeshStandardMaterial({color:0xffcb57,roughness:.38}),dark=new THREE.MeshStandardMaterial({color:0x1b4867,roughness:.5});const torso=new THREE.Mesh(new THREE.BoxGeometry(.65,.82,.34),suit);torso.position.y=1.1;g.add(torso);const head=new THREE.Mesh(new THREE.BoxGeometry(.62,.54,.5),suit);head.position.y=1.78;g.add(head);const visor=new THREE.Mesh(new THREE.BoxGeometry(.48,.16,.03),dark);visor.position.set(0,1.8,-.27);g.add(visor);[-1,1].forEach(s=>{const leg=new THREE.Mesh(new THREE.BoxGeometry(.2,.58,.24),suit);leg.position.set(s*.19,.38,0);g.add(leg)});const arm=new THREE.Mesh(new THREE.CylinderGeometry(.16,.19,.68,10),accent);arm.rotation.z=Math.PI/2;arm.position.set(.58,1.22,0);g.add(arm);const cannon=new THREE.Mesh(new THREE.CylinderGeometry(.17,.2,.45,10),dark);cannon.rotation.z=Math.PI/2;cannon.position.set(.93,1.22,0);g.add(cannon);return g}
+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;renderer.shadowMap.enabled=true;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 i=0;i<44;i++){const h=2+Math.random()*8,b=new THREE.Mesh(new THREE.BoxGeometry(1.5,h,1.7),new THREE.MeshStandardMaterial({color:i%2?0x207b95:0x415f9b,roughness:.7}));b.position.set(-8+i*3.2,h/2,-5);scene.add(b)}
+function robot(){const g=new THREE.Group(),a=new THREE.MeshStandardMaterial({color:0x46cfc3,roughness:.42}),b=new THREE.MeshStandardMaterial({color:0xffcb57}),d=new THREE.MeshStandardMaterial({color:0x1b4867});let m=new THREE.Mesh(new THREE.BoxGeometry(.65,.82,.34),a);m.position.y=1.1;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.62,.54,.5),a);m.position.y=1.78;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.48,.16,.03),d);m.position.set(0,1.8,-.27);g.add(m);[-1,1].forEach(s=>{let l=new THREE.Mesh(new THREE.BoxGeometry(.2,.58,.24),a);l.position.set(s*.19,.38,0);g.add(l)});m=new THREE.Mesh(new THREE.CylinderGeometry(.16,.19,.68,10),b);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 platform(x,y,w){let p=new THREE.Mesh(new THREE.BoxGeometry(w,.24,2.2),new THREE.MeshStandardMaterial({color:0x694da1,roughness:.6}));p.position.set(x,y,0);scene.add(p);platforms.push({x,y,w})}[ [9,1.5,3],[17,2.2,3.5],[27,1.5,4],[37,2.5,3.4] ].forEach(v=>platform(...v));
+const enemies=[],bolts=[];function enemy(x){const g=new THREE.Group(),a=new THREE.MeshStandardMaterial({color:0xf46561,roughness:.4}),d=new THREE.MeshStandardMaterial({color:0x332646});let m=new THREE.Mesh(new THREE.SphereGeometry(.42,12,9),a);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=>{let w=new THREE.Mesh(new THREE.BoxGeometry(.65,.09,.24),d);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})}
</script></body></html>

v2

@joaobarrosfranca · 8/12/2026, 3:42:31 PM

Diferença em relação à v1.

-<!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"><title>Bolt Runner 3D</title>
-<style>
-*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden;background:#76cddd;font-family:system-ui,-apple-system,sans-serif;touch-action:none}canvas{display:block}#hud{position:fixed;z-index:5;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}.label{font-size:10px;font-weight:1000;letter-spacing:1.8px}.value{font-size:28px;line-height:1;font-weight:1000}.right{text-align:right}.lives{font-size:19px;color:#ffdf66;letter-spacing:2px}#bossHud{position:fixed;z-index:5;top:71px;left:18%;right:18%;display:none;text-align:center;font-size:10px;letter-spacing:2px;font-weight:1000;color:white;text-shadow:0 2px 5px #155a6d}.bar{height:9px;background:#5b2337;border:2px solid #fff;border-radius:5px;overflow:hidden;margin-top:5px}.fill{height:100%;background:linear-gradient(90deg,#ffdd50,#ff4d68);width:100%;transition:width .1s}.controls{position:fixed;z-index:6;left:0;right:0;bottom:17px;padding:0 14px;display:flex;justify-content:space-between;align-items:end}.move,.action{display:flex;gap:9px}.controls button{border:2px solid #fff;color:#fff;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer;user-select:none}.move button{width:53px;height:53px;border-radius:15px;background:#1687a4ce;font-size:23px}.action button{width:62px;height:62px;border-radius:50%;font-size:11px;letter-spacing:.3px}.jump{background:#8e55ce}.blast{background:#ee7543}.controls button:active{transform:scale(.94);filter:brightness(1.2)}#cover{position:fixed;z-index:10;inset:0;display:grid;place-items:center;padding:27px;text-align:center;color:#fff;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:#fff;padding:15px 28px;font-weight:1000;font-size:14px;letter-spacing:1px;box-shadow:0 5px 0 #9b3d3f;cursor:pointer}#start:active{transform:translateY(3px);box-shadow:0 2px 0 #9b3d3f}.hint{font-size:12px;color:#eaffff;margin-top:18px}
-</style></head><body>
-<div id="hud"><div><div class="label">SECTOR</div><div id="sector" class="value">01</div></div><div class="right"><div class="label">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="bossHud">IRON COLOSSUS<div class="bar"><div id="bossFill" class="fill"></div></div></div>
-<div class="controls"><div class="move"><button id="left">←</button><button id="right">→</button></div><div class="action"><button id="jump" class="jump">JUMP</button><button id="blast" class="blast">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" type="button">POWER UP</button><div class="hint">Move, jump and blast · Keyboard: A/D, W, Space</div></div></div>
+<!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}.label{font-size:10px;font-weight:1000;letter-spacing:1.8px}.value{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;text-shadow:0 2px 5px #155a6d}#bar{height:9px;border:2px solid white;background:#5b2337;border-radius:5px;overflow:hidden;margin-top:5px}#fill{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}.controls button{border:2px solid white;color:white;font-weight:1000;box-shadow:0 4px 11px #16485b8a;cursor:pointer}.move,.action{display:flex;gap:9px}.move button{width:53px;height:53px;border-radius:15px;background:#1687a4ce;font-size:23px}.action button{width:62px;height:62px;border-radius:50%;font-size:11px}.jump{background:#8e55ce}.blast{background:#ee7543}.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="label">SECTOR</div><div class="value">01</div></div><div style="text-align:right"><div class="label">LIVES</div><div id="lives" class="lives">● ● ●</div></div></div><div id="boss">IRON COLOSSUS<div id="bar"><div id="fill"></div></div></div><div class="controls"><div class="move"><button id="left">←</button><button id="right">→</button></div><div class="action"><button id="jump" class="jump">JUMP</button><button id="blast" class="blast">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;renderer.shadowMap.enabled=true;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);sun.castShadow=true;scene.add(sun);
-const ground=new THREE.Mesh(new THREE.BoxGeometry(150,.45,5),new THREE.MeshStandardMaterial({color:0x216c77,roughness:.8}));ground.position.set(45,-.27,0);ground.receiveShadow=true;scene.add(ground);
-const trimMat=new THREE.MeshStandardMaterial({color:0xffc855,emissive:0xb26318,emissiveIntensity:.6});for(let x=-20;x<120;x+=3){const t=new THREE.Mesh(new THREE.BoxGeometry(1.2,.1,5.05),trimMat);t.position.set(x,.01,0);scene.add(t)}
-for(let i=0;i<45;i++){const h=2+Math.random()*8,w=1+Math.random()*2;const building=new THREE.Mesh(new THREE.BoxGeometry(w,h,1.7),new THREE.MeshStandardMaterial({color:Math.random()<.5?0x207b95:0x415f9b,roughness:.7}));building.position.set(-9+i*3.2,h/2,-4-Math.random()*5);scene.add(building);const light=new THREE.Mesh(new THREE.BoxGeometry(w*.58,.12,.04),new THREE.MeshBasicMaterial({color:Math.random()<.5?0xffd160:0xa1ffff}));light.position.set(building.position.x,h*.62,building.position.z+.9);scene.add(light)}
-function makeRobot(){const g=new THREE.Group(),suit=new THREE.MeshStandardMaterial({color:0x46cfc3,roughness:.42,metalness:.12}),accent=new THREE.MeshStandardMaterial({color:0xffcb57,roughness:.38}),dark=new THREE.MeshStandardMaterial({color:0x1b4867,roughness:.5});const torso=new THREE.Mesh(new THREE.BoxGeometry(.65,.82,.34),suit);torso.position.y=1.1;g.add(torso);const head=new THREE.Mesh(new THREE.BoxGeometry(.62,.54,.5),suit);head.position.y=1.78;g.add(head);const visor=new THREE.Mesh(new THREE.BoxGeometry(.48,.16,.03),dark);visor.position.set(0,1.8,-.27);g.add(visor);[-1,1].forEach(s=>{const leg=new THREE.Mesh(new THREE.BoxGeometry(.2,.58,.24),suit);leg.position.set(s*.19,.38,0);g.add(leg)});const arm=new THREE.Mesh(new THREE.CylinderGeometry(.16,.19,.68,10),accent);arm.rotation.z=Math.PI/2;arm.position.set(.58,1.22,0);g.add(arm);const cannon=new THREE.Mesh(new THREE.CylinderGeometry(.17,.2,.45,10),dark);cannon.rotation.z=Math.PI/2;cannon.position.set(.93,1.22,0);g.add(cannon);return g}
+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;renderer.shadowMap.enabled=true;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 i=0;i<44;i++){const h=2+Math.random()*8,b=new THREE.Mesh(new THREE.BoxGeometry(1.5,h,1.7),new THREE.MeshStandardMaterial({color:i%2?0x207b95:0x415f9b,roughness:.7}));b.position.set(-8+i*3.2,h/2,-5);scene.add(b)}
+function robot(){const g=new THREE.Group(),a=new THREE.MeshStandardMaterial({color:0x46cfc3,roughness:.42}),b=new THREE.MeshStandardMaterial({color:0xffcb57}),d=new THREE.MeshStandardMaterial({color:0x1b4867});let m=new THREE.Mesh(new THREE.BoxGeometry(.65,.82,.34),a);m.position.y=1.1;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.62,.54,.5),a);m.position.y=1.78;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(.48,.16,.03),d);m.position.set(0,1.8,-.27);g.add(m);[-1,1].forEach(s=>{let l=new THREE.Mesh(new THREE.BoxGeometry(.2,.58,.24),a);l.position.set(s*.19,.38,0);g.add(l)});m=new THREE.Mesh(new THREE.CylinderGeometry(.16,.19,.68,10),b);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 platform(x,y,w){let p=new THREE.Mesh(new THREE.BoxGeometry(w,.24,2.2),new THREE.MeshStandardMaterial({color:0x694da1,roughness:.6}));p.position.set(x,y,0);scene.add(p);platforms.push({x,y,w})}[ [9,1.5,3],[17,2.2,3.5],[27,1.5,4],[37,2.5,3.4] ].forEach(v=>platform(...v));
+const enemies=[],bolts=[];function enemy(x){const g=new THREE.Group(),a=new THREE.MeshStandardMaterial({color:0xf46561,roughness:.4}),d=new THREE.MeshStandardMaterial({color:0x332646});let m=new THREE.Mesh(new THREE.SphereGeometry(.42,12,9),a);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=>{let w=new THREE.Mesh(new THREE.BoxGeometry(.65,.09,.24),d);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})}
</script></body></html>
-const player=makeRobot();player.position.set(0,.02,0);scene.add(player);
-const player=makeRobot();player.position.set(0,.02,0);scene.add(player);
-const platforms=[];function platform(x,y,w){const p=new THREE.Mesh(new THREE.BoxGeometry(w,.25,2.2),new THREE.MeshStandardMaterial({color:0x694da1,roughness:.6,emissive:0x24124d,emissiveIntensity:.5}));p.position.set(x,y,0);scene.add(p);platforms.push({x,y,w})}
-const platforms=[];function platform(x,y,w){const p=new THREE.Mesh(new THREE.BoxGeometry(w,.25,2.2),new THREE.MeshStandardMaterial({color:0x694da1,roughness:.6,emissive:0x24124d,emissiveIntensity:.5}));p.position.set(x,y,0);scene.add(p);platforms.push({x,y,w})}
-platform(10,1.5,3);platform(18,2.3,3.5);platform(28,1.6,4);platform(38,2.6,3.5);
-platform(10,1.5,3);platform(18,2.3,3.5);platform(28,1.6,4);platform(38,2.6,3.5);
-const enemies=[],projectiles=[];function drone(x,y){const g=new THREE.Group(),mat=new THREE.MeshStandardMaterial({color:0xf46561,roughness:.4,metalness:.22}),dark=new THREE.MeshStandardMaterial({color:0x332646,roughness:.5});const body=new THREE.Mesh(new THREE.SphereGeometry(.42,12,9),mat);body.scale.z=.65;g.add(body);const eye=new THREE.Mesh(new THREE.SphereGeometry(.13,8,6),new THREE.MeshBasicMaterial({color:0xffff89}));eye.position.z=-.28;g.add(eye);[-1,1].forEach(s=>{const wing=new THREE.Mesh(new THREE.BoxGeometry(.65,.09,.24),dark);wing.position.set(s*.43,0,.03);g.add(wing)});g.position.set(x,y,0);scene.add(g);enemies.push({g,hp:3,boss:false,nextShot:0})}
-const enemies=[],projectiles=[];function drone(x,y){const g=new THREE.Group(),mat=new THREE.MeshStandardMaterial({color:0xf46561,roughness:.4,metalness:.22}),dark=new THREE.MeshStandardMaterial({color:0x332646,roughness:.5});const body=new THREE.Mesh(new THREE.SphereGeometry(.42,12,9),mat);body.scale.z=.65;g.add(body);const eye=new THREE.Mesh(new THREE.SphereGeometry(.13,8,6),new THREE.MeshBasicMaterial({color:0xffff89}));eye.position.z=-.28;g.add(eye);[-1,1].forEach(s=>{const wing=new THREE.Mesh(new THREE.BoxGeometry(.65,.09,.24),dark);wing.position.set(s*.43,0,.03);g.add(wing)});g.position.set(x,y,0);scene.add(g);enemies.push({g,hp:3,boss:false,nextShot:0})}
-function colossus(){const g=new THREE.Group(),mat=new THREE.MeshStandardMaterial({color:0x92355b,roughness:.42,metalness:.23}),dark=new THREE.MeshStandardMaterial({color:0x33213e,roughness:.5});const body=new THREE.Mesh(new THREE.BoxGeometry(1.8,2.1,.7),mat);body.position.y=1.16;g.add(body);const head=new THREE.Mesh(new THREE.BoxGeometry(1.35,.7,.7),dark);head.position.y=2.52;g.add(head);[-1,1].forEach(s=>{const arm=new THREE.Mesh(new THREE.BoxGeometry(.52,1.35,.6),mat);arm.position.set(s*1.15,1.2,0);g.add(arm);const eye=new THREE.Mesh(new THREE.SphereGeometry(.15,8,6),new THREE.MeshBasicMaterial({color:0xffea65}));eye.position.set(s*.28,2.52,-.38);g.add(eye)});g.position.set(52,.02,0);scene.add(g);enemies.push({g,hp:35,maxHp:35,boss:true,nextShot:0});bossActive=true;bossHud.style.display="block";bossFill.style.width="100%"}
-function colossus(){const g=new THREE.Group(),mat=new THREE.MeshStandardMaterial({color:0x92355b,roughness:.42,metalness:.23}),dark=new THREE.MeshStandardMaterial({color:0x33213e,roughness:.5});const body=new THREE.Mesh(new THREE.BoxGeometry(1.8,2.1,.7),mat);body.position.y=1.16;g.add(body);const head=new THREE.Mesh(new THREE.BoxGeometry(1.35,.7,.7),dark);head.position.y=2.52;g.add(head);[-1,1].forEach(s=>{const arm=new THREE.Mesh(new THREE.BoxGeometry(.52,1.35,.6),mat);arm.position.set(s*1.15,1.2,0);g.add(arm);const eye=new THREE.Mesh(new THREE.SphereGeometry(.15,8,6),new THREE.MeshBasicMaterial({color:0xffea65}));eye.position.set(s*.28,2.52,-.38);g.add(eye)});g.position.set(52,.02,0);scene.add(g);enemies.push({g,hp:35,maxHp:35,boss:true,nextShot:0});bossActive=true;bossHud.style.display="block";bossFill.style.width="100%"}
-[6,13,21,32,41].forEach((x,i)=>drone(x,.5+(i%2)*.45));
-[6,13,21,32,41].forEach((x,i)=>drone(x,.5+(i%2)*.45));
-function bolt(playerShot){const m=new THREE.Mesh(new THREE.BoxGeometry(.5,.1,.1),new THREE.MeshBasicMaterial({color:playerShot?0xfff18a:0xff5a84}));m.position.copy(playerShot?player.position:enemyShotPos);m.position.y+=playerShot?1.25:.95;scene.add(m);projectiles.push({m,player:playerShot})}
-function bolt(playerShot){const m=new THREE.Mesh(new THREE.BoxGeometry(.5,.1,.1),new THREE.MeshBasicMaterial({color:playerShot?0xfff18a:0xff5a84}));m.position.copy(playerShot?player.position:enemyShotPos);m.position.y+=playerShot?1.25:.95;scene.add(m);projectiles.push({m,player:playerShot})}
-let enemyShotPos=new THREE.Vector3(),running=false,lives=3,move=0,vy=0,jumpQueued=false,firing=false,last=0,nextFire=0,bossActive=false;
-let enemyShotPos=new THREE.Vector3(),running=false,lives=3,move=0,vy=0,jumpQueued=false,firing=false,last=0,nextFire=0,bossActive=false;
-const livesEl=document.querySelector("#lives"),cover=document.querySelector("#cover"),copy=document.querySelector("#copy"),start=document.querySelector("#start"),bossHud=document.querySelector("#bossHud"),bossFill=document.querySelector("#bossFill");
-const livesEl=document.querySelector("#lives"),cover=document.querySelector("#cover"),copy=document.querySelector("#copy"),start=document.querySelector("#start"),bossHud=document.querySelector("#bossHud"),bossFill=document.querySelector("#bossFill");
-function updateLives(){livesEl.textContent=Array(lives).fill("●").join(" ")||"—"}function damage(){lives--;updateLives();player.rotation.z=-.45;if(lives<=0){running=false;copy.innerHTML="The skyworks pushed back.<br>Recharge and clear the sector!";start.textContent="REBOOT";cover.style.display="grid";bossHud.style.display="none"}}
-function updateLives(){livesEl.textContent=Array(lives).fill("●").join(" ")||"—"}function damage(){lives--;updateLives();player.rotation.z=-.45;if(lives<=0){running=false;copy.innerHTML="The skyworks pushed back.<br>Recharge and clear the sector!";start.textContent="REBOOT";cover.style.display="grid";bossHud.style.display="none"}}
-function destroyEnemy(i){const e=enemies[i];scene.remove(e.g);enemies.splice(i,1);if(e.boss){bossActive=false;bossHud.style.display="none";running=false;copy.innerHTML="<b>Sector cleared!</b><br>You defeated the Iron Colossus.";start.textContent="PLAY AGAIN";cover.style.display="grid"}}
-function destroyEnemy(i){const e=enemies[i];scene.remove(e.g);enemies.splice(i,1);if(e.boss){bossActive=false;bossHud.style.display="none";running=false;copy.innerHTML="<b>Sector cleared!</b><br>You defeated the Iron Colossus.";start.textContent="PLAY AGAIN";cover.style.display="grid"}}
-function fire(){if(!running)return;bolt(true)}function jump(){if(running&&Math.abs(vy)<.005&&player.position.y<.1)vy=.105}
-function fire(){if(!running)return;bolt(true)}function jump(){if(running&&Math.abs(vy)<.005&&player.position.y<.1)vy=.105}
-function hold(el,dir){el.addEventListener("pointerdown",e=>{e.preventDefault();move=dir});["pointerup","pointerleave","pointercancel"].forEach(t=>el.addEventListener(t,()=>move=0))}
-function hold(el,dir){el.addEventListener("pointerdown",e=>{e.preventDefault();move=dir});["pointerup","pointerleave","pointercancel"].forEach(t=>el.addEventListener(t,()=>move=0))}
-hold(document.querySelector("#left"),-1);hold(document.querySelector("#right"),1);document.querySelector("#jump").addEventListener("click",jump);
-hold(document.querySelector("#left"),-1);hold(document.querySelector("#right"),1);document.querySelector("#jump").addEventListener("click",jump);
-const blast=document.querySelector("#blast");blast.addEventListener("pointerdown",e=>{e.preventDefault();firing=true});["pointerup","pointerleave","pointercancel"].forEach(t=>blast.addEventListener(t,()=>firing=false));
-const blast=document.querySelector("#blast");blast.addEventListener("pointerdown",e=>{e.preventDefault();firing=true});["pointerup","pointerleave","pointercancel"].forEach(t=>blast.addEventListener(t,()=>firing=false));
-start.addEventListener("click",()=>{lives=3;updateLives();player.position.set(0,.02,0);vy=0;running=true;cover.style.display="none";last=0});
-start.addEventListener("click",()=>{lives=3;updateLives();player.position.set(0,.02,0);vy=0;running=true;cover.style.display="none";last=0});
-addEventListener("keydown",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")move=-1;if(k==="d"||k==="arrowright")move=1;if(k==="w"||k==="arrowup")jumpQueued=true;if(k===" ")firing=true;if(k==="enter"&&!running)start.click()});addEventListener("keyup",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft"||k==="d"||k==="arrowright")move=0;if(k===" ")firing=false});
-addEventListener("keydown",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")move=-1;if(k==="d"||k==="arrowright")move=1;if(k==="w"||k==="arrowup")jumpQueued=true;if(k===" ")firing=true;if(k==="enter"&&!running)start.click()});addEventListener("keyup",e=>{const k=e.key.toLowerCase();if(k==="a"||k==="arrowleft"||k==="d"||k==="arrowright")move=0;if(k===" ")firing=false});
-function animate(t){requestAnimationFrame(animate);const dt=Math.min(35,last?t-last:16);last=t;player.rotation.z+=(0-player.rotation.z)*.12;if(running){player.position.x=Math.max(-4,Math.min(53,player.position.x+move*dt*.005));if(jumpQueued){jump();jumpQueued=false}vy-=dt*.006;let oldY=player.position.y;player.position.y+=vy*dt*.06;let landed=false;if(player.position.y<=.02){player.position.y=.02;vy=0;landed=true}for(const p of platforms){const onX=Math.abs(player.position.x-p.x)<p.w/2-.1;if(vy<=0&&onX&&oldY>=p.y+.18&&player.position.y<=p.y+.18){player.position.y=p.y+.18;vy=0;landed=true}}if(!landed&&player.position.y<-.5){player.position.y=.02;vy=0;damage()}if(!bossActive&&player.position.x>45&&enemies.length===0)colossus();if(firing&&t>nextFire){fire();nextFire=t+230}
-function animate(t){requestAnimationFrame(animate);const dt=Math.min(35,last?t-last:16);last=t;player.rotation.z+=(0-player.rotation.z)*.12;if(running){player.position.x=Math.max(-4,Math.min(53,player.position.x+move*dt*.005));if(jumpQueued){jump();jumpQueued=false}vy-=dt*.006;let oldY=player.position.y;player.position.y+=vy*dt*.06;let landed=false;if(player.position.y<=.02){player.position.y=.02;vy=0;landed=true}for(const p of platforms){const onX=Math.abs(player.position.x-p.x)<p.w/2-.1;if(vy<=0&&onX&&oldY>=p.y+.18&&player.position.y<=p.y+.18){player.position.y=p.y+.18;vy=0;landed=true}}if(!landed&&player.position.y<-.5){player.position.y=.02;vy=0;damage()}if(!bossActive&&player.position.x>45&&enemies.length===0)colossus();if(firing&&t>nextFire){fire();nextFire=t+230}
-for(let i=enemies.length-1;i>=0;i--){const e=enemies[i];if(!e.boss)e.g.position.y=.65+Math.sin(t*.004+i)*.22;if(player.position.x>e.g.position.x-6&&t>e.nextShot){enemyShotPos.copy(e.g.position);bolt(false);e.nextShot=t+(e.boss?700:1500)}}
-for(let i=enemies.length-1;i>=0;i--){const e=enemies[i];if(!e.boss)e.g.position.y=.65+Math.sin(t*.004+i)*.22;if(player.position.x>e.g.position.x-6&&t>e.nextShot){enemyShotPos.copy(e.g.position);bolt(false);e.nextShot=t+(e.boss?700:1500)}}
-for(let i=projectiles.length-1;i>=0;i--){const b=projectiles[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);projectiles.splice(i,1);if(e.boss)bossFill.style.width=(e.hp/e.maxHp*100)+"%";if(e.hp<=0)destroyEnemy(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);projectiles.splice(i,1);damage();continue}if(b.m.position.x>62||b.m.position.x<-7){scene.remove(b.m);projectiles.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)}
-for(let i=projectiles.length-1;i>=0;i--){const b=projectiles[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);projectiles.splice(i,1);if(e.boss)bossFill.style.width=(e.hp/e.maxHp*100)+"%";if(e.hp<=0)destroyEnemy(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);projectiles.splice(i,1);damage();continue}if(b.m.position.x>62||b.m.position.x<-7){scene.remove(b.m);projectiles.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)});updateLives();animate(0);
-addEventListener("resize",()=>{camera.aspect=innerWidth/innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth,innerHeight)});updateLives();animate(0);
+function boss(){const g=new THREE.Group(),a=new THREE.MeshStandardMaterial({color:0x92355b,roughness:.42}),d=new THREE.MeshStandardMaterial({color:0x33213e});let m=new THREE.Mesh(new THREE.BoxGeometry(1.8,2.1,.7),a);m.position.y=1.16;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(1.35,.7,.7),d);m.position.y=2.52;g.add(m);[-1,1].forEach(s=>{let arm=new THREE.Mesh(new THREE.BoxGeometry(.52,1.35,.6),a);arm.position.set(s*1.15,1.2,0);g.add(arm)});g.position.set(52,.02,0);scene.add(g);enemies.push({g,hp:35,max:35,boss:true,next:0});bossActive=true;bossHud.style.display="block";fill.style.width="100%"}[6,13,21,32,41].forEach(enemy);
+function boss(){const g=new THREE.Group(),a=new THREE.MeshStandardMaterial({color:0x92355b,roughness:.42}),d=new THREE.MeshStandardMaterial({color:0x33213e});let m=new THREE.Mesh(new THREE.BoxGeometry(1.8,2.1,.7),a);m.position.y=1.16;g.add(m);m=new THREE.Mesh(new THREE.BoxGeometry(1.35,.7,.7),d);m.position.y=2.52;g.add(m);[-1,1].forEach(s=>{let arm=new THREE.Mesh(new THREE.BoxGeometry(.52,1.35,.6),a);arm.position.set(s*1.15,1.2,0);g.add(arm)});g.position.set(52,.02,0);scene.add(g);enemies.push({g,hp:35,max:35,boss:true,next:0});bossActive=true;bossHud.style.display="block";fill.style.width="100%"}[6,13,21,32,41].forEach(enemy);
+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})}
+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})}
+let running=false,lives=3,dir=0,vy=0,firing=false,nextShot=0,last=0,bossActive=false;const livesEl=document.querySelector("#lives"),cover=document.querySelector("#cover"),copy=document.querySelector("#copy"),start=document.querySelector("#start"),bossHud=document.querySelector("#boss"),fill=document.querySelector("#fill");
+let running=false,lives=3,dir=0,vy=0,firing=false,nextShot=0,last=0,bossActive=false;const livesEl=document.querySelector("#lives"),cover=document.querySelector("#cover"),copy=document.querySelector("#copy"),start=document.querySelector("#start"),bossHud=document.querySelector("#boss"),fill=document.querySelector("#fill");
+function life(){livesEl.textContent=Array(lives).fill("●").join(" ")||"—"}function damage(){lives--;life();if(lives<=0){running=false;copy.innerHTML="The skyworks pushed back.<br>Recharge and clear the sector!";start.textContent="REBOOT";cover.style.display="grid";bossHud.style.display="none"}}function jump(){if(running&&Math.abs(vy)<.002&&player.position.y<.04)vy=.011}
+function life(){livesEl.textContent=Array(lives).fill("●").join(" ")||"—"}function damage(){lives--;life();if(lives<=0){running=false;copy.innerHTML="The skyworks pushed back.<br>Recharge and clear the sector!";start.textContent="REBOOT";cover.style.display="grid";bossHud.style.display="none"}}function jump(){if(running&&Math.abs(vy)<.002&&player.position.y<.04)vy=.011}
+function endBoss(){running=false;copy.innerHTML="<b>Sector cleared!</b><br>You defeated the Iron Colossus.";start.textContent="PLAY AGAIN";cover.style.display="grid";bossHud.style.display="none"}
+function endBoss(){running=false;copy.innerHTML="<b>Sector cleared!</b><br>You defeated the Iron Colossus.";start.textContent="PLAY AGAIN";cover.style.display="grid";bossHud.style.display="none"}
+function removeEnemy(i){const e=enemies[i];scene.remove(e.g);enemies.splice(i,1);if(e.boss)endBoss()}
+function removeEnemy(i){const e=enemies[i];scene.remove(e.g);enemies.splice(i,1);if(e.boss)endBoss()}
+function hold(el,v){el.addEventListener("pointerdown",e=>{e.preventDefault();dir=v});["pointerup","pointerleave","pointercancel"].forEach(t=>el.addEventListener(t,()=>dir=0))}hold(left,-1);hold(right,1);jump.addEventListener("click",jump);blast.addEventListener("pointerdown",e=>{e.preventDefault();firing=true});["pointerup","pointerleave","pointercancel"].forEach(t=>blast.addEventListener(t,()=>firing=false));start.addEventListener("click",()=>{lives=3;life();running=true;cover.style.display="none";last=0});
+function hold(el,v){el.addEventListener("pointerdown",e=>{e.preventDefault();dir=v});["pointerup","pointerleave","pointercancel"].forEach(t=>el.addEventListener(t,()=>dir=0))}hold(left,-1);hold(right,1);jump.addEventListener("click",jump);blast.addEventListener("pointerdown",e=>{e.preventDefault();firing=true});["pointerup","pointerleave","pointercancel"].forEach(t=>blast.addEventListener(t,()=>firing=false));start.addEventListener("click",()=>{lives=3;life();running=true;cover.style.display="none";last=0});
+addEventListener("keydown",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")dir=-1;if(k==="d"||k==="arrowright")dir=1;if(k==="w"||k==="arrowup")jump();if(k===" ")firing=true;if(k==="enter"&&!running)start.click()});addEventListener("keyup",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft"||k==="d"||k==="arrowright")dir=0;if(k===" ")firing=false});
+addEventListener("keydown",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft")dir=-1;if(k==="d"||k==="arrowright")dir=1;if(k==="w"||k==="arrowup")jump();if(k===" ")firing=true;if(k==="enter"&&!running)start.click()});addEventListener("keyup",e=>{let k=e.key.toLowerCase();if(k==="a"||k==="arrowleft"||k==="d"||k==="arrowright")dir=0;if(k===" ")firing=false});
+function loop(t){requestAnimationFrame(loop);let 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));let old=player.position.y;vy-=dt*.000035;player.position.y+=vy*dt;if(player.position.y<=.02){player.position.y=.02;vy=0}for(const p of platforms){if(vy<=0&&Math.abs(player.position.x-p.x)<p.w/2-.12&&old>=p.y+.17&&player.position.y<=p.y+.17){player.position.y=p.y+.17;vy=0}}if(!bossActive&&player.position.x>45&&enemies.length===0)boss();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--){let 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)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)});life();loop(0);
+function loop(t){requestAnimationFrame(loop);let 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));let old=player.position.y;vy-=dt*.000035;player.position.y+=vy*dt;if(player.position.y<=.02){player.position.y=.02;vy=0}for(const p of platforms){if(vy<=0&&Math.abs(player.position.x-p.x)<p.w/2-.12&&old>=p.y+.17&&player.position.y<=p.y+.17){player.position.y=p.y+.17;vy=0}}if(!bossActive&&player.position.x>45&&enemies.length===0)boss();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--){let 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)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)});life();loop(0);
← Histórico de versões