Java 使用libgdx平滑移动和旋转游戏对象
我试图学习一些游戏开发,当我回忆起我在生活中学习的线性代数和向量数学时,我也开始玩libgdx 我首先想做的是一个简单的旋转运动,我想出了一个方法,通过计算从当前方向到所需方向的角度来实现。虽然它对静止的精灵有效,但向它添加运动证明它是错误的,因为精灵正在做一个U形转弯,不是指向点,而是指向点的方向 该示例在这里用Scala实现。有问题的代码位于类中 以下是本课程的主要部分,仅供快速参考:Java 使用libgdx平滑移动和旋转游戏对象,java,scala,libgdx,Java,Scala,Libgdx,我试图学习一些游戏开发,当我回忆起我在生活中学习的线性代数和向量数学时,我也开始玩libgdx 我首先想做的是一个简单的旋转运动,我想出了一个方法,通过计算从当前方向到所需方向的角度来实现。虽然它对静止的精灵有效,但向它添加运动证明它是错误的,因为精灵正在做一个U形转弯,不是指向点,而是指向点的方向 该示例在这里用Scala实现。有问题的代码位于类中 以下是本课程的主要部分,仅供快速参考: def update(delta: Float) { rotate(delta) move(del
def update(delta: Float) {
rotate(delta)
move(delta)
}
private def move(delta: Float) {
velocity.set(direction).scl(movementSpeed)
position.add(velocity.scl(delta))
}
private def rotate(delta: Float) {
val current = direction.angle()
val target = targetDirection.angle()
if (current != target) {
val rotateAngle = rotationSpeed * delta
val left = distance(current, target)
val right = distance(target, current)
if (left < right) rotateLeft(current, left, rotateAngle)
else rotateRight(current, right, rotateAngle)
}
}
private def distance(start: Float, end: Float): Float = {
val angle = start - end
if (angle < 0) angle + 360 else if (angle > 360) angle - 360 else angle
}
private def rotateLeft(current: Float, target: Float, angle: Float) {
if (target - angle < 0) direction.set(targetDirection)
else direction.setAngle(direction.angle() - angle)
}
private def rotateRight(current: Float, target: Float, angle: Float) {
if (target - angle < 0) direction.set(targetDirection)
else direction.setAngle(direction.angle() + angle)
}
现在,我觉得有一个更干净的解决方案,使用一些向量,位置,速度,方向和可能的目的地,但我有点卡住了,不知道从这里去哪里
我想要一种行为,你可以从一个rts太空游戏中想象到,在为一艘飞船设置目的地后,它会朝那个方向移动,但不只是切换方向,而是平稳地转弯,从鼠标点击的地方准确地移动到目标点
非常感谢您的帮助。您需要一个航向,定义为以弧度或度数表示的角度。让我们假设一个0分的航向,向右90分,向下180分,向左270分 根据你的航向和速度,每次使用基本三角来计算你的三角洲和三角洲 算出你的目标位置,然后再次使用基本三角法算出目标航向,从你的飞船指向目标位置 将当前标题向目标标题移动,每帧增加一点 如果您在上述过程中的某个特定部分遇到问题,请发布一篇不是您的整个项目的文章,以展示您目前的成果,我们将从这里开始。我找到了这一页,它帮助我理解了这一点。我用向量代数替换了我的天真实现,结果如下
private def rotate(delta: Float) {
val targetHeading = destination.cpy.sub(position).nor
val angle = angleBetween(heading, targetHeading)
if (angle != 0) {
if (Math.abs(angle) < rotationSpeed / 50) heading.set(targetHeading)
else {
val rotation: Float = Math.max(Math.abs(angle), rotationSpeed) * delta
if (angle > 0) heading.rotate(rotation)
else heading.rotate(-rotation)
}
}
}
我的问题是,在调用rotate的每个更新循环中设置目标点而不是更新目标点时,会计算先前的targetDirection。方法如下所示
private def angleBetween(v1: Vector2, v2: Vector2): Float = {
val result = Math.toDegrees(Math.atan2(v2.y, v2.x) - Math.atan2(v1.y, v1.x)).toFloat
if (result < -180) result + 360
else if (result > 180) result - 360
else result
}
所以它只是计算两个向量之间的角度。重要的是结果在-180范围内,180决定了转弯的方向
现在,当船到达目的地时,它开始绕目的地转一圈,但实施停止行为将是微不足道的,只是为了防止位置。谢谢你的提示。在阅读了你的答案后,我发现了这个网站,它极大地帮助我理解了这应该如何工作。