我正在開發一個平臺游戲,我希望有一個指向令牌的箭頭:
只需將箭頭捕捉到令牌就可以了 - 一切正常:
const dist_x = player.x - token.x
const dist_y = player.y - token.y
const angle = Math.atan2(dist_y, dist_x)
arrow.angle = angle
但問題是我希望箭頭圍繞令牌擺動,如下所示。它作業正常,但是當箭頭的角度接近 360 并且令牌的角度接近 0 時,代碼認為箭頭需要一直擺動到零 - 而不是只是加起來一點點很好回圈。這是我的代碼:
const dist_x = player.x - token.x
const dist_y = player.y - token.y
const angle = Math.atan2(dist_y, dist_x) // angle between arrow & token
arrow.angle = arrow.rot_speed // acceleration
arrow.rot_speed *= .9 // slowly calm down
// distance between goal angle of arrow and angle at the moment
const angle_dist = angle - arrow.angle
// move in that direction
arrow.rot_speed = angle_dist
這個問題在很多場合對我來說都是一個很大的阻礙,所以我會很感激任何幫助。
uj5u.com熱心網友回復:
要解決這樣的問題,您需要檢查您擺動的角度差是否低于 180,如果不是,則將您擺動的角度添加 360。我認為這將解決它會擺動的部分。我不知道您將如何在代碼中實作這一點,但這是我在以前的經驗中遇到的通用解決方案。
當然,您需要將所有這些轉換為弧度:D
uj5u.com熱心網友回復:
我不確定這是否有幫助。假設有dist_x
和dist_y
用于獲取角度的值,atan2()
如下所示
N = 8
r = 1
console.log("angle dist_x dist_y atan2 angle")
for(i = 0; i < N; i ) {
q = (i / 8) * 2 * Math.PI
dist_x = r * Math.cos(q)
dist_y = r * Math.sin(q)
theta = Math.atan2(dist_y, dist_x)
theta2 = theta
if(q > Math.PI) {
theta2 = 2 * Math.PI
}
console.log(
q.toFixed(3),
dist_x.toFixed(3),
dist_y.toFixed(3),
theta.toFixed(3),
theta2.toFixed(3)
)
}
產生
angle dist_x dist_y atan2 angle
0.000 1.000 0.000 0.000 0.000
0.785 0.707 0.707 0.785 0.785
1.571 0.000 1.000 1.571 1.571
2.356 -0.707 0.707 2.356 2.356
3.142 -1.000 0.000 3.142 3.142
3.927 -0.707 -0.707 -2.356 3.927 <---
4.712 -0.000 -1.000 -1.571 4.712 <---
5.498 0.707 -0.707 -0.785 5.498 <---
這表明導致第三和第四象限
第三象限:
dist_x < 0
,第四象限dist_y < 0
:dist_x > 0
,dist_y < 0
必須加上 2 PI 才能獲得 0 到 2 PI 之間的所有角度。
編輯
給定代碼的可能實作
..
const angle = Math.atan2(dist_y, dist_x) // angle between arrow & token
/*
result of atan2():
dist_x > 0, dist_y > 0 ==> 0 < angle < PI/2 (1st quadrant)
dist_x < 0, dist_y > 0 ==> PI/2 < angle < PI (2nd quadrant)
dist_x < 0, dist_y < 0 ==> -PI < angle < -PI/2 (3rd quadrant)
dist_x > 0, dist_y < 0 ==> -PI/2 < angle < 0 (4th quadrant)
*/
// Map all angles from (-PI, PI) to (0, 2 PI)
if(dist_y < 0) angle = 2 * Math.PI
uj5u.com熱心網友回復:
謝謝@Aquil Contractor 的回答,我玩弄了代碼,這是我想出的解決方案:
const dist_x = player.x - token.x
const dist_y = player.y - token.y
let angle = Math.atan2(dist_y, dist_x) // angle between arrow & token
const quarter = Math.PI / 2 // equivalent to 90° (I just thought I'd mention)
/* if the angles are further than 180° away from each
other, bring the goal angle toward the current. */
if (arrow.angle > quarter && angle < -quarter) angle = Math.PI * 2
else if (arrow.angle < -quarter && angle > quarter) angle -= Math.PI * 2
arrow.angle = arrow.rot_speed
arrow.rot_speed *= .9
arrow.rot_speed = angle - arrow.angle
該解決方案比我預期的要簡單得多,但效果很好并且很有意義。
感謝大家的幫助和想法!
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/480072.html
標籤:javascript 数学 游戏开发
上一篇:在Python中求解線性方程組