c
Python
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Superhéroe 3D</title>
<style>
body {
margin: 0;
overflow: hidden;
background: black;
}
#info {
position: absolute;
top: 20px;
left: 20px;
color: white;
font-family: Arial;
background: rgba(0,0,0,0.6);
padding: 15px;
border-radius: 10px;
z-index: 10;
}
</style>
</head>
<body>
<div id="info">
🦸 SUPERHÉROE 3D<br>
Flechas / WASD = Mover<br>
ESPACIO = Golpear 💥
</div>
<script type="module">
import * as THREE from
"https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js";
// ESCENA
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87ceeb);
// CÁMARA
const camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 5, 12);
// RENDER
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(
window.innerWidth,
window.innerHeight
);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// LUCES
const luz = new THREE.DirectionalLight(
0xffffff,
3
);
luz.position.set(5,10,5);
scene.add(luz);
scene.add(
new THREE.AmbientLight(0xffffff,1)
);
// SUELO
const suelo = new THREE.Mesh(
new THREE.PlaneGeometry(100,100),
new THREE.MeshStandardMaterial({
color:0x444444
})
);
suelo.rotation.x = -Math.PI/2;
scene.add(suelo);
// =========================
// SUPERHÉROE
// =========================
const heroe = new THREE.Group();
scene.add(heroe);
heroe.position.y = 1;
// MATERIAL
const negro = new THREE.MeshStandardMaterial({
color:0x111111
});
// CABEZA
const cabeza = new THREE.Mesh(
new THREE.SphereGeometry(0.45,32,32),
negro
);
cabeza.position.y = 3.5;
heroe.add(cabeza);
// FUNCIÓN PARA HACER PALITOS
function palo(largo){
return new THREE.Mesh(
new THREE.CylinderGeometry(
0.12,
0.12,
largo,
16
),
negro
);
}
// CUERPO
const cuerpo = palo(2);
cuerpo.position.y = 2.1;
heroe.add(cuerpo);
// BRAZO IZQUIERDO
const brazoIzq = palo(1.6);
brazoIzq.position.set(
-0.6,
2.5,
0
);
brazoIzq.rotation.z =
Math.PI/4;
heroe.add(brazoIzq);
// BRAZO DERECHO
const brazoDer = palo(1.6);
brazoDer.position.set(
0.6,
2.5,
0
);
brazoDer.rotation.z =
-Math.PI/4;
heroe.add(brazoDer);
// PIERNAS
const piernaIzq = palo(1.8);
piernaIzq.position.set(
-0.5,
0.7,
0
);
piernaIzq.rotation.z =
-Math.PI/7;
heroe.add(piernaIzq);
const piernaDer = palo(1.8);
piernaDer.position.set(
0.5,
0.7,
0
);
piernaDer.rotation.z =
Math.PI/7;
heroe.add(piernaDer);
// =========================
// CAPA ROJA
// =========================
const capaMaterial =
new THREE.MeshStandardMaterial({
color:0xff0000,
side:THREE.DoubleSide
});
const capa = new THREE.Mesh(
new THREE.PlaneGeometry(
2,
3
),
capaMaterial
);
capa.position.set(
0,
2,
-0.35
);
capa.rotation.x =
0.15;
heroe.add(capa);
// =========================
// ENEMIGO
// =========================
const enemigo =
new THREE.Group();
scene.add(enemigo);
enemigo.position.set(
5,
1,
0
);
const rojo =
new THREE.MeshStandardMaterial({
color:0x880000
});
const cabezaEnemigo =
new THREE.Mesh(
new THREE.SphereGeometry(
0.5,
32,
32
),
rojo
);
cabezaEnemigo.position.y =
3.3;
enemigo.add(
cabezaEnemigo
);
const cuerpoEnemigo =
new THREE.Mesh(
new THREE.BoxGeometry(
1.2,
2,
0.8
),
rojo
);
cuerpoEnemigo.position.y =
2;
enemigo.add(
cuerpoEnemigo
);
// =========================
// CONTROLES
// =========================
const teclas = {};
document.addEventListener(
"keydown",
e => {
teclas[e.key.toLowerCase()] = true;
// ATAQUE
if(e.code === "Space"){
atacar();
}
});
document.addEventListener(
"keyup",
e => {
teclas[e.key.toLowerCase()] = false;
});
// =========================
// ATAQUE
// =========================
let atacando = false;
function atacar(){
if(atacando) return;
atacando = true;
brazoDer.rotation.x =
-Math.PI/2;
setTimeout(()=>{
brazoDer.rotation.x = 0;
atacando = false;
},200);
}
// =========================
// ANIMACIÓN
// =========================
function animate(){
requestAnimationFrame(
animate
);
// MOVIMIENTO
if(
teclas["arrowleft"] ||
teclas["a"]
){
heroe.position.x -= 0.08;
}
if(
teclas["arrowright"] ||
teclas["d"]
){
heroe.position.x += 0.08;
}
if(
teclas["arrowup"] ||
teclas["w"]
){
heroe.position.z -= 0.08;
}
if(
teclas["arrowdown"] ||
teclas["s"]
){
heroe.position.z += 0.08;
}
// CAPA MOVIÉNDOSE
capa.rotation.x =
0.15 +
Math.sin(Date.now()*0.006)
* 0.08;
// CÁMARA SIGUE AL HÉROE
camera.position.x =
heroe.position.x;
camera.position.z =
heroe.position.z + 12;
camera.lookAt(
heroe.position.x,
2,
heroe.position.z
);
renderer.render(
scene,
camera
);
}
animate();
// AJUSTAR PANTALLA
window.addEventListener(
"resize",
()=>{
camera.aspect =
window.innerWidth /
window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(
window.innerWidth,
window.innerHeight
);
});
</script>
</body>
</html>Sign in to react
v
Published feedback
InimitableRobby
Updated Oct 5, 2026Tu juego 'Superhéroe 3D' destaca por el uso creativo de figuras básicas para construir personajes y por permitir mover al héroe en un entorno 3D, mostrando una comprensión clara de cómo animar y responder a las teclas.
Facundo, me parece genial cómo lograste que el héroe responda directamente cuando lo mueves y ataca al presionar espacio, justo como en los juegos de acción: ¡así la experiencia se siente interactiva y divertida!