LoginSignup
10
3

More than 5 years have passed since last update.

3DCG素人がthree.jsを使ってFPSゲームを作ってみた Part1

Last updated at Posted at 2018-12-06

three.jsってなんだよ?

HTML5のcanvasを使って、3Dコンテンツを描写するJavaScriptのライブラリ。
JavaScriptが使えれば、素人でも作れるということなので、簡単なFPSゲームを作ってみようと思う。
three.js公式
Three.js入門サイト

とりあえず下準備

必要なライブラリの読み込み、3D空間の設定、カメラ設定、光源設定を行う。

three.jsライブラリ読み込み

CDNを利用
https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js

各種設定

// 3D空間の設定
const scene = new THREE.Scene();
// 背景色設定
scene.background = new THREE.Color( 0x000000 );
// 光源設定
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0.5, 1, 0.75)
scene.add(light);
// 座標軸を表示
const axes = new THREE.AxisHelper(400);
scene.add(axes)
// カメラ設定
const camera = new THREE.PerspectiveCamera(60, width / height);
camera.position.set(300, 200, 400);
camera.lookAt(new THREE.Vector3(0, 0, 0))

まだこの段階では何も描写されていない。
01.png

フィールド・オブジェクトの配置

土台となるフィールド、平面では寂しいので簡単なオブジェクトを配置する。

オブジェクト配置

// フィールド作成
const geometry = new THREE.BoxGeometry(512, 8, 512, 10, 10, 1);
const material = new THREE.MeshPhongMaterial({color: 0xe29676});
const field = new THREE.Mesh(geometry, material);
field.position.y = -5;
scene.add(field);
// オブジェクト作成
scene.add(createBox(16, 16, 16, {x: -128, z: -128, y: 8}, 0x6c9bd2));
scene.add(createBox(16, 16, 16, {x: 128, z: -128, y: 8}, 0x9cbb1c));
scene.add(createBox(16, 16, 16, {x: -128, z: 128, y: 8}, 0x9cbb1c));
scene.add(createBox(16, 16, 16, {x: 128, z: 128, y: 8}, 0x6c9bd2));

// ボックスオブジェクトの生成関数
function createBox(x, y, z, position, color) {
  const geometry = new THREE.BoxGeometry(x, y, z);
  const material = new THREE.MeshPhongMaterial({color: color});
  const box = new THREE.Mesh(geometry, material);
  box.position.x = position.x;
  box.position.z = position.z;
  box.position.y = position.y;
  return box;
}

おぉ~感無量
02.png

この上を歩きたい!

移動を実現するには、キーボード・マウスの入力を受け取り、いろいろな計算を行ってカメラを移動させる。
一から実装するのは無理なので、PointerLockControlライブラリを使う。

PointerLockControlライブラリ読み込み

CDNを利用
https://threejs.org/examples/js/controls/PointerLockControls.js

設定

/**
キーボード入力イベントの設定
移動距離算出
カメラの設定
毎フレーム毎に移動距離からカメラを移動させる処理を追加
*/

// 移動距離算出 即時関数
let move = (function() {

  const SPEED = 60.0;

  let moveForward  = false;
  let moveBackward = false;
  let moveLeft     = false;
  let moveRight    = false;
  let prevTime     = performance.now();

  // キーダウンイベント設定
  document.addEventListener( 'keydown', function(e) {
    switch ( e.keyCode ) {
      case 87: // w
        moveForward = true;
        break;
      case 65: // a
        moveLeft = true;
        break;
      case 83: // s
        moveBackward = true;
        break;
      case 68: // d
        moveRight = true;
        break;
    }
  }, false );

  // キーアップイベント設定
  document.addEventListener( 'keyup', function(e) {
    switch ( e.keyCode ) {
      case 87: // w
        moveForward = false;
        break;
      case 65: // a
        moveLeft = false;
        break;
      case 83: // s
        moveBackward = false;
        break;
      case 68: // d
        moveRight = false;
        break;
    }
  }, false );

  return {
    getVelocity() {
      let time = performance.now();
      let delta = ( time - prevTime ) / 1000;
      let directionX = Number( moveLeft ) - Number( moveRight );
      let directionZ = Number( moveForward ) - Number( moveBackward );
      let velocity = new THREE.Vector3();
      velocity.x -= directionX * SPEED * delta;
      velocity.z -= directionZ * SPEED * delta;
      prevTime = time;
      return velocity;
    }
  }

})();

// カメラ設定
const camera = new THREE.PerspectiveCamera(60, width / height);
const controls = new THREE.PointerLockControls(camera);
controls.getObject().position.y = 10
// canvasクリックでポインタロック
scene.add(controls.getObject());
document.getElementById('myCanvas').addEventListener('click', function() {
  controls.lock(); 
});

// 毎フレーム時に実行されるループイベントです
function tick() {
  let v = move.getVelocity();
  controls.getObject().translateX(v.x)
  controls.getObject().translateZ(v.z)
  renderer.render(scene, camera); // レンダリング

  requestAnimationFrame(tick);
}

動かしてみる

キーバインド
前方移動: w
後方移動: s
左移動: a
右移動: d
視野方向の変更: マウスでcanvas内をクリックすると、ポインタがロックされ、マウス移動に応じて視野方向が変更
※ESCキーで元に戻ります。

See the Pen three.js by Gen Abe (@gen6414) on CodePen.


次回予告

とりあえず移動ができるようになったので、オブジェクトへの当たり判定をつけたいな

おわり

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3