之前一段時間家裡和公司的事太多,一直沒有時間寫部落格,最近騰出一段時間,看了一遍官方的examples,收貨頗多,想整理一點東西出來,又苦於沒有好的東西,three寫點東西真是太難了。好吧,今天郭先生就寫一個小汽車的3D遊戲,如下圖
這個遊戲幾乎沒用新的知識點,用了只有有向包圍盒OBB。官方demo,線案例請點選部落格原文。但是在做遊戲之前先來複習幾個知識。
1 有向包圍盒OBB
在之前的文章有專門寫過Box3盒模型,它屬於軸對齊包圍盒,而OBB包圍盒是一種有向的包圍盒,顯而易見他們的最大區別就是包圍盒是否隨模型轉動,從他們的構造引數就可以看出一些特徵
Box3( min : Vector3, max : Vector3 ) min - Vector3 表示包圍盒的下邊界。 預設值是( + Infinity, + Infinity, + Infinity )。 max - Vector3 表示包圍盒的上邊界。 預設值是( - Infinity, - Infinity, - Infinity )。
OBB( center : Vector3, halfSize : Vector3, rotation : Matrix3 ) center - Vector3 表示包圍盒的中心。 預設值是( 0, 0, 0 )。 halfSize - Vector3 表示包圍盒的中心。 預設值是( 0, 0, 0 )。 rotation - Matrix3 表示包圍盒的中心。 預設值是( 1, 0, 0, 0, 1, 0, 0, 0, 1 )。
OBB的rotation是一個三維矩陣(而不是尤拉角,注意區別Object3D的rotation屬性),它裡面包含著盒模型的方向資訊,除此之外幾乎和Box3相同,OBB的方法和Box3也幾乎相同。
2 尤拉角
在做遊戲的過程中我們也需要了解一下尤拉角,它的前三個引數可以十分方便的表示旋轉,但是如果繞多個軸同時旋轉的時候可能就會遇到難以解決的問題了,這個時候可能就會用到第四個引數order。下面我們舉個例子。
如上圖有兩個幾何體(模擬兩個輪子)mesh1和mesh2,mesh1車軸在z軸,mesh2在x軸。現在我們只讓他們沿車軸轉動,只需要改變一個引數即可。
mesh1.rotation.copy(new THREE.Euler(0, 0, z)); mesh2.rotation.copy(new THREE.Euler(x, 0, 0));
但是當我們現在不僅要讓他們沿車軸滾動,還需要沿著y軸傳動,具體轉動如下
mesh1.rotation.copy(new THREE.Euler(0, y, z)); mesh2.rotation.copy(new THREE.Euler(x, y, 0));
但是得到的結果和我們想要的就不大一樣了,mesh1沿著y軸轉動的同時沿可以沿著z軸轉動,而mesh2旋轉就很奇怪。這件事就是因為尤拉角三個維度的旋轉是有順序的,在mesh1中y軸的轉動不會受到z軸的影響,因為沿y軸會先於z軸旋轉,而mesh2中y軸的轉動就會受到x軸的影響,因此我們需要尤拉角的第四個引數order
mesh2.rotation.copy(new THREE.Euler(x, y, 0, 'YZX'));
這樣就可以正常旋轉了
3 遊戲中用到的變數和常量
這節只說一下用到的變數,下一節在繼續說。
let camera, camera2, scene, scene2; let car = new THREE.Group(), orthoCar = new THREE.Group(), carHalfSize = new THREE.Vector3(), tyreArray = [], steering_wheel, buildObbArray = []; const carHeight = 10, rotateMax = Math.PI / 6, speedCorrection = 0.04, rotateCorrection = 0.002,
let speed = 0, rotateTyre = 0, rotateRun = 0, rotateVector = new THREE.Vector3(1,0,0); let view = 0;
camera, camera2: 分別是透視相機和正交投影相機
scene, scene2: 分別是主場景和小地圖場景
car: 小車模型
orthoCar: 小地圖中的小車模型
carHalfSize: 小車半長寬高資料
tyreArray: 包含小車四個輪子的組
steering_wheel: 小車的方向盤
buildObbArray: 建築物陣列
carHeight: 車高
rotateMax: 車轉彎最大角度
speedCorrection, rotateCorrection: 速度係數和角度係數
speed: 車速
rotateTyre: 車輪相對於車的角度
rotateRun: 車相對於場景的旋轉角度
rotateVector: 車前進方向向量,和rotateRun意義相同(表現形式不同)
ivew: 車的視角,0代表車內,1代表車外
下一節我們接著說。
轉載請註明地址:郭先生的部落格