@joaobarrosfranca · 8/12/2026, 3:41:08 PM
Versão inicial — todas as linhas são novas.
+<!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>+<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 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})}+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})}+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));+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;+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 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 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);+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});+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}+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)}+addEventListener("resize",()=>{camera.aspect=innerWidth/innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth,innerHeight)});updateLives();animate(0);+</script></body></html>