一旦玩家击中pi,玩家轮换时的转速为360

HKV*_*ant 15 math mouse triggers go game-physics

使用Golang制作游戏,因为它似乎对游戏非常有效.我让玩家总是面向鼠标,但想要一个转弯率使某些角色变得比其他角色慢.以下是计算转弯圈的方法:

func (p *player) handleTurn(win pixelgl.Window, dt float64) {
    mouseRad := math.Atan2(p.pos.Y-win.MousePosition().Y, win.MousePosition().X-p.pos.X) // the angle the player needs to turn to face the mouse
    if mouseRad > p.rotateRad-(p.turnSpeed*dt) {
        p.rotateRad += p.turnSpeed * dt
    } else if mouseRad < p.rotateRad+(p.turnSpeed*dt) {
        p.rotateRad -= p.turnSpeed * dt
    }
}
Run Code Online (Sandbox Code Playgroud)

mouseRad是转向面对鼠标的弧度,我只是添加转弯率[在这种情况下,2].

发生的事情是当鼠标到达左侧并穿过中心y轴时,弧度角从-pi变为pi,反之亦然.这会导致玩家完整360.

解决这个问题的正确方法是什么?我已经尝试使角的绝对值和它仅由它发生在pi和0 [左正方形的右侧在中心处y轴上.

我附上了一个问题的GIF,以提供更好的可视化.GIF

基本概要:

播放器慢慢旋转以跟随鼠标,但是当角度达到pi时,它会改变极性,这会导致玩家进行360 [将所有背部计数到相反的极性角度].

编辑:dt是增量时间,只是为了显示运动中正确的帧解耦变化

p.rotateRad从0开始,是一个float64.

Github回复暂时:在这里

你需要这个库来构建它![去实现它(梦想);去得到它(东西]

icz*_*cza 7

事先注意:我下载了你的示例repo并在其上应用了我的更改,它完美无缺.这是它的录音:

固定光标跟随

(供参考,GIF记录byzanz)


一个简单而简单的解决方案是不比较角度(mouseRad和变化的p.rotateRad),而是计算和"标准化"差异,使其在范围内-Pi..Pi.然后,您可以根据差异的符号(负面或正面)决定转向哪种方式.

"归一化"角度可以通过加/减2*Pi直到它落在该-Pi..Pi范围内来实现.加/减2*Pi不会改变角度,因为2*Pi正好是一个完整的圆.

这是一个简单的规范化函数:

func normalize(x float64) float64 {
    for ; x < -math.Pi; x += 2 * math.Pi {
    }
    for ; x > math.Pi; x -= 2 * math.Pi {
    }
    return x
}
Run Code Online (Sandbox Code Playgroud)

并在handleTurn()这样使用它:

func (p *player) handleTurn(win pixelglWindow, dt float64) {
    // the angle the player needs to turn to face the mouse:
    mouseRad := math.Atan2(p.pos.Y-win.MousePosition().Y,
        win.MousePosition().X-p.pos.X)

    if normalize(mouseRad-p.rotateRad-(p.turnSpeed*dt)) > 0 {
        p.rotateRad += p.turnSpeed * dt
    } else if normalize(mouseRad-p.rotateRad+(p.turnSpeed*dt)) < 0 {
        p.rotateRad -= p.turnSpeed * dt
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在这个有效的Go Playground演示中使用它.

请注意,如果存储角度归一化(在范围内-Pi..Pi),normalize()函数中的循环最多只能进行1次迭代,因此速度非常快.显然你不想存储像是100*Pi + 0.1一样的角度0.1.normalize()使用这两个输入角度将产生正确的结果,而前者的情况下的循环将具有50次迭代,在后者的情况下将具有0次迭代.

另请注意,normalize()可以通过使用模拟整数除法和余数的浮点运算来优化"大"角度,但如果您坚持标准化或"小"角度,则此版本实际上更快.