如何阻止游戏飞船向后加速?

时间:2019-10-03 22:00:18

标签: java animation javafx

我有一个带有飞船对象(带有JavaFX多边形)的游戏。当我用钥匙移动飞船时(通过EventHandlers和AnimationTimers),它会向上移动。当我放开时,它应该将加速度更改为-4,因此它会不断从船舶速度中减去-4,直到假定达到0。但是,由于船舶可以在所有方向上移动,因此速度有时为负数当船前进时。因此,当我尝试在速度为负数时停止飞船时,它不会发生,并且飞船会不断向后移动。

当船的速度为负并向前移动时,我尝试了一些计算,但是它有点太复杂了,我相信它没有用。

以下是“船舶计算速度x”方法的代码:

AnimationTimer calculateVelocityX = new AnimationTimer() {
        @Override
        public void handle(long now) {
            if (getAcceleration() == 17)
                setVelocityX(getVelocityX() + (Math.cos(Math.toRadians(getRotation())) * (getAcceleration() * 0.01)));
            else if (acceleration == -4)
                setVelocityX(getVelocityX() + (Math.cos(Math.toRadians(getTempRotation())) * (getAcceleration() * 0.01)));
        }
    };
    AnimationTimer shipAccelerationTimer = new AnimationTimer() {
        @Override
        public void handle(long now) {
            getShipImage().setLayoutX(getShipImage().getLayoutX() + getVelocityX());
            getShipImage().setLayoutY(getShipImage().getLayoutY() - getVelocityY());
            wrapShip();
            if (getVelocityX() == 0 && getVelocityY() == 0) {
                getCalculateVelocityX().stop();
                getCalculateVelocityY().stop();
                setAcceleration(17);
                setCounterOne(0);
                setCounterTwo(0);
                setCounterThree(0);
                getShipAccelerationTimer().stop();
            }
        }
    };

此代码将使船舶向后移动,因为由于十进制精度,速度实际上无法达到0。但是,如果我说当速度小于0时,根据我上面的说法是不可能的。

将货物沿指定方向移动时的速度标志图像:

UsbDk

因此,我不能只具有“当速度小于0时”,因为像在第2、3、4象限中一样,我可以向前移动,但是具有x,y负速度或两者都负。

2 个答案:

答案 0 :(得分:0)

如果我在你里面,我会考虑考虑速度的大小和方向,与正X和正Y相比,幅度> = 0且方向为±1。

答案 1 :(得分:0)

向后加速将不起作用,因为方向不是恒定的。

请考虑以下情况:船加速后停下之前,先向上加速然后向右旋转90度。 y方向上的零件速度分量永远不会变为0,但x方向上的运动方向将继续变化...

如果没有加速度,则需要沿与当前运动相反的方向减速,而不是根据船当前所面对的方向进行加速度。

我首先建议不要在此处使用3个注释来更改速度。这只会使您的代码不必要地复杂。您可以在一个动画中完成全部操作。

示例:

(代码保持简单而不是精心设计)

@Override
public void start(Stage primaryStage) throws Exception {
    double w = 600;
    double h = 600;

    Rotate rotation = new Rotate(0, 0, 0);
    Line ship = new Line(0, 0, 20, 0);
    ship.getTransforms().add(rotation);

    ship.setLayoutX(w / 2);
    ship.setLayoutY(h / 2);

    Pane root = new Pane(ship);
    root.setPrefSize(w, h);

    class Animator extends AnimationTimer {
        // the current speed
        double vx;
        double vy;

        // the direction the ship is facing
        double directionX = 1;
        double directionY = 0;

        // the current acceleration magnitude
        double acceleration = 0;

        @Override
        public void handle(long now) {
            if (acceleration > 0) {
                // speed up in the direction the ship is currently facing
                vx += directionX * acceleration * 0.001;
                vy += directionY * acceleration * 0.001;

                acceleration -= 0.1;
            } else if (vx != 0 || vy != 0) {
                // decelerate
                double speed = Math.hypot(vx, vy);

                // constant deceleration opposite to velocity
                double correctionFactor = Math.max((speed - 0.01) / speed, 0);
                vx *= correctionFactor;
                vy *= correctionFactor;
            }

            // update position
            ship.setLayoutX(ship.getLayoutX() + vx);
            ship.setLayoutY(ship.getLayoutY() + vy);
        }

    }

    Animator animator = new Animator();
    animator.start();

    Scene scene = new Scene(root);

    // make sure the ship always faces the mouse
    root.setOnMouseMoved(evt -> {
        double dx = evt.getX() - ship.getLayoutX();
        double dy = evt.getY() - ship.getLayoutY();

        if (dx == 0 && dy == 0) {
            // handle special case of mouse being in the same position as the ship
            dx = 1;
        }

        // assign normalized direction
        double magnitude = Math.hypot(dx, dy);
        animator.directionX = dx / magnitude;
        animator.directionY = dy / magnitude;

        // update ship rotation
        rotation.setAngle(Math.toDegrees(Math.atan2(dy, dx)));
    });

    root.setOnMouseClicked(evt -> {
        // accelerate
        animator.acceleration = 17;
    });
    primaryStage.setScene(scene);
    primaryStage.show();
}