目次

WebGLとは

WebGL(ウェブジーエル)は、ウェブブラウザ3次元コンピュータグラフィックスを表示させるための標準仕様。OpenGL 2.0もしくはOpenGL ES 2.0をサポートするプラットフォーム上で、特別なブラウザのプラグインなしで、ハードウェアでアクセラレートされた三次元グラフィックスを表示可能にする。技術的には、JavaScriptとネイティブのOpenGL ES 2.0のバインディングである。WebGLは非営利団体のKhronos Groupで管理されている。

WebGLはHTMLcanvas要素を使う。

Wikipediaより

参考サイト

3Dモデリングソフトで作成したファイルを表示させるなら↓

Blender サンプル

Three.jsのダウンロード

mrdoob/three.js · GitHubにアクセスし、上部にある「ZIP」をクリックしてダウンロード

Three.js を使用する際には「build」フォルダの中にあります

サンプルもあるから参考になるかも?

使い方

ココでは特に説明しません

初心者は初めにHTML5による物理シミュレーション環境の構築 ~WebGLライブラリThree.js 入門(1/3)~で勉強して

次に【1】Cubeで遊ぼう! 迷路生成編 - はじめてのthree.js | Xlune::Blogで勉強すればいいかも

【注意点】

色んなサイトを参考するにあたっての注意点

以下の理由によりコピペだけじゃ正常に動作しないことがあります

  • Three.jsだけだと「addObject()」は使えません
var scene = new THREE.Scene();
[誤] scene.addObject( obj ); => エラー吐く
[正] scene.add( obj );       => add( obj )と書き直せばおk
  • Three.jsだけだと省略形を利用できない
   var cube = new THREE.Mesh(
        [誤] new THREE.Cube(50,50,50),         => エラー吐く
        [正] new THREE.CubeGeometry(50,50,50), => 省略せずに書く!
        new THREE.MeshLambertMaterial({color: 0xff0000}) //材質の設定
   );
   scene.add(cube);
   cube.position.set(0,0,0);

立方体以外も同様に省略しない

  • テクスチャを貼付ける際はサーバーにアップロードした方がいいかも

ローカルで画像を貼付けようとすると以下のようにエラーを吐く(Google Chrome の JavaScript コンソールより)

Cross-origin image load denied by Cross-Origin Resource Sharing policy.

違うドメインの画像を読み込ませれないなら分かるがローカルファイルを読み込ませれないのは意味がわかんねorz

Mac なら 「Web 共有」をオンにすればおk

Windows なら サーバにアップロードするか 「XAMPP」をインストールするってのもありかも

Blender

Blender は3DCGアニメーションを作成するための統合環境アプリケーションです

Blender Exporterと組み合わせれば楽にWebGL開発できるかもね

サンプル

Blender Exportter

Three用にjsファイルを出力するアドオン

ファイルのコピー

three.jsフォルダーの以下の場所にアドオンがある

mrdoob-three.js/utils/exporters/blender/バージョン/scripts/addons

「io_mesh_threejs」フォルダーをBlenderがインストールされている以下のフォルダーにコピーすればおk

Windows

C:/UsersvUSERNAME/AppData/Roaming/Blender Foundation/Blender/バージョン/scripts/addons

OSX

blender.appを「control」を押しながら「クリック」して「パッケージの内容を表示」を選択して以下のフォルダーにコピー

/Applications/Blender/blender.app/Contents/MacOS/バージョン/scripts/addons

Linux

/home/USERNAME/.blender/バージョン/scripts/addons

有効化

メニューから User Preferences を開いて Addons タブを開く

Import-Export カテゴリを選択して Import-Export: three.js format をチェックすればおk

おそらく一番下にあるはず

日本語化

#youtube(E7yS4Bzzbmw)

サンプル

匠で遊ぼう!

creeper.jpg

コチラから遊べます↓

http://batako.net/sample/webgl/

更新情報

  • [2012/06/26] 口から地球吐き出し攻撃機能を追加(もはや匠ではないw)
  • [2012/06/25] ダッシュとジャンプ機能を追加

どういうの?

匠を操作して緑地化を目指すw そんな感じのサンプル

いつも家をリフォームさせてくれる匠

でも

今回は移動先を緑地化してくれる

爆発音がするけど爆発しない自然にやさしい

こんな匠を愛でて楽しましょう!

元ネタはMinecraftというゲームです

#youtube(MmB9b5njVbA)

操作方法

W :前進

D :右移動

S :後退

A :左移動

J :左回転

L :右回転

SHIFT : ダッシュ

SPACE : ジャンプ

ENTER / 左クリック : 攻撃

↑ / I:視点を上に移動

→ :匠を軸に右回転

↓ / K:視点を下に移動

← :匠を軸に左回転

T :一人称/三人称 切り替え

G :爆発(音だけw)

右クリックドラッグ : 視点移動

マウス操作はいまいち正常に動かない

ダウンロード

もしかしたら後で削除するかも

ダウンロード開始

【注意】

ローカルで動作させると以下のようにエラーが発生しテクスチャが正常に表示されません

Cross-origin image load denied by Cross-Origin Resource Sharing policy.

サーバー上で動作させる必要があるみたいなので

Mac なら 「Web 共有」をオンにして開発すればおk

Windows なら サーバにアップロードするか 「XAMPP」をインストールするってのもありかも

ソース

無駄にjQueryを使用してるからダウンロードの必要あり

画像と音楽ファイルを読み込んでるからコピペでは正常に動作しないので注意!

<!DOCTYPE html>
<html>
	<head>
		<meta charset="Shift-JIS">
		<title>WebGL</title>
		<script src="js/Three.js"></script>
		<script src="js/jquery-1.7.2.min.js"></script>
		<!-- キャンバスの設定 -->
		<style type="text/css">
			body{
				margin:0;
				padding:0;
			}
			div#canvas-frame{
				border: none;               /* 枠線を消す */
				cursor: pointer;            /* マウスカーソルを「ポインター」に設定(CSS3) */
				width: 500px;               /* 確保する領域の横幅の設定 */
				height: 500px;              /* 保する領域の縦幅の設定 */
				background-color: #EEEEEE;  /* 背景色の設定 */
			}
		</style>
		<script>
			/**************************************************
			 * グローバル変数(オブジェクト)の宣言
			 **************************************************/
			 
			var width, height;
			var renderer;
			
			//オブジェクトの位置
			monster_height = 200;
			var monster = new THREE.Vector3;
			monster.x = 0;
			monster.y = monster_height;
			monster.z = 0;
			// モンスターの方向
			var monster_angle = 0;
			// モンスターの向き変換量
			var monster_angle_range = 3;
			// モンスターの移動距離
			var move_range = 15;
			
			// 地面生成済座標の格納配列
			var land = [];
			land.push('0,0');
			
			// 効果音
			var audio = new Audio('sound/creeper.m4a');
			
			/**************************************************
			 * レンダラーの設定
			 **************************************************/
			 
			function initThree() {
				// 額縁を担う「canvas-frame」で指定したの要素の横幅と縦幅の取得
				//width = document.getElementById('canvas-frame').clientWidth;
				//height = document.getElementById('canvas-frame').clientHeight;
				//width = $('#canvas-frame').width();
				//height = $('#canvas-frame').height();
				width = $('html').prop('clientWidth');
				height = $('html').prop('clientHeight');
				
				// レンダラーオブジェクトの生成(プロパティ:アンチエイリアスを有効)
				// アンチエイリアスとは、物体の輪郭を描画するときに輪郭と背景の色との混ぜ合わせることでエッジをなめらかにすることです。
				// アンチエイリアスを有効にすることで、物体の輪郭がギザギザになることを抑えます。 
				// Three.js はデフォルトでは無効になっているので、利用したければ明示的に有効にする必要があります。
				renderer = new THREE.WebGLRenderer({antialias: true});
				
				// レンダラーの横幅と縦幅を設定(額縁と同じサイズに設定)
				renderer.setSize(width, height);
				
				// 「canvas-frame」で指定した要素の中に「canvas」要素を追加する
				//document.getElementById('canvas-frame').appendChild(renderer.domElement);
				$('#canvas-frame').append(renderer.domElement);
				
				// レンダラーのクリアカラー(背景色とアルファ値)を設定
				renderer.setClearColorHex(0xFFFFFF, 1.0);
				
				// キーイベント設定
				$(document).bind('keydown', keyDownHandler);
				$(document).bind('keyup', keyUpHandler);
				
				// マウスイベント設定
				$(document).bind('mousemove', mouseMoveHandler);
			}
			
			/**************************************************
			* キーイベント設定
			**************************************************/
			
			// マウスの座標
			var mouse_X = 0;
			var mouse_Y = 0;
			
			// マウス感度
			var mickey = 5;
			
			function mouseMoveHandler(e){
				var x = e.clientX - mouse_X;
				var y = e.clientY - mouse_Y;
				
				if(x > mickey){
					roll_right();
					mouse_X = e.clientX
					mouse_Y = e.clientY
				}else if(x < -mickey){
					roll_left();
					mouse_X = e.clientX
					mouse_Y = e.clientY
				}
				if(y > mickey){
					forward();
					mouse_X = e.clientX
					mouse_Y = e.clientY
				}else if(y < -mickey){
					back();
					mouse_X = e.clientX
					mouse_Y = e.clientY
				}
				
				$('#canvas-frame .clientX').html(mouse_X);
				$('#canvas-frame .clientY').html(mouse_Y);
			}
			
			/**************************************************
			* キーイベント設定
			**************************************************/
			
			// キーフラグ配列
			var keyState = [];
			
			// キーを離した時
			function keyUpHandler(e){
				keyState[e.keyCode] = false;
				$("#canvas-frame .e_keyCode").html('keyUp : '+e.keyCode);
				return false;
			}
			
			// キーを押した時
			function keyDownHandler(e){
				keyState[e.keyCode] = true;
				$("#canvas-frame .e_keyCode").html('keyDown : '+e.keyCode);
				switch(e.keyCode){
					// 視点切り替え : T
					case 84:
						viewpoint();
						break;
					default:
						break;
				}
				return false;
			}
			
			/**************************************************
			* 移動処理
			**************************************************/
			// 前進
			function forward(){
				// 移動距離からオブジェクトの移動距離を求める
				var deg = monster_angle + 90;
				var x = move_range * Math.sin( deg * Math.PI / 180 );
				var z = move_range * Math.cos( deg * Math.PI / 180 );
				
				// オブジェクトの表示位置変更
				//alert('deg : '+deg+'\nx: '+x+'\nz : '+z);
				for(var i in cube){
					cube[i].position.x += x;
					cube[i].position.z += z;
				}
				
				// モンスターの位置変更
				monster.x += x;
				monster.z += z;
			}
			
			// 後退
			function back(){
				// 移動距離からオブジェクトの移動距離を求める
				var deg = monster_angle + 90;
				var x = move_range * Math.sin( deg * Math.PI / 180 );
				var z = move_range * Math.cos( deg * Math.PI / 180 );
				
				// オブジェクトの表示位置変更
				//alert('deg : '+deg+'\nx: '+x+'\nz : '+z);
				for(var i in cube){
					cube[i].position.x -= x;
					cube[i].position.z -= z;
				}
				
				// モンスターの位置変更
				monster.x -= x;
				monster.z -= z;
			}
			
			// 左移動
			function left(){
				// 移動距離からオブジェクトの移動距離を求める
				var deg = monster_angle + 90;
				var x = move_range * Math.sin( (deg + 90) * Math.PI / 180 );
				var z = move_range * Math.cos( (deg + 90) * Math.PI / 180 );
				
				// オブジェクトの表示位置変更
				//alert('deg : '+deg+'\nx: '+x+'\nz : '+z);
				for(var i in cube){
					cube[i].position.x += x;
					cube[i].position.z += z;
				}
				
				// モンスターの位置変更
				monster.x += x;
				monster.z += z;
			}
			
			// 右移動
			function right(){
				// 移動距離からオブジェクトの移動距離を求める
				var deg = monster_angle + 90;
				var x = move_range * Math.sin( (deg - 90) * Math.PI / 180 );
				var z = move_range * Math.cos( (deg - 90) * Math.PI / 180 );
				
				// オブジェクトの表示位置変更
				//alert('deg : '+deg+'\nx: '+x+'\nz : '+z);
				for(var i in cube){
					cube[i].position.x += x;
					cube[i].position.z += z;
				}
				
				// モンスターの位置変更
				monster.x += x;
				monster.z += z;
			}
			/**************************************************
			* 方向処理
			**************************************************/
			
			// 左回転
			function roll_left(){
				monster_angle = (monster_angle + monster_angle_range) % 360;
				$('#canvas-frame .monster_angle').html(monster_angle);
				// カメラの向き変換
				cameraTarget3.x += angleCycle;
				cameraTarget3.z += angleCycle;
				// モンスターオブジェクトの位置変換
				for(var i in cube){
					// モンスターの中心からオブジェクトの距離を測定
					var x = cube[i].position.x - monster.x;
					var z = cube[i].position.z - monster.z;
					if(x == 0 && z == 0){
						var rad2 = monster_angle * Math.PI / 180;
					}
					else{
						var r = Math.sqrt(z*z+x*x);
						// モンスターの中心からのオブジェクトの角度を測定
						var rad = Math.atan2(x, z); // Math.atan2(縦軸, 横軸)
						var deg = rad/Math.PI*180;
						// 位置変換
						var rad2 = (deg + monster_angle_range) * Math.PI / 180;
						cube[i].position.x = monster.x + r * Math.sin( rad2 );
						cube[i].position.z = monster.z + r * Math.cos( rad2 );
					}
					// 向き変換(Y軸方向に回転)
					cube[i].rotation.set( 0, rad2, 0 );
					//alert('i : '+i+'\nx:'+x+'\nz:'+z+'\nr:'+r+'\nrad:'+rad+'\ndeg:'+deg+'\nrad2 : '+rad2);
				}
			}
			// 右回転
			function roll_right(){
				monster_angle = (monster_angle - monster_angle_range) % 360;
				$('#canvas-frame .monster_angle').html(monster_angle);
				// カメラの向き変換
				cameraTarget3.x -= angleCycle;
				cameraTarget3.z -= angleCycle;
				// モンスターオブジェクトの位置変換
				for(var i in cube){
					// モンスターの中心からオブジェクトの距離を測定
					var x = cube[i].position.x - monster.x;
					var z = cube[i].position.z - monster.z;
					if(x == 0 && z == 0){
						var rad2 = monster_angle * Math.PI / 180;
					}
					else{
						var r = Math.sqrt(z*z+x*x);
						// モンスターの中心からのオブジェクトの角度を測定
						var rad = Math.atan2(x, z); // Math.atan2(縦軸, 横軸)
						var deg = rad/Math.PI*180;
						// 位置変換
						var rad2 = (deg - monster_angle_range) * Math.PI / 180;
						cube[i].position.x = monster.x + r * Math.sin( rad2 );
						cube[i].position.z = monster.z + r * Math.cos( rad2 );
					}
					// 向き変換(Y軸方向に回転)
					cube[i].rotation.set( 0, rad2, 0 );
					//alert('i : '+i+'\nx:'+x+'\nz:'+z+'\nr:'+r+'\nrad:'+rad+'\ndeg:'+deg+'\nrad2 : '+rad2);
				}
			}
			// 左矢印 : 37
			function hidari(){
				// 三人称の時のみ有効
				if(viewpoint_flag < 0){
					cameraTarget3.x += angleCycle;
					cameraTarget3.z += angleCycle;
				}
			}
			// 上矢印 : 38
			function ue(){
				// 三人称の時のみ有効
				if(viewpoint_flag < 0){
					cameraTarget3.y += angleYCycle;
					// 範囲修正
					cameraTarget3.y = Math.max(Math.min(cameraTarget3.y, angleYMax), angleYMin);
				}
			}
			 // 右矢印 : 39
			function migi(){
				// 三人称の時のみ有効
				if(viewpoint_flag < 0){
					cameraTarget3.x -= angleCycle;
					cameraTarget3.z -= angleCycle;
				}
			}
			// 下矢印 : 40
			function shita(){
				// 三人称の時のみ有効
				if(viewpoint_flag < 0){
					cameraTarget3.y -= angleYCycle;
					// 範囲修正
					cameraTarget3.y = Math.max(Math.min(cameraTarget3.y, angleYMax), angleYMin);
				}
			}
			// ズームイン : 219
			function zoomIn(){
				// 三人称の時のみ有効
				if(viewpoint_flag < 0){
					distanceTarget += zoomCycle;
					// 範囲修正
					distanceTarget = Math.max(Math.min(distanceTarget, zoomMax), zoomMin);
				}
			}
			// ズームアウト : 221
			function zoomOut(){
				// 三人称の時のみ有効
				if(viewpoint_flag < 0){
					distanceTarget -= zoomCycle;
					// 範囲修正
					distanceTarget = Math.max(Math.min(distanceTarget, zoomMax), zoomMin);
				}
			}
			// 視点切り替え : 84
			function viewpoint(){
				viewpoint_flag *= (-1);
				if(viewpoint_flag > 0){
					$('#canvas-frame .viewpoint').html('一人称');
					// カメラ距離初期値
					distance = 1;
					// カメラ距離
					distanceTarget = 1;
					// カメラ初期位置
					cameraTarget3.x = 270 + monster_angle;
					cameraTarget3.y = 0.01;
					cameraTarget3.z = 270 + monster_angle;
				}
				else{
					$('#canvas-frame .viewpoint').html('三人称');
					// カメラ距離初期値
					distance = 750;
					// カメラ距離
					distanceTarget = 500;
					// 視点の方向初期化
					lookAt_x = 0;
					lookAt_y = 0;
					lookAt_z = 0;
					// カメラの位置初期化
					cameraTarget3.x = 270 + monster_angle;
					cameraTarget3.y = 45;
					cameraTarget3.z = 270 + monster_angle;
				}
			}
			
			/**************************************************
			 * カメラの設定
			 **************************************************/
			 
			// グローバル変数(オブジェクト)の宣言
			var camera;
			//カメラ位置角度
			var cameraPos3 = new THREE.Vector3;
			//カメラ移動先の位置角度
			var cameraTarget3 = new THREE.Vector3;
			//カメラ距離初期値
			var distance = 750;
			//カメラ距離
			var distanceTarget = 500;
			var zoomCycle = 10;
			var zoomMin = 1;//300
			var zoomMax = 1500;
			//カメラ移動角度
			var angleCycle = monster_angle_range;	// 横方向
			var angleYCycle = 1; 			// 縦方向
			var angleYMin = 0.001;
			var angleYMax = 70;
			//カメラ初期位置
			cameraPos3.x = cameraTarget3.x = 270;
			cameraPos3.y = cameraTarget3.y =  45;
			cameraPos3.z = cameraTarget3.z = 270;
			// カメラの視点
			var lookAt_x = 0;
			var lookAt_y = 0;
			var lookAt_z = 0;
			// 視点切り替えフラグ
			// 一人称 : 1
			// 三人称 : -1
			var viewpoint_flag = -1;
			
			function initCamera() {
				
				// 透視投影によるカメラの設定
				// THREE.PerspectiveCamera( fov , aspect , near , far )
				camera = new THREE.PerspectiveCamera( 75 , width / height , 1 , 10000 );
				
				// カメラの位置座標の設定
				camera.position.z = distance;
				
				/*
				// カメラの位置座標の設定
				camera.position.set(0, 0, 1000);
				
				// カメラの上を「y」軸方向に設定
				camera.up.x = 0;
				camera.up.y = 1;
				camera.up.z = 0;
				
				// 視野の中心座標の設定
				camera.lookAt( {x:0, y:0, z:0 } );
				*/
			}
			
			/**************************************************
			 * シーンの宣言
			 **************************************************/
			 
			var scene;
			function initScene() {    
				scene = new THREE.Scene();
			}
			
			/**************************************************
			 * 光源の設定とシーンへの追加
			 **************************************************/
			 
			// グローバル変数(オブジェクト)の宣言
			var light;
			function initLight() {
				
				// 平行光源の設定
				// THREE.DirectionalLight( 色, 光の強さ)
				light = new THREE.DirectionalLight(0xFFFFFF, 1.0, 0);
				
				// 光源ベクトルの設定
				light.position.set( 0, 100, 0 );
				
				// シーンに光源を追加
				scene.add(light);
			}
			
			/**************************************************
			 * オブジェクト宣言とシーンへの追加
			 **************************************************/
			
			var cube = Array();
			function initObject(){
				var creeper_face = [
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_front.png')}), // front
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_back.png')}),  // back
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),   // top
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),   // bottom
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_right.png')}), // right
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_left.png')})   // left
				];
				var creeper_body = [
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // front
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // back
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // top
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // bottom
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // right
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')})   // back
				];
				var creeper_foot = [
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // front
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // back
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // top
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // bottom
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')}),  // right
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/creeper/face_top.png')})   // back
				];
				var foot_height = 70;
				var foot_oku = 60;
				var foot_yoko = 50;
				var geometry = new THREE.CubeGeometry( foot_oku, foot_height, foot_yoko, 5, 5, 5, creeper_foot);
				var material = new THREE.MeshFaceMaterial();
				var body_height = 130;
				cube = [
							new THREE.Mesh(geometry, material),
							new THREE.Mesh(geometry, material),
							new THREE.Mesh(geometry, material),
							new THREE.Mesh(geometry, material),
							new THREE.Mesh(new THREE.CubeGeometry( 70, body_height, 100, 5, 5, 5, creeper_body), material),
							new THREE.Mesh(new THREE.CubeGeometry( 100, 100, 100, 5, 5, 5, creeper_face), material)
				];
				// 右前足
				cube[0].position.z = foot_yoko/2;
				cube[0].position.x = 50;
				cube[0].position.y = foot_height/2;
				// 左前足
				cube[1].position.z = -foot_yoko/2;
				cube[1].position.x =  50;
				cube[1].position.y = foot_height/2;
				// 右後足
				cube[2].position.z =  foot_yoko/2;
				cube[2].position.x =  -50;
				cube[2].position.y = foot_height/2;
				// 左後足
				cube[3].position.z = -foot_yoko/2;
				cube[3].position.x =  -50;
				cube[3].position.y = foot_height/2;
				// 中段
				cube[4].position.y =  foot_height + foot_height/2 + 30;
				// 上段頭
				cube[5].position.y =  foot_height + body_height + 50;
				for(var i in cube){
					scene.add( cube[i] );
				}
				
				// 地面
				plane = new THREE.Mesh(
					new THREE.PlaneGeometry(1000, 1000, 5, 5),
					new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/turf.png')})
				);
				scene.add(plane);
				plane.position.set(0, 0,0);
			}
			
			/**************************************************
			 * レンダリングの実行
			 **************************************************/
			
			function threeStart() {
				try{
					initThree();                    // レンダラーの設定
					initCamera();                   // カメラの設定
					initScene();                    // シーンの宣言
					initLight();                    // 光源の設定とシーンへの追加
					initObject();                   // 立方体の宣言とシーンへの追加
					renderer.clear();               // Three.js の初期化
					renderer.render(scene, camera); // カメラの準備
					loop();                         // アニメーション開始
				}catch(e){
					alert(e);
				}
			}
			
			/**************************************************
			 * アニメーション
			 **************************************************/
			function loop() {
				
				//移動計算
				cameraPos3.x += (cameraTarget3.x - cameraPos3.x) * 0.2;
				cameraPos3.y += (cameraTarget3.y - cameraPos3.y) * 0.2;
				cameraPos3.z += (cameraTarget3.z - cameraPos3.z) * 0.2;
				distance += (distanceTarget - distance) * 0.2;
				
				$('#canvas-frame .cameraPos3_x').html(cameraPos3.x);
				$('#canvas-frame .cameraPos3_y').html(cameraPos3.y);
				$('#canvas-frame .cameraPos3_z').html(cameraPos3.z);
				$('#canvas-frame .distanceTarget').html(distanceTarget);
				$('#canvas-frame .distance').html(distance);
				
				//カメラを動かす
				camera.position.x = distance * Math.sin( cameraPos3.x * Math.PI / 180 ) + monster.x;
				camera.position.y = distance * Math.tan( cameraPos3.y * Math.PI / 180 ) + monster.y;
				camera.position.z = distance * Math.cos( cameraPos3.z * Math.PI / 180 ) + monster.z;
				
				$('#canvas-frame .camera_position_x').html(camera.position.x);
				$('#canvas-frame .camera_position_y').html(camera.position.y);
				$('#canvas-frame .camera_position_z').html(camera.position.z);
				
				// 視野の中心座標の設定
				camera.lookAt( {x:monster.x + lookAt_x, y:monster.y + lookAt_y, z:monster.z + lookAt_z } );
				
				$('#canvas-frame .lookAt_x').html(lookAt_x + monster.x);
				$('#canvas-frame .lookAt_y').html(lookAt_y + monster.y);
				$('#canvas-frame .lookAt_z').html(lookAt_z + monster.z);
				
				$('#canvas-frame .monster_x').html(monster.x);
				$('#canvas-frame .monster_y').html(monster.y);
				$('#canvas-frame .monster_z').html(monster.z);
				
				// キーが押されているかチェック
				for(var key in keyState){
					if(keyState[key]){
						switch(key){
							// 前進 : W
							case '87':
								forward();
								break;
							// 後退 : S
							case '83':
								back();
								break;
							// 左移動 : A
							case '65':
								left();
								break;
							// 右移動 : D
							case '68':
								right();
								break;
							// 左回転 : J
							case '74':
								roll_left();
								break;
							// 右回転 : L
							case '76':
								roll_right();
								break;
							// カメラ左回転 : 左矢印
							case '37':
								hidari();
								break;
							// カメラ上回転 : 上矢印
							case '38':
								ue();
								break;
							// カメラ右回転 : 右矢印
							case '39':
								migi();
								break;
							// カメラ上回転 : 下矢印
							case '40':
								shita();
								break;
							// ズームイン : [
							case '219':
								zoomIn();
								break;
							// ズームアウト : ]
							case '221':
								zoomOut();
								break;
							// 爆発音 : G
							case '71':
								audio.play();
								break;
							default:
								break;
						}
					}
				}
				
				// 地面を生成していない領域に侵入したら地面を生成
				var x = Math.round(monster.x/1000)*1000;
				var z = Math.round(monster.z/1000)*1000;
				if(land.indexOf(x+','+z)<0){
					// 地面
					plane = new THREE.Mesh(
						new THREE.PlaneGeometry(1000, 1000, 5, 5),
						new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/turf.png')})
					);
					scene.add(plane);
					plane.position.set(x, 0, z);
					
					land.push(x+','+z);
				}
				
				renderer.clear();
				renderer.render(scene, camera);
				window.requestAnimationFrame(loop);
			} 
			
			/**************************************************
			 * 読み込み完了後の処理
			 **************************************************/
			$(document).ready(function(){
				try{
					// レンダリングの実行
					threeStart();
				}catch(e){
					alert('Err-'+e);
				}
			});
		</script>
	</head>
	<body>
		<div id="canvas-frame">
			<!-- 情報表示領域 -->
			<div style="position:fixed;z-index:1000;top:0;left:0;">
				カメラの位置<br>
				camera.position.x : <span class="camera_position_x"></span><br>
				camera.position.y : <span class="camera_position_y"></span><br>
				camera.position.z : <span class="camera_position_z"></span><br>
				distanceTarget : <span class="distanceTarget"></span><br>
				視点 : <span class="viewpoint"></span><br>
				lookAt_x : <span class="lookAt_x"></span><br>
				lookAt_y : <span class="lookAt_y"></span><br>
				lookAt_z : <span class="lookAt_z"></span><br>
				移動計算<br>
				cameraPos3.x : <span class="cameraPos3_x"></span><br>
				cameraPos3.y : <span class="cameraPos3_y"></span><br>
				cameraPos3.z : <span class="cameraPos3_z"></span><br>
				distance : <span class="distance"></span><br>
				位置<br>
				monster_x : <span class="monster_x"></span><br>
				monster_y : <span class="monster_y"></span><br>
				monster_z : <span class="monster_z"></span><br>
				向き<br>
				monster_angle : <span class="monster_angle">0</span><br>
				入力キー<br>
				e.keyCode : <span class="e_keyCode"></span><br>
				マウス<br>
				X : <span class="clientX"></span><br>
				Y : <span class="clientY"></span><br>
				テスト<br>
				<span class="test"></span><br>
				<span class="test2"></span><br>
			</div>
		</div>
	</body>
</html>

添付ファイル: filecreeper.jpg 149件 [詳細] filecreeper.zip 70件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-01-16 (土) 18:03:29 (435d)