Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>3D War Advanced</title> <style> body { margin:0; overflow:hidden; background:black; touch-action:none; } canvas { display:block; } #attackBtn, #axeBtn{ position:absolute; width:75px; height:75px; border-radius:50%; text-align:center; line-height:75px; font-size:22px; color:white; opacity:0.9; } #attackBtn{ right:30px; bottom:60px; background:#8b0000; } #axeBtn{ right:120px; bottom:130px; background:#555; } #joystickBase{ position:absolute; left:40px; bottom:80px; width:130px; height:130px; border-radius:50%; background:rgba(255,255,255,0.08); } #joystickStick{ position:absolute; width:60px; height:60px; border-radius:50%; background:rgba(255,255,255,0.35); left:75px; bottom:115px; } </style> </head> <body> <div id="attackBtn">⚔</div> <div id="axeBtn">🪓</div> <div id="joystickBase"></div> <div id="joystickStick"></div> <script src="https://cdn.jsdelivr.net/npm/three@0.152.2/build/three.min.js"></script> <script> const scene = new THREE.Scene(); scene.background = new THREE.Color(0x0d0d12); scene.fog = new THREE.Fog(0x000000, 20, 80); const camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({antialias:true}); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; document.body.appendChild(renderer.domElement); // Luces scene.add(new THREE.HemisphereLight(0xffffff,0x222233,0.6)); const dirLight = new THREE.DirectionalLight(0xffffff,1); dirLight.position.set(10,15,10); dirLight.castShadow = true; scene.add(dirLight); // Suelo const floor = new THREE.Mesh( new THREE.PlaneGeometry(300,300), new THREE.MeshStandardMaterial({color:0x1a1a1f, roughness:0.9}) ); floor.rotation.x = -Math.PI/2; floor.receiveShadow = true; scene.add(floor); // ===== PERSONAJE ===== function createCharacter(color){ const g = new THREE.Group(); const mat = new THREE.MeshStandardMaterial({color, roughness:0.7}); const skin = new THREE.MeshStandardMaterial({color:0xffd2a6}); const torso = new THREE.Mesh(new THREE.CylinderGeometry(0.7,0.9,2.2,32), mat); torso.position.y = 2; g.add(torso); const head = new THREE.Mesh(new THREE.SphereGeometry(0.6,32,32), skin); head.position.y = 3.6; g.add(head); const limbGeo = new THREE.CylinderGeometry(0.3,0.3,2,16); const armL = new THREE.Mesh(limbGeo, mat); armL.position.set(-1.1,2.2,0); armL.rotation.z = Math.PI/8; g.add(armL); const armR = armL.clone(); armR.position.x = 1.1; armR.rotation.z = -Math.PI/8; g.add(armR); const legL = new THREE.Mesh(limbGeo, mat); legL.scale.y = 1.1; legL.position.set(-0.4,0.9,0); g.add(legL); const legR = legL.clone(); legR.position.x = 0.4; g.add(legR); return g; } const player = createCharacter(0xaa0000); scene.add(player); // ===== HACHA ===== const axe = new THREE.Group(); const handle = new THREE.Mesh( new THREE.CylinderGeometry(0.1,0.1,2,16), new THREE.MeshStandardMaterial({color:0x8b4513}) ); handle.rotation.z = Math.PI/2; axe.add(handle); const blade = new THREE.Mesh( new THREE.BoxGeometry(0.2,1.2,1), new THREE.MeshStandardMaterial({color:0xcccccc, metalness:0.8}) ); blade.position.x = 1; axe.add(blade); axe.visible=false; scene.add(axe); let axeState="idle"; let axeVelocity=new THREE.Vector3(); // ===== ENEMIGOS ===== let enemies=[]; function spawnEnemy(){ const e = createCharacter(0x006600); e.position.set((Math.random()-0.5)*40,0,(Math.random()-0.5)*40); scene.add(e); enemies.push(e); } setInterval(spawnEnemy,5000); // ===== JOYSTICK ===== const base=document.getElementById("joystickBase"); const stick=document.getElementById("joystickStick"); let joystick={active:false,dx:0,dy:0,touchId:null}; renderer.domElement.addEventListener("touchstart", e=>{ for(let t of e.changedTouches){ if(t.clientX<window.innerWidth/2 && !joystick.active){ joystick.active=true; joystick.touchId=t.identifier; moveStick(t.clientX,t.clientY); } } }); renderer.domElement.addEventListener("touchmove", e=>{ for(let t of e.changedTouches){ if(t.identifier===joystick.touchId){ moveStick(t.clientX,t.clientY); } } // Cámara (lado derecho) const t=e.touches[0]; if(t.clientX>window.innerWidth/2){ camAngle += e.movementX*0.002; } }); renderer.domElement.addEventListener("touchend", e=>{ joystick.dx=0; joystick.dy=0; joystick.active=false; stick.style.left="75px"; stick.style.bottom="115px"; }); function moveStick(x,y){ const r=base.getBoundingClientRect(); const cx=r.left+r.width/2; const cy=r.top+r.height/2; let dx=x-cx; let dy=y-cy; const max=45; const dist=Math.sqrt(dx*dx+dy*dy); if(dist>max){ dx=dx/dist*max; dy=dy/dist*max; } joystick.dx=dx/max; joystick.dy=dy/max; stick.style.left=(cx-30+dx)+"px"; stick.style.top=(cy-30+dy)+"px"; } // ===== CONTROLES ===== document.getElementById("axeBtn").addEventListener("touchstart", ()=>{ if(axeState==="idle"){ axe.visible=true; axe.position.copy(player.position); const dir=new THREE.Vector3(0,0,-1).applyQuaternion(player.quaternion); axeVelocity.copy(dir).multiplyScalar(0.8); axeState="forward"; } }); // ===== CÁMARA LIBRE ===== let camAngle=0; const camDistance=15; const camHeight=8; // ===== LOOP ===== function animate(){ requestAnimationFrame(animate); // Movimiento jugador relativo a cámara const forward=new THREE.Vector3(Math.sin(camAngle),0,Math.cos(camAngle)); const right=new THREE.Vector3(forward.z,0,-forward.x); player.position.add(forward.clone().multiplyScalar(-joystick.dy*0.4)); player.position.add(right.clone().multiplyScalar(joystick.dx*0.4)); if(joystick.dx||joystick.dy){ player.rotation.y=Math.atan2(-joystick.dx,-joystick.dy)+camAngle; } // Enemigos siguen enemies.forEach(e=>{ e.position.lerp(player.position,0.002); e.lookAt(player.position); }); // Hacha if(axeState==="forward"){ axe.position.add(axeVelocity); if(axe.position.distanceTo(player.position)>15){ axeState="return"; } } else if(axeState==="return"){ const dir=new THREE.Vector3().subVectors(player.position,axe.position).normalize(); axe.position.add(dir.multiplyScalar(1)); if(axe.position.distanceTo(player.position)<1){ axe.visible=false; axeState="idle"; } } enemies.forEach((e,i)=>{ if(axe.visible && axe.position.distanceTo(e.position)<2){ scene.remove(e); enemies.splice(i,1); } }); // Cámara orbitable camera.position.x = player.position.x + Math.sin(camAngle)*camDistance; camera.position.z = player.position.z + Math.cos(camAngle)*camDistance; camera.position.y = camHeight; camera.lookAt(player.position); renderer.render(scene,camera); } animate(); </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

2

Requests

2

Domains

162KB

Transfer Size

626KB

Content Size

2,612.0ms

Dom Content Loaded

136.0ms

First Paint

2,612.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...