Three.js: Así se hace el Juego del Calamar con Javascript portada

Three.js: Así se hace el Juego del Calamar con Javascript

Compártelo

Acabo de encontrarme una versión muy sencilla del juego Red Light Green Light de Squid Game con JavaScript y Three.js.

Puedes jugarlo aquí.

Si quieres un tutorial paso a paso de cómo crear este juego te dejaré, al final de este, el vídeo de donde saqué el código y el mismo código original.

Ahora, vayamos paso a paso en este tutorial ya que será muy interesante explicar cómo funciona la biblioteca Tree.JS con el que trabajaremos con los modelos 3D.

¿Comenzamos?

Configuración del proyecto básico con Three.js

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

renderer.setClearColor( 0xb7c3f3, 1 );

const light = new THREE.AmbientLight( 0xffffff );
scene.add( light )

camera.position.z = 5;

function animate() {
    if(gameStat == "over") return
    renderer.render( scene, camera );
    requestAnimationFrame( animate );
    player.update()
}
animate();

window.addEventListener( 'resize', onWindowResize, false );

function onWindowResize(){
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );

}

Utiliza el modelo 3d de la muñeca del juego del calamar

Three.js: Así se hace el Juego del Calamar con Javascript

En este enlace podrás descargar el modelo 3d de la muñeca de famosa prueba Red Light Green Light del Juego del Calamar.

    const loader = new THREE.GLTFLoader()
    loader.load("../models/scene.gltf", (gltf) => {
            scene.add( gltf.scene );
            gltf.scene.scale.set(.4, .4, .4);
            gltf.scene.position.set(0, -1, 0);
            this.doll = gltf.scene;
        })

Así se crea También la clase de la Muñeca

function delay(ms){
    return new Promise(resolve => setTimeout(resolve, ms));
}

class Doll{
    constructor(){
        loader.load("../models/scene.gltf", (gltf) => {
            scene.add( gltf.scene );
            gltf.scene.scale.set(.4, .4, .4);
            gltf.scene.position.set(0, -1, 0);
            this.doll = gltf.scene;
        })
    }

    lookBackward(){
        gsap.to(this.doll.rotation, {y: -3.15, duration: .45})
        setTimeout(() => isLookingBackward = true, 150)
    }

    lookForward(){
        gsap.to(this.doll.rotation, {y: 0, duration: .45})
        setTimeout(() => isLookingBackward = false, 450)
    }

    //Makes the doll look back for 1.5 - 3 seconds then look forward for .75 - 1.5 seconds and keep repeating these.
    async start(){
        this.lookBackward()
        await delay((Math.random() * 1000) + 1000)
        this.lookForward()
        await delay((Math.random() * 750) + 750)
        this.start()
    }
}

Creación del campo de juego para cruzar con los cubos

function createCube(size, positionX, rotY = 0, color = 0xfbc851){
    const geometry = new THREE.BoxGeometry(size.w, size.h, size.d);
    const material = new THREE.MeshBasicMaterial( { color: color } );
    const cube = new THREE.Mesh( geometry, material );
    cube.position.x = positionX;
    cube.rotation.y = rotY;
    scene.add( cube );
    return cube
}

function createTrack(){
    createCube({w: start_position * 2 + .2, h: 1.5, d: 1}, 0, 0, 0xe5a716).position.z = -1;
    createCube({w: .2, h: 1.5, d: 1}, start_position, -.35);
    createCube({w: .2, h: 1.5, d: 1}, end_position, .35);
}
createTrack()

Creación de clase Jugador

class Player{
    constructor(){
        const geometry = new THREE.SphereGeometry( .3, 32, 16 );
        const material = new THREE.MeshBasicMaterial( { color: 0xffffff } );
        const sphere = new THREE.Mesh( geometry, material );
        sphere.position.z = 1
        sphere.position.x = start_position
        scene.add( sphere )
        this.player = sphere
        this.playerInfo = {
            positionX: start_position,
            velocity: 0
        }
    }

    run(){
        this.playerInfo.velocity = .03
    }

    stop(){
        gsap.to(this.playerInfo, {velocity: 0, duration: .1})
    }

    update(){ //Update function is called in animation loop
        this.check()
        this.playerInfo.positionX -= this.playerInfo.velocity
        this.player.position.x = this.playerInfo.positionX
    }
}

Creación de eventos de pulsación de teclas para mover a los jugadores

window.addEventListener('keydown', (e) => {
    if(e.key == "ArrowUp"){
        player.run()
    }
})
window.addEventListener('keyup', (e) => {
    if(e.key == "ArrowUp"){
        player.stop()
    }
})

Por último, habría que distribuir estas funciones dentro de clases como prefieras e implementar la lógica del juego para que sea funcional.

Si tienes práctica con Javascript esto no presentará ningún problema, en el caso de que seas novato o tengas un nivel medio tirando a bajo, aquí tienes el vídeo original de este proyecto, donde te explicará paso a paso cómo crear el juego (en inglés, eso sí) y si no puedes esperar para ver cómo queda, este es el enlace al código del programa.

Espero que te haya resultado de ayuda y una interesante oportunidad para comenzar a usar esta buenísima biblioteca de Javascript como es Three.js con la que podrás manejar gráficos de mil maneras diferentes. Una vez tengas experiencia con ella, no habrá nada que se te resista en cuanto a diseños increíbles se refiere.

Ya sabes, si te quedan dudas o quieres preguntarnos algo, no lo dudes, estamos aquí para ayudarte a ser mejor programador.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *