遊戲編程中需要掌握哪些數學物理知識

一、

相似三角形知識的應用

在搖桿控制物體運動的遊戲中,搖桿的手柄(下圖黃色圓餅),不能移出搖桿所在的套(下圖灰色圓環),也就是說搖桿偏離中心點的最大距離為max_R。一旦觸摸移動過程中移動的點超出此最大距離,我們需要將搖桿手柄拖回到最大距離處。

遊戲編程中需要掌握哪些數學物理知識

如何將搖桿拖回到灰色圓環處,無非是要求出在C點的座標。根據△ODC和△OBA為相似三角形,有OD:OB = OC:OA,也就是?:pos.x = max_R:len

其中pos為A點的座標(x,y),len為向量OA的模。

?表示C點的x座標,也就是但是我們求出來,要作為新的pos,去設置搖桿的位置。

所以有:

遊戲編程中需要掌握哪些數學物理知識

二、 單位向量

在搖桿控制物體的運動時,如果搖桿只控制物體的方向,也就是說不管搖桿偏離原點多遠,都不會影響物體運動的速度,而隻影響物體運動的方向,也就是實質上我們要獲取一個方向的值(比如向量與x軸正方向的夾角),這時候,我們就需要使用單位向量。

單位向量是指向量的模為1的向量,也就是以一個單位長度為半徑畫一個圓,從圓心指向圓周上任意一點的向量都是單位向量。

假設單位向量OA與x軸正向的夾角為α,則向量OA可以用(cosα,sinα)表示,也就是A點的座標。如下圖所示:

遊戲編程中需要掌握哪些數學物理知識

所以不管任何向量,我們要轉換為單位向量,只需要計算出這個向量的餘弦和正弦值就可以了。例如向量OC我們將其轉換為單位向量就是OC’,因為OC’的長度為1,所以向量OC’的座標就是(cos(c),sin(c)),c為OC和x軸正方向的夾角。而OC’和OC的方向是重合的,他們與x軸正向夾角相等,也就是我們只需要計算向量OC的cos(c)、sin(c)即可。

假設得到的C點座標為pos(x,y),則在Cocos遊戲開發中,會有下列代碼:

var len = pos.mag(); // 求向量pos的模(內部算法是(x2+y2)開根號)。

pos.x = pos.x / len; // 得到單位向量的x座標

pos.y = pos.y/ len; // 得到單位向量的y座標

三、 弧度角度轉換

角度指從原點發出的射線與X軸正向的角度。而x軸正向繞原點在水平平面內旋轉一週為360°。而弧度是指圓弧長度與半徑的比值。假設有個半徑r為1的圓,則其一週為360°。圓周對應的弧度長為2πr=2π。也就是說在角度轉換為弧度是360°等價於2π,180°等價於π。

(1)弧度轉換為角度:根據 degree : 180 = rad:π

var rad = Math.atan2(y, x); // 反正切函數,得到弧度

var degree = 180 * rad / Math.PI ; // 將弧度rad轉換為角度

(2)角度轉換為弧度:根據rad:π=degree:180

var degree = 90;

var rad = Math.PI * degree / 180; // 角度轉換為弧度

四、 向量轉換為夾角

在遊戲中,有時候我們需要計算物體旋轉了多少度,比如我們要模擬一個KTV裡面的遊戲轉盤,手指觸摸的時候,要獲取觸摸的點的位置,觸摸點的位置與轉盤中心點之間構成一個向量,我們要獲取轉動了多少度,就需要有一個參考向量。

如下圖所示,假如藍色的圓就是轉盤的邊緣,我們最開始觸摸A點,然後轉動到B點,這時候轉動的角度就是∠AOB,這個角度在Cocos中如何求呢?

代碼pos就表示B點的座標,pos和原點(0,0)相減,得到向量OB,也即代碼中的dirVec,弧AB為radian,轉換為角度degree。

遊戲編程中需要掌握哪些數學物理知識

// 向量轉換為角度

vectorsToDegree(dirVec) {

// 水平向右的對比向量

let comVec = cc.v2(1, 0);

// 求方向向量與對比向量間的弧度

let radian = dirVec.signAngle(comVec);

// 將弧度轉換為角度

let degree = cc.misc.radiansToDegrees(radian);

return degree;

},

調用示例(具體可以參考我們的《KTV酒令轉盤虛擬仿真實現》):

// 獲取觸摸點與原點連線的射線與X軸正向的角度

getTouchAngle(e){

var screen_pos = e.getLocation(); // 觸摸點世界座標

// 轉換為相對於當前節點的錨點的座標

var pos = this.node.convertToNodeSpaceAR(screen_pos);

// 獲取觸摸點距離輪盤中心點的向量

var dirVec = pos.sub(cc.v2(0,0));

// 將向量轉換為基於參考方向(v2(0,1))的角度

return this.vectorsToDegree(dirVec);

},

五、 切水果遊戲中的拋物線

重力加速g:

Vy = V0 + g * t;

h = V0 * t + 0.5 * g * t * t;

斜拋運動(如下圖所示):

分解到水平上: 勻速直線運動;

分解到豎直方向: 勻變速直線運動 (加速度)。

遊戲編程中需要掌握哪些數學物理知識

具體在Cocos中如何實現,限於篇幅,在此不做贅述,可以參考我們的公開課《切水果》核心技術:拋物線物理仿真。

六、 如何產生不重複的隨機序列

應用場景:例如洗牌,發牌,例如掃雷遊戲中從100個格子中隨機抽取10個埋雷。

凡是需要打亂順序,或者從某個數組中抽取一定數量的不重複的元素,都用得著。

// 數組工具類

var ArrayUtils = function(){};

// 【1】初始化得到有序元素數組:[start,end)的自然數序列

ArrayUtils.initOrderArray = function(start, end){

let sortArray = [];

for(let i= start; i

sortArray.push(i);

}

return sortArray;

};

// 【2】從數組arr中隨機抽取count個元素,返回數組

ArrayUtils.randChoiseFromArr = function(arr, count){

let result = arr;

// 隨機排序,打亂順序

result.sort(function(){

return 0.5 - Math.random();

});

// 返回打亂順序後的數組中的前count個元素

return result.slice(0,count);

};

// 【3】從從start到end中的連續整數中隨機抽取count個數字

ArrayUtils.randChoiseFromTo = function(start, end, count){

let arr = this.initOrderArray(start,end);

return this.randChoiseFromArr(arr, count);

};

// 【2】-【方式二】從數組arr中隨機抽取count個元素,返回數組

ArrayUtils.getRandomArrayElements = function(arr, count) {

// 從0位置取到結束位置存入shffled數組

let shuffled = arr.slice(0);

let i = arr.length;

let min = i - count;

let temp = 0;

let index = 0;

// 隨機一個位置的元素和最後一個元素交換

// 隨機一個位置元素和倒數第二個元素交換

// 假設i=8,count=3,則min=5,

// 循環體中[i]=7,6,5,也就是說最後三個元素要從數組中隨機取

// 循環結束後,從min=5的位置取到結束,即取3個元素。

while(i-- > min) {

index = Math.floor((i + 1) * Math.random());

temp = shuffled[index];

shuffled[index] = shuffled[i];

shuffled[i] = temp;

}

return shuffled.slice(min);

};

module.exports = ArrayUtils;

原理解析:如上述代碼,方式一randChoiseFromArr 方法,採用隨機排序打亂數組中所有元素的順序,然後從數組第一個元素開始抽取需要的count個元素。

方式二getRandomArrayElements方法,需要取幾個元素,就隨機幾個位置和倒數最後幾個元素交換,最後取倒數最後幾個元素即可。注意:index = Math.floor((i

+ 1) * Math.random()); i+1才能保證最後一個元素可能是自身和自身交換,也就是保證這個位置的元素可能是原有這個位置的元素。

上面所有代碼我們已經全部測試通過,感興趣的朋友可以自己動手去實踐。

相似三角形、單位向量轉換、弧度角度轉換,大家可以看我們的公開課《Cocos Creator坦克大戰遊戲》。向量轉換為夾角在我們公開課《KTV酒令轉盤虛擬仿真實現》中講過。如何產生不重複的隨機序列,在掃雷遊戲中應用。需要這方面資料視頻的朋友,可以點擊下面鏈接加群瞭解點擊鏈接加入群聊【cocos/unity交流群】


分享到:


相關文章: