block by harrystevens 462c6277ba7fae4912a440656c493604

Ball Control

Full Screen

Use the arrow keys to move the ball.

index.html

<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      margin: 0;
      overflow: none;
    }
  </style>
</head>
<body>
  <div id="scene"></div>
  <div id="stats"></div>
  <script src="https://unpkg.com/three@0.105.2/build/three.js"></script>
  <script src="https://unpkg.com/three@0.104.0/examples/js/libs/stats.min.js"></script>
  <script src="https://unpkg.com/three@0.104.0/examples/js/utils/SceneUtils.js"></script>
  <script>
    let right = 0,
        left = 0,
        up = 0,
        down = 0;

    const stats = (_ => {
      const stats = new Stats();
      stats.domElement.style.position = "absolute";
      stats.domElement.style.left = "0px";
      stats.domElement.style.top = "0px";
      document.getElementById("stats").appendChild(stats.domElement);
      return stats;
    })();

    const scene = new THREE.Scene();

    const camera = (_ => {
      const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 1000);
      camera.position.set(40, 40, 40);
      camera.lookAt(scene.position);
      return camera;
    })();

    const renderer = (_ => {
      const renderer = new THREE.WebGLRenderer();
      renderer.setClearColor("#fff");
      renderer.setPixelRatio(devicePixelRatio);
      renderer.shadowMap.enabled = true;
      renderer.shadowMap.type = THREE.PCFSoftShadowMap;
      renderer.gammaOutput = true;
      renderer.gammaFactor = 2.2;
      document.getElementById("scene").appendChild(renderer.domElement);
      return renderer;
    })();

    const floor = (_ => {
      const geo = new THREE.PlaneBufferGeometry(20, 20);
      const mat = new THREE.MeshLambertMaterial({ color: "green" });
      const mesh = new THREE.Mesh(geo, mat);
      mesh.rotation.x = Math.PI * -0.5;
      mesh.receiveShadow = true;
      scene.add(mesh);
      return mesh;
    })();

    const floorTwo = (_ => {
      const geo = new THREE.PlaneBufferGeometry(10, 40);
      const mat = new THREE.MeshLambertMaterial({ color: "green" });
      const mesh = new THREE.Mesh(geo, mat);
      mesh.rotation.x = Math.PI * -0.5;
      mesh.position.set(15, 0, -10);
      mesh.receiveShadow = true;
      scene.add(mesh);
      return mesh;      
    })();

    const rightWall = (_ => {
      const geo = new THREE.PlaneBufferGeometry(20, 4);
      const mat = new THREE.MeshLambertMaterial({ color: "orange" });
      const mesh = new THREE.Mesh(geo, mat);
      mesh.position.set(0, 2, -10)
      mesh.receiveShadow = true;
      mesh.castShadow = true;
      scene.add(mesh);
      return mesh;
    })();

    const leftWall = (_ => {
      const geo = new THREE.PlaneBufferGeometry(20, 4);
      const mat = new THREE.MeshLambertMaterial({ color: "purple" });
      const mesh = new THREE.Mesh(geo, mat);
      mesh.rotation.y = Math.PI * 0.5
      mesh.position.set(-10, 2, 0)
      mesh.receiveShadow = true;
      mesh.castShadow = true;
      scene.add(mesh);
      return mesh;
    })();

    const leftWall2 = (_ => {
      const geo = new THREE.PlaneBufferGeometry(20, 4);
      const mat = new THREE.MeshLambertMaterial({ color: "purple" });
      const mesh = new THREE.Mesh(geo, mat);
      mesh.rotation.y = Math.PI * 0.5
      mesh.position.set(10, 2, -20)
      mesh.receiveShadow = true;
      mesh.castShadow = true;
      scene.add(mesh);
      return mesh;
    })();

    const sphere = (_ => {
      const geo = new THREE.SphereBufferGeometry(4, 32, 32);
      const mats = [
        new THREE.MeshLambertMaterial({ color: "#fff", wireframe: true }),
        new THREE.MeshPhongMaterial({ shininess: 100, color: "blue" })
      ]
      const mesh = new THREE.SceneUtils.createMultiMaterialObject(geo, mats)
      mesh.children.forEach(e => {
        e.castShadow = true;
      });      
      mesh.position.y = 4;
      scene.add(mesh);
      return mesh;
    })();

    const ambient = (_ => {
      const light = new THREE.AmbientLight("#ccc", 0.8);
      scene.add(light);
      return light;  
    })();

    const spot = (_ => {
      const light = new THREE.SpotLight("#fff", 0.8);
      light.position.set(-20, 20, 20);
      light.castShadow = true;
      light.shadow.mapSize.width = 1024;
      light.shadow.mapSize.height = 1024;
      light.angle = Math.PI / 5;
      scene.add(light);
      return light;
    })();

    document.addEventListener("keydown", e => {
      if (e.key === "ArrowRight"){
        right = 1;
        e.preventDefault()
      }
      if (e.key === "ArrowLeft"){
        left = 1;
        e.preventDefault()
      }
      if (e.key === "ArrowUp"){
        up = 1;
        e.preventDefault()
      }
      if (e.key === "ArrowDown"){
        down = 1;
        e.preventDefault()
      }
    });
    document.addEventListener("keyup", e => {
      if (e.key === "ArrowRight"){
        right = 0;
        e.preventDefault()
      }
      if (e.key === "ArrowLeft"){
        left = 0;
        e.preventDefault()
      }
      if (e.key === "ArrowUp"){
        up = 0;
        e.preventDefault()
      }
      if (e.key === "ArrowDown"){
        down = 0;
        e.preventDefault()
      }
    });

    function animate(){
      requestAnimationFrame(animate);

      if (right){
        if (sphere.position.x < 19.5) sphere.position.x += 0.2;
        sphere.rotateOnWorldAxis(new THREE.Vector3(0, 0, 1), -0.05);
      }
      if (left){
        if (sphere.position.z < -8){
          if (sphere.position.x > 13.5) sphere.position.x -= 0.2  
        }
        else {
          if (sphere.position.x > -8) sphere.position.x -= 0.2  
        }
        sphere.rotateOnWorldAxis(new THREE.Vector3(0, 0, 1), 0.05);
      }
      if (up){
        if (sphere.position.x < 12.5){
          if (sphere.position.z > -7.5) sphere.position.z -= 0.2;  
        }
        else {
          if (sphere.position.z > -28) sphere.position.z -= 0.2;
        }
        sphere.rotateOnWorldAxis(new THREE.Vector3(1, 0, 0), -0.05);
      }
      if (down){
        if (sphere.position.z < 9) sphere.position.z += 0.2;
        sphere.rotateOnWorldAxis(new THREE.Vector3(1, 0, 0), 0.05);
      }

      stats.update();
      renderer.render(scene, camera);
    }
    animate();

    function size(){
      camera.aspect = innerWidth / innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(innerWidth, innerHeight);      
    }
    size();
    onresize = size;
  </script>
</body>
</html>