Traverse from one cube room to another cube room with the help of keys

I am trying to make series of 3D rooms with cubes. We can move from one room to another room. Please find the room designs spanshot.


User should be able to move from one cube room to another cube room with the help of keys as done in Games. I am new to three.js, but after looking into the documentations I was able to place the cubes in the same formats.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Three JS Crash Course</title>

  <style>
    body{
      margin: 0;
    }
    canvas{
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
  <script src="./js/three.min.js"></script>
  <script src="./js/OrbitControls.js"></script>

  <script>
    const scene = new THREE.Scene()

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

    const renderer = new THREE.WebGLRenderer({ antialias: true })
    renderer.setSize( window.innerWidth, window.innerHeight )

    document.body.appendChild( renderer.domElement )

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

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

    conrtrols = new THREE.OrbitControls( camera, renderer.domElement )

    var group=new THREE.Object3D();

    // create the shape
    const geometry = new THREE.BoxGeometry( 1, 1, 1 )

    const cubeMaterial = [
      new THREE.MeshLambertMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
      new THREE.MeshPhongMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
      new THREE.MeshLambertMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
      new THREE.MeshPhongMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
      new THREE.MeshLambertMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
      new THREE.MeshPhongMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide })
    ]
    const material = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe: false } )
    const material1 = new THREE.MeshFaceMaterial(cubeMaterial)
    // const material2 = new THREE.MeshFaceMaterial(cubeMaterial)
    // const material3 = new THREE.MeshFaceMaterial(cubeMaterial)
  
    material.side = THREE.BackSide; 
    const cube = new THREE.Mesh( geometry, material )
    const cube1 = new THREE.Mesh( geometry, material1 )
    const cube2 = new THREE.Mesh( geometry, material )
    const cube3 = new THREE.Mesh( geometry, material )
    const cube4 = new THREE.Mesh( geometry, material1 )
    const cube5 = new THREE.Mesh( geometry, material )
    const cube6 = new THREE.Mesh( geometry, material )
    const cube7 = new THREE.Mesh( geometry, material1 )
    const cube8 = new THREE.Mesh( geometry, material )
    const cube9 = new THREE.Mesh( geometry, material )

    cube.position.x = 0
    cube1.position.x = 1
    cube2.position.set(1, -1)
    cube3.position.set(2, -1)
    cube4.position.set(1, 1)
    cube5.position.set(1, 2)
    cube6.position.set(1, 3)
    cube7.position.set(1, 4)
    cube8.position.set(2, 4)
    cube9.position.set(3, 4)

    group.add(cube)
    group.add(cube1)
    group.add(cube2)
    group.add(cube3)
    group.add(cube4)
    group.add(cube5)
    group.add(cube6)
    group.add(cube7)
    group.add(cube8)
    group.add(cube9)

    scene.add(group)

    camera.position.z = 5

    const ambientLight = new THREE.AmbientLight( 0xFFFFFF, 1.0 )
    scene.add( ambientLight )

    function update () {
      // cube.rotation.x += 0.01
      // cube.rotation.y += 0.005;
    }

    function render () {
      renderer.render( scene, camera )
    }

    function gameLoop () {
      requestAnimationFrame( gameLoop )
      update()
      render()
    }

    gameLoop()
  </script>

</body>
</html>

Any help is appreciated.

Using
document.addEventListener('keydown', function( e ) { ... } you can relize movements.

An example from the collection:

MultiFormGeometry


document.addEventListener('keydown', function( e ) {
    
    if ( e.keyCode === 37 ) staticMesh.position.x -= 0.1; // arrow keys
    if ( e.keyCode === 38 ) staticMesh.position.y += 0.1;
    if ( e.keyCode === 39 ) staticMesh.position.x += 0.1;
    if ( e.keyCode === 40 ) staticMesh.position.y -= 0.1;
    
    if ( e.keyCode === 76 ) { // l left 
        
        rot +=0.03;
        staticMesh.rotation.z = rot;
        
    }
    
    if ( e.keyCode === 82 ) { // r right
        
        rot -=0.03;
        staticMesh.rotation.z = rot;
        
    }
    
} );
1 Like

I have no idea how to implement this. Could you change the code so that camera goes from room 1 to room 2 and so forth. Here is my code till now:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Whitehat Engineering | Test</title>

  <style>
    body {
      margin: 0;
    }

    canvas {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

  <script type="importmap">
    {
      "imports": {
        "three": "https://unpkg.com/three/build/three.module.js"
      }
    }
  </script>
  <script type="module">
    import * as THREE from 'three';
    import * as CameraUtils from 'https://unpkg.com/three/examples/jsm/utils/CameraUtils.js';
    import { OrbitControls } from 'https://unpkg.com/three/examples/jsm/controls/OrbitControls.js';

    const scene = new THREE.Scene()

    const renderer = new THREE.WebGLRenderer({ antialias: true })
    renderer.setSize(window.innerWidth, window.innerHeight)

    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
    camera.position.set(-2, 2, 2);

    const controls = new OrbitControls(camera, renderer.domElement)

    document.body.appendChild(renderer.domElement)

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

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

    var group = new THREE.Object3D();

    // create the shape
    const geometry = new THREE.BoxGeometry(1, 1, 1)

    // const material = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe: false } )
    // const cubeMaterial = [
    //   new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
    //   new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
    //   new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
    //   new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
    //   new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide }),
    //   new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load('img/1.jpeg'), side: THREE.DoubleSide })
    // ]
    // const cube = new THREE.Mesh( geometry, cubeMaterial )
    // const cube1 = new THREE.Mesh( geometry, cubeMaterial )
    // const cube2 = new THREE.Mesh( geometry, cubeMaterial )
    // const cube3 = new THREE.Mesh( geometry, cubeMaterial )
    // const cube4 = new THREE.Mesh( geometry, cubeMaterial )
    // const cube5 = new THREE.Mesh( geometry, cubeMaterial )
    // const cube6 = new THREE.Mesh( geometry, cubeMaterial )

    const cubes = [
      {
        position: [0, 0, 0]
      },
      {
        position: [1, 0, 0]
      },
      {
        position: [1, 0, 1]
      },
      {
        position: [2, 0, 1]
      },
      {
        position: [1, 0, -1]
      },
      {
        position: [1, 0, -2]
      },
      {
        position: [1, 0, -3]
      }
    ]

    for (let i = 0; i < cubes.length; i++) {
      let right = THREE.DoubleSide
      let left = THREE.DoubleSide
      let top = THREE.DoubleSide
      let bottom = THREE.DoubleSide
      let front = THREE.DoubleSide
      let back = THREE.DoubleSide

      const [x, y, z] = cubes[i].position
      // const prevCube = i > 0 && cubes[i - 1]
      // let xNext, yNext, zNext
      // if (prevCube && prevCube.position.length > 0) {
      //   console.log('inside')
      //   xNext = prevCube.position[0]
      //   yNext = prevCube.position[1]
      //   zNext = prevCube.position[2]
      // }

      // if (i === 0) {
      //   left = THREE.BackSide
      //   right = THREE.FrontSide
      // } else if (xNext - x === 1) {
      //   console.log('inside')
      //   left = THREE.FrontSide
      // }
      const cubeMaterial = [
        new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('img/1.jpeg'), side: right }),
        new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('img/1.jpeg'), side: left }),
        new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('img/1.jpeg'), side: top }),
        new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('img/1.jpeg'), side: bottom }),
        new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('img/1.jpeg'), side: front }),
        new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('img/1.jpeg'), side: back })
      ]
      const cube = new THREE.Mesh(geometry, cubeMaterial)
      cube.position.set(x, y, z)

      if (i === 0) {
        var cubeAxis = new THREE.AxesHelper(20);
        cube.add(cubeAxis);
      }

      group.add(cube)
    }
    // console.log(group, 'group')
    // var cubeAxis = new THREE.AxesHelper(20);
    // cube.add(cubeAxis);

    const ambientLight = new THREE.AmbientLight(0xFFFFFF, 1.0)
    scene.add(ambientLight)

    // cube.position.set(0, 0, 0)
    // cube1.position.set(1, 0, 0)
    // cube2.position.set(1, 0, 1)
    // cube3.position.set(2, 0, 1)
    // cube4.position.set(1, 0, -1)
    // cube5.position.set(1, 0, -2)
    // cube6.position.set(1, 0, -3)

    // group.add(cube)
    // group.add(cube1)
    // group.add(cube2)
    // group.add(cube3)
    // group.add(cube4)
    // group.add(cube5)
    // group.add(cube6)

    scene.add(group)

    function update() {
      // cube.rotation.x += 0.01
      // cube.rotation.y += 0.005;
    }

    function render() {
      renderer.render(scene, camera)
    }

    function gameLoop() {
      requestAnimationFrame(gameLoop)
      update()
      render()
    }

    gameLoop()

    document.addEventListener('keydown', function (e) {

    // left
    if (e.keyCode === 37) {
      console.log(37)
    }
    // top
    if (e.keyCode === 38) {
      console.log(38)
    }
    // right
    if (e.keyCode === 39) {
      console.log(39)
    }
    // bottom
    if (e.keyCode === 40) {
      console.log(40)
    }
    });

  </script>
</body>

</html>

If you want to place the camera individually in the rooms, you must set the position of the camera.

I tried this once in the Multi Form example (see above) as I am working on the code.
Since there is an object in the origin, I am inside this object after pressing c.

     if ( e.keyCode === 67 ) { // c camera set  
        
        camera.position.set( 0.1, 0.2, 0.3);
        
    }

-Annotation-
It is better to provide a live example (jsfiddle or codepen) instead of the listing. Then one can work immediately in your code. Otherwise, the effort is greater and there is not always time to deal with it in more detail.

@hofk : I think placing camera inside the cube is not a good idea.
Actually, I have few conditions:

  • Wall of a room must be opaque if there is no next room to traverse.
  • Move from one room to another. You are only allowed to move from one space to another space. Ex: From room 1 you have only option to move to room 2 and from room 2 only option to move either room 5 or room 3.
  • Able to navigate 360 inside a room.
  • Use the concept of 3D transformations

Since, I am new to Threejs. I am running out of ideas to complete this task. Since, you have a depth idea about Threejs, could you help me complete this task.
Code: Edit fiddle - JSFiddle - Code Playground

I don’t quite understand your goal. If something moves in the boxes, it must also be visible. So with partially opaque walls, the camera must be in the box or a neighboring box with an open wall.

Maybe this discussion will help you.

How to remove interior faces while keeping exterior faces untouched? - #19 by hofk

see also

BoxLabyrinthCreation3D

BufferLabyrinthCreation3D

DungeonCreation2D

Can we connect in social media platform. I need this task done by tomorrow. My whatsapp number is +9779860556972