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))
フィールド・オブジェクトの配置
土台となるフィールド、平面では寂しいので簡単なオブジェクトを配置する。
オブジェクト配置
// フィールド作成
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;
}
おぉ~感無量
#この上を歩きたい!
移動を実現するには、キーボード・マウスの入力を受け取り、いろいろな計算を行ってカメラを移動させる。
一から実装するのは無理なので、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.
# 次回予告 とりあえず移動ができるようになったので、オブジェクトへの当たり判定をつけたいなおわり