当前位置: 首页 > 知识库问答 >
问题:

基于物理学的二维运动:随时间改变物体的方向

卢骏俊
2023-03-14

我目前正在用Java开发一个2D太空游戏,你可以在太空中控制一艘船。游戏不使用任何外部库。

船应该向光标移动。然而,当移动光标时,旧的力量并没有神奇地消失;随着时间的推移,船改变了航向,最终朝着期望的方向移动。

然而,我遇到了一个关于船只移动的问题。基本上,我想要实现的是这张图片的粗略说明:

这张图片显示了船在一次比赛中应该如何移动。进一步解释:

>

目标角是光标当前所在的位置。

当前角度是船舶当前行驶的方向。

当前角度应该越来越接近目标角度,直到它达到这两个角度相同的点。

船应该朝着目标角度改变方向,采取尽可能短的路线;它可以向左和向右转弯,而不仅仅是向左或向右转弯。

现在我已经解释了我想要实现的目标,现在我将描述到目前为止我已经实现了什么,以及它是如何工作的。

基本上,“船”是一个坐在屏幕中央的图像。当你“移动”船时,船保持不动;移动的是游戏区的其余部分。

船相对于代表游戏区域的坐标系的当前“位置”是整数xPos和yPos。

下面是一些演示系统工作原理的示例代码:

 int xPos;
 int yPos;

 public void updateMovement() {
     xPos += xSpeed;
     yPos += ySpeed; 
 }

 public void moveForward() {
     double yTempSpeed = ySpeed;
     double xTempSpeed = xSpeed;
     yTempSpeed += 0.01 * Math.sin(Math.toRadians(targetAngle));
     xTempSpeed += 0.01 * Math.cos(Math.toRadians(targetAngle));
     double resultVector = Math.sqrt(xTempSpeed * xTempSpeed + yTempSpeed * yTempSpeed);
     if (resultVector < 2) {
         ySpeed += 0.01 * Math.sin(Math.toRadians(targetAngle));
         xSpeed += 0.01 * Math.cos(Math.toRadians(targetAngle));
 }

该代码成功地将船舶的最大速度设置为所需值,但是,如果结果“矢量”大于2,即速度已经达到最大值,并且目标角度大于2,则该代码不起作用(船舶的航向不会改变)太接近船只当前行驶的角度(-Pi/2)。

我将如何去改变基于此实现的当前角度?

共有3个答案

钱俊楚
2023-03-14

您可能会发现以下(Swift)代码很有用,尽管您需要自己处理船舶线速度和角速度的每帧积分:

func moveShipTowards(location: CGPoint) {
    if let ship = shipNode? {

        let distanceVector = CGVector(origin: ship.position, point: location)
        let targetAngle = distanceVector.angle
        let shipAngle = ship.zRotation
        var dø = targetAngle - shipAngle

        // convert to shortest arc
        if dø > π {
            dø -= 2.0 * π
        } else if dø < -π {
            dø += 2.0 * π
        }

        // resulting angular velocity
        ship.physicsBody.angularVelocity = 12 * dø.clampedTo(π)

        var velocityUnitVector = CGVector(cosf(ship.zRotation), sinf(ship.zRotation))
        var magnitude = distanceVector.length.clampedTo(400)

        ship.physicsBody.velocity = velocityUnitVector * magnitude
    }
}

它处理的是在接近目标点时让船减速。现在来看,它似乎不能正确处理加速度。

邓正真
2023-03-14

船的正常速度怎么样,不要让它超过你的速度限制(=2):

//it's good to put all constants out of a function in one place
//to make it easier if you ever wanted to change it
private final int MAX_SPEED = 2;
private final double ACCEL_FACTOR = 0.01;

public void moveForward() {
 ySpeed += ACCEL_FACTOR * Math.sin(Math.toRadians(targetAngle));
 xSpeed += ACCEL_FACTOR * Math.cos(Math.toRadians(targetAngle));

 //normalize ship speed, i.e. preserve ratio of xSpeed/ySpeed
 //but make sure that xSpeed^2 + ySpeed^2 <= MAX_SPEED^2

 //your code goes here
 //...

}

了解向量规范化。这样,船速的变化将正常应用(此时速度可以调整)

湛铭
2023-03-14
  public void moveForward() {
     ySpeed += 0.01 * Math.sin(Math.toRadians(targetAngle));
     xSpeed += 0.01 * Math.cos(Math.toRadians(targetAngle));
     double currentSpeed = Math.sqrt(xTempSpeed * xTempSpeed + yTempSpeed * yTempSpeed);
     if (currentSpeed > maxSpeed) {
         //the resulting speed is allways <= maxspeed (normed to that)
         ySpeed *= maxSpeed/currentSpeed;
         xSpeed *= maxSpeed/currentSpeed;
 }

希望这是你需要的。。。虽然航天器有最高速度是不现实的,但就“可玩性”而言,我也会这么做。

 类似资料:
  • 我正在构建一个迷宫游戏,在这里我有一个简单的地图... 直到没有问题,但我的问题是碰撞 这是我的地图: 在这里,我用以下代码自己构建了地图: 此碰撞代码用于右上角矩形 我已经尝试了两种不同类型的碰撞代码,但都不起作用 碰撞码: 在这里,当玩家从左侧击中矩形时,玩家向下移动,当玩家从底部击中矩形时,玩家向左移动。 我用if, else if语句尝试过相同的代码,但仍然不起作用。当玩家点击左侧时,它可

  • 本文向大家介绍基于OpenCv的运动物体检测算法,包括了基于OpenCv的运动物体检测算法的使用技巧和注意事项,需要的朋友参考一下 基于一个实现的基于OpenCv的运动物体检测算法,可以用于检测行人或者其他运动物体。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 真实世界中的光源 基于物理的光照符合真实世界中的光源描述,在真实环境中,我们所见到的光源产品都具有自身的工业参数,我们先来看一个宜家的灯泡 从产品包装上,我们可以了解到这个灯泡的几个重要工业参数: 功率 色温 尺寸 这三个重要参数影响真实世界中的光源表现效果,下面我们来重点讲解一下这三个参数的物理意义。 发光功率 发光功率就是我们通常所说的光源强度。Cocos Creator 3D 中使用 光学

  • 这是Three.js中大部分对象的基类,提供了一系列的属性和方法来对三维空间中的物体进行操纵。 请注意,可以通过.add( object )方法来将对象进行组合,该方法将对象添加为子对象,但为此最好使用Group(来作为父对象)。 构造器 Object3D() 构造器中不带有参数。 属性 .animations : AnimationClip Array with object's animati

  • 我正在开发一个增强现实应用程序,它可以识别物体并改变颜色。我可以为此使用Vuforia SDK,还是有其他更好的SDK可供使用? 有什么好的API用于动态三维对象建模吗

  • 注意:这将只显示有关使用Java消费者API的消费者(非基于ZooKeeper的消费者)的信息。 此工具还适用于基于ZooKeeper的使用者: bin/kafka-consumer-groups.sh--zookeeper localhost:2181--description--group my-group null PS:这似乎没有出现在2.5文档中