为什么我的函数没有做它应该做的,在javafx中改变球的速度方向?

f45qwnt8  于 2021-04-02  发布在  Java
关注(0)|答案(1)|浏览(304)

所以我做了一个小程序,在那里我有一个球,应该是慢慢加速时下降,慢慢减速时再次跳起来。同时它应该向左和向右移动,基本上是从一边到另一边反弹。
我现在遇到的问题是,当球碰到画布底部时,使球在y轴上改变速度的方法,在第一次成功跳跃/反弹并且球在底部出现故障之后,停止改变代数符号。
我试过打印一些东西,如果它进入函数movebubbleup(),当它在屏幕底部出现故障时打印出来,应该会再次向上移动,那么为什么代数符号不会改变呢?当打印速度时,它变得越来越大,即使movebubbleup()中有bubblevelocity-=5。
因此该方法被调用,通过在输入时打印一个随机字符串来证明,但它没有做任何我希望它做的事情,同时也做了它的对应的movebubbledown()应该做的事情。当故障发生时不会调用它,因为我也尝试过在那里打印一些东西。
以下是改变速度的方法:

void moveBubbleDown() {
    bubbleSpeedY += 5;
    bubbleVelocityY = bubbleSpeedY;
}

void moveBubbleUp() {
    bubbleSpeedY -= 5;
    bubbleVelocityY = -bubbleSpeedY;
}

下面是一些方法,它们调用函数,然后根据它们更改y-pos:

//calculates YPos of bubble

    //changes which method should be called, if the ball has left the border 
    //and sets him on the edge of it
        if (bubble.getTranslateY()>=heightPane-radiusBubble) {
            bubble.setTranslateY(heightPane-radiusBubble);
            moveDown=false;
        } else if (bubble.getTranslateY() <= maxHeight) {
            bubble.setTranslateY(maxHeight);
            moveDown=true;
        }

        if (moveDown) {
            moveBubbleDown();
        } else {
            moveBubbleUp();
        }
        final double deltaYBubble = elapsedSeconds * bubbleVelocityY;
        bubble.setTranslateY(bubble.getTranslateY() + deltaYBubble);

为了不遗漏任何内容,我将发布其余代码,以便您也可以自己尝试:

import javafx.animation.AnimationTimer;
   import javafx.application.Application;
   import javafx.scene.Parent;
   import javafx.scene.Scene;
   import javafx.scene.layout.Pane;
   import javafx.scene.paint.Color;
   import javafx.scene.shape.Circle;
   import javafx.stage.Stage;

   public class Main extends Application {

       //Global Variables
       private static final int widthPane = 1000;
       private static final int heightPane = 650;
       long lastUpdateTime = 0;

       //canvas
       private Pane root = new Pane();

       //Enemy
       int bubbleSpeedY = 30;
       int bubbleVelocityY = bubbleSpeedY;
       final int bubbleSpeedX = 200;
       int bubbleVelocityX = 0;
       int radiusBubble = 25;
       boolean moveDown=true;
       boolean moveRight=true;
       int maxHeight = 50;
       private Circle bubble = new Circle(radiusBubble, Color.CADETBLUE);

       private Parent createContent() {
           root.setPrefSize(widthPane, heightPane);

           root.getChildren().addAll(bubble);

           return root;
       }

       @Override
       public void start(Stage stage) throws Exception{

           bubble.setTranslateY(maxHeight);
           bubble.setTranslateX((int)(Math.random()*widthPane));

           Scene scene = new Scene(createContent());

           final AnimationTimer gameAnimation = new AnimationTimer() {
               @Override
               public void handle(long timestamp) {
                   update(timestamp);
               }
           };
           gameAnimation.start();

           stage.setScene(scene);
           stage.show();
       }

       /**
        * changes velocity so that the bubble goes to the right
        */
       void moveBubbleRight() {
           bubbleVelocityX = bubbleSpeedX;
       }

       /**
        * changes velocity so that the bubble goes to the left
        */
       void moveBubbleLeft() {
           bubbleVelocityX =-bubbleSpeedX;
       }

       void moveBubbleDown() {
           bubbleSpeedY += 5;
           bubbleVelocityY = bubbleSpeedY;
       }

       void moveBubbleUp() {
           bubbleSpeedY -= 5;
           bubbleVelocityY = -bubbleSpeedY;
       }

       /**
        * updates the pos of the bubble depending on the velocity,
        * looks if it's about to leave the border,
        * and sets it on the edge if it is
        *
        * @param timestamp helps calculate the time that has passed since the last update / frame
        */
       private void update(long timestamp) {
           if (lastUpdateTime > 0) {

               final double elapsedSeconds = (timestamp - lastUpdateTime) / 1_000_000_000.0 ;

               //bubble
               //calculates YPos of bubble

               //changes which method should be called, if the ball has left the border 
               //and sets him on the edge of it
               if (bubble.getTranslateY()>=heightPane-radiusBubble) {
                   bubble.setTranslateY(heightPane-radiusBubble);
                   moveDown=false;
               } else if (bubble.getTranslateY() <= maxHeight) {
                   bubble.setTranslateY(maxHeight);
                   moveDown=true;
               }

               if (moveDown) {
                   moveBubbleDown();
               } else {
                   moveBubbleUp();
               }
               final double deltaYBubble = elapsedSeconds * bubbleVelocityY;
               bubble.setTranslateY(bubble.getTranslateY() + deltaYBubble);

               //calculates XPos of Bubble
               if (bubble.getTranslateX() >= widthPane - radiusBubble) {
                   bubble.setTranslateX(widthPane - radiusBubble);
                   moveRight=false;
               } else if (bubble.getTranslateX() - radiusBubble <= 0) {
                   moveRight=true;
               }

               if (moveRight) {
                   moveBubbleRight();
               } else {
                   moveBubbleLeft();
               }

               final double deltaXBubble = elapsedSeconds * bubbleVelocityX;

               bubble.setTranslateX(bubble.getTranslateX() + deltaXBubble);

           }
           lastUpdateTime=timestamp;
       }

       public static void main(String[] args) {
           launch(args);
       }
   }

谢谢大家的帮助,因为我还不太熟悉代码,我认为这个问题远远超出了我的代码知识。好吧,也许这是一个愚蠢的小错误,我忽略了这是破坏一切。

agxfikkp

agxfikkp1#

它与你撞到地板时的速度有关。简单的时间改变可以让它不发生。我认为,速度是这样的,气泡没有适当地离开地面,所以它被卡住,触发了撞击地面的条件。我在moveup/down调用之后添加了一个垂直气泡速度的打印,然后它就不再卡住了!
我对你的代码做了一个小改动,以简化垂直移动,情况似乎更好:

package stackoverflow.answers.demo;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Main extends Application {

    //Global Variables
    private static final int widthPane = 1000;
    private static final int heightPane = 650;
    long lastUpdateTime = 0;

    //canvas
    private Pane root = new Pane();

    //Enemy
    double bubbleAccelerationY = 300;
    double bubbleSpeedY = 30;
    double bubbleVelocityY = bubbleSpeedY;
    final int bubbleSpeedX = 200;
    int bubbleVelocityX = 0;
    int radiusBubble = 25;
    boolean moveDown = true;
    boolean moveRight = true;
    int maxHeight = 50;
    private Circle bubble = new Circle(radiusBubble, Color.CADETBLUE);

    private Parent createContent() {
        root.setPrefSize(widthPane, heightPane);
        root.getChildren().addAll(bubble);
        return root;
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {

        bubble.setTranslateY(maxHeight);
        bubble.setTranslateX((int) (Math.random() * widthPane));

        Scene scene = new Scene(createContent());

        final AnimationTimer gameAnimation = new AnimationTimer() {
            @Override
            public void handle(long timestamp) {
                update(timestamp);
            }
        };
        gameAnimation.start();

        stage.setScene(scene);
        stage.show();
    }

    /**
     * changes velocity so that the bubble goes to the right
     */
    void moveBubbleRight() {
        bubbleVelocityX = bubbleSpeedX;
    }

    /**
     * changes velocity so that the bubble goes to the left
     */
    void moveBubbleLeft() {
        bubbleVelocityX = -bubbleSpeedX;
    }

    void accelerateBubble(double secs) {
        bubbleVelocityY += (secs * bubbleAccelerationY);
    }

    void bounceBubble() {
        bubbleVelocityY = -bubbleVelocityY;
    }

    /**
     * updates the pos of the bubble depending on the velocity, looks if it's about to leave the border, and sets it on
     * the edge if it is
     *
     * @param timestamp helps calculate the time that has passed since the last update / frame
     */
    private void update(long timestamp) {
        if (lastUpdateTime > 0) {

            final double elapsedSeconds = (timestamp - lastUpdateTime) / 1_000_000_000.0;

            //bubble
            //calculates YPos of bubble
            //changes which method should be called, if the ball has left the border
            //and sets him on the edge of it
            if (bubble.getTranslateY() >= heightPane - radiusBubble) {
                bubble.setTranslateY(heightPane - radiusBubble);
                bounceBubble();
            } else if (bubble.getTranslateY() <= maxHeight) {
                bubble.setTranslateY(maxHeight);
            }

            accelerateBubble(elapsedSeconds);

            final double deltaYBubble = elapsedSeconds * bubbleVelocityY;
            bubble.setTranslateY(bubble.getTranslateY() + deltaYBubble);

            //calculates XPos of Bubble
            if (bubble.getTranslateX() >= widthPane - radiusBubble) {
                bubble.setTranslateX(widthPane - radiusBubble);
                moveRight = false;
            } else if (bubble.getTranslateX() - radiusBubble <= 0) {
                moveRight = true;
            }

            if (moveRight) {
                moveBubbleRight();
            } else {
                moveBubbleLeft();
            }

            final double deltaXBubble = elapsedSeconds * bubbleVelocityX;

            bubble.setTranslateX(bubble.getTranslateX() + deltaXBubble);

        }
        lastUpdateTime = timestamp;
    }
}

相关问题