[英]How to get to an angle choosing the shortest rotation direction
我的游戲中有一個角色必須順利旋轉才能達到理想的角度。 將angle
視為當前角度,將touchAngle
視為所需角度,始終在0到360之間。我想在每次游戲更新中將+ 1 / -1添加到當前角度以獲得所需的touchAngle
。 問題首先是它必須選擇方向,它必須在0到360之間。這是我的偽代碼:
int touchAngle;
float angle;
public void update()
{
if ((int)angle != touchAngle) angle += ???
}
由於您的值在區間[0 360]
中始終是標准化的,因此這不應該太難。 您只需要區分兩種不同的情況:
angle < touchAngle
angle > touchAngle
在第一種情況下,我們想要逆時針旋轉,因此更新必須是angle =+ 1
(假設您希望每個更新周期都轉1)。 在第二種情況下,我們想要順時針轉動,因此更新應該是angle -= 1
。
問題是這並不總是最短的旋轉方式。 例如,如果:
angle == 359
touchAngle == 1
我們不想一直使用358,357,356 ...而是我們想要逆時針旋轉2個單位: abs(angle - touchAngle)
。這可以通過比較角度abs(angle - touchAngle)
之間的距離來實現。
如果這個值大於180
則意味着我們的方向錯誤,所以我們必須這樣做
if(angle < touchAngle) {
if(abs(angle - touchAngle)<180)
angle += 1;
else angle -= 1;
}
else {
if(abs(angle - touchAngle)<180)
angle -= 1;
else angle += 1;
}
當然所有這些直到((int)angale != touchAngle)
。 我可能在案件中犯了錯誤,但這是原則。
通常你想帶的時間等式,這樣就可以平滑地改變角度可達time
。 大多數設置都有辦法獲得渲染前一幀所花費的時間,而這樣做的典型方法就是說..
int touchAngle;
float angle;
float deltaTime; //Time it took to render last frame, typically in miliseconds
float amountToTurnPerSecond;
public void update()
{
if((int)angle != touchAngle) angle += (deltaTime * amountToTurnPerSecond);
}
這將使每秒,你的角度由amountToTurnPerSecond
改變,但在每一幀上緩慢改變正確的變化量,使其平滑。 需要注意的是,大多數時候你不會在touchAngle
均勻地結束,所以檢查一下你是否過去而不是設置為touchAngle
會是一個好主意。
編輯以跟進評論:
我認為獲得正確轉彎方向的最簡單方法實際上根本就不是使用角度。 您需要在二維空間中獲得從觸摸到角色的相對方向。 通常你從屏幕空間到世界空間進行觸摸,然后在那里進行計算(至少這是我過去所做的)。 首先觸摸世界空間,然后使用矢量十字產品來確定方向。 這看起來有點像以下......
character position = cx, cy
target position = tx, ty
current facing direction of character = rx, ry
首先我們取角色和目標位置之間的距離:
dx = tx - cx
dy = ty - cy
這不僅告訴我們離我們有多遠,而且基本上告訴我們如果我們在0,0,那么目標在2d空間中的哪個象限?
接下來我們做一個交叉產品:
cross_product = dx * ry - dy * rx
如果這是積極的你走一條路,如果它是負面的你走另一條路。 這樣做的原因是,如果距離是例如(-5, 2)
那么我們就知道如果我們正對着北方,那么我們的左邊是5,前進是2.所以我們向左轉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.