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>
facundo96542Legendary facundo96542
Sign in to react
Uploaded Oct 5, 2026

v

Published feedback

Robby
InimitableRobby
Updated Oct 5, 2026

Tu 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!