Java 使用libgdx平滑移动和旋转游戏对象

Java 使用libgdx平滑移动和旋转游戏对象,java,scala,libgdx,Java,Scala,Libgdx,我试图学习一些游戏开发,当我回忆起我在生活中学习的线性代数和向量数学时,我也开始玩libgdx 我首先想做的是一个简单的旋转运动,我想出了一个方法,通过计算从当前方向到所需方向的角度来实现。虽然它对静止的精灵有效,但向它添加运动证明它是错误的,因为精灵正在做一个U形转弯,不是指向点,而是指向点的方向 该示例在这里用Scala实现。有问题的代码位于类中 以下是本课程的主要部分,仅供快速参考: def update(delta: Float) { rotate(delta) move(del

我试图学习一些游戏开发,当我回忆起我在生活中学习的线性代数和向量数学时,我也开始玩libgdx

我首先想做的是一个简单的旋转运动,我想出了一个方法,通过计算从当前方向到所需方向的角度来实现。虽然它对静止的精灵有效,但向它添加运动证明它是错误的,因为精灵正在做一个U形转弯,不是指向点,而是指向点的方向

该示例在这里用Scala实现。有问题的代码位于类中

以下是本课程的主要部分,仅供快速参考:

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决定了转弯的方向


现在,当船到达目的地时,它开始绕目的地转一圈,但实施停止行为将是微不足道的,只是为了防止位置。

谢谢你的提示。在阅读了你的答案后,我发现了这个网站,它极大地帮助我理解了这应该如何工作。