404

Rounded box, tweening

by Paul West

HTML

<script src="https://unpkg.com/three@0.88.0/build/three.min.js"></script>
<script src="https://unpkg.com/three@0.88.0/examples/js/libs/tween.min.js"></script>
<script src="https://unpkg.com/three@0.88.0/examples/js/controls/OrbitControls.js"></script>
<script>
  // round-edged box
  function createBoxWithRoundedEdges(width, height, depth, radius0, smoothness) {
    let shape = new THREE.Shape();
    let eps = 0.00001;
    let radius = radius0 - eps;
    shape.absarc(eps, eps, eps, -Math.PI / 2, -Math.PI, true);
    shape.absarc(eps, height - radius * 2, eps, Math.PI, Math.PI / 2, true);
    shape.absarc(width - radius * 2, height - radius * 2, eps, Math.PI / 2, 0, true);
    shape.absarc(width - radius * 2, eps, eps, 0, -Math.PI / 2, true);
    let geometry = new THREE.ExtrudeBufferGeometry(shape, {
      amount: depth - radius0 * 2,
      bevelEnabled: true,
      bevelSegments: smoothness * 2,
      steps: 1,
      bevelSize: radius,
      bevelThickness: radius0,
      curveSegments: smoothness
    });

    geometry.center();

    return geometry;
  }

</script>

CSS

body {
  overflow: hidden;
  margin: 0;
}

JavaScript

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(2, 10, 7).setLength(17);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setClearColor(0xffffff);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

addEventListener("resize", () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
})

var controls = new THREE.OrbitControls(camera, renderer.domElement);

scene.add(new THREE.AmbientLight(0xffffff, .5));
var light = new THREE.DirectionalLight(0xffffff, .5);
light.position.setScalar(10);
scene.add(light);

var map404 = [
  [0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0],
  [0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0],
  [0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0],
  [1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1],
  [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0],
  [0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0]
];

var roundedBoxGeometry = createBoxWithRoundedEdges(1, 1, 1, .25, 3);
roundedBoxGeometry.computeVertexNormals();
roundedBoxGeometry.translate(0, .5, 0);
var colorNormal = new THREE.Color("rgb(128,255,128)");
var colorBad = new THREE.Color("red");
var colorGood = new THREE.Color("blue");
var roundedBoxMaterial = new THREE.MeshLambertMaterial({
  color: colorNormal.clone()
});

var boxes = [];
for (let y = 0; y < map404.length; y++) {
  for (let x = 0; x < map404[0].length; x++) {
    if (map404[y][x] === 0) continue;
    let roundedBox = new THREE.Mesh(roundedBoxGeometry, roundedBoxMaterial.clone());
    roundedBox.position.set(x - 8, 0, y - 2);
    scene.add(roundedBox);
    boxes.push(roundedBox);
  }
}

var startPosition = new THREE.Vector3();
var guardStartPosition = new THREE.Vector3();
var badBox,...