我的形状移动了,但会暂停一段时间



我用JavaFX编程了一个简单的"游戏"。它基本上是一个左右移动的矩形。问题是,当按下某个键时,矩形会移动(很好),但在持续移动之前会暂停一段时间。有什么解决方案吗?

p.S我是这个网站的新手>_<

package sample;
import javafx.application.Application;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Main extends Application
{
    protected static SimpleIntegerProperty sint_speed = new SimpleIntegerProperty(1);
    protected static double dbl_playerW = 140,dbl_playerH = 20;
    protected static SimpleDoubleProperty sdbl_playerX = new  SimpleDoubleProperty(130),sdbl_playerY = new SimpleDoubleProperty(360);
    @Override
    public void start(Stage stg_main)
    {
        Group grp_main = new Group();
        Label lbl_spd = new Label();
        lbl_spd.textProperty().bind(sint_speed.asString());
        Button btn_increaseSpd = new Button(">");
        btn_increaseSpd.setOnAction(e->
        {
            sint_speed.set(sint_speed.intValue() + 1);
        });
        Button btn_decreaseSpd = new Button("<");
        btn_decreaseSpd.setOnAction(e->
        {
            if(sint_speed.intValue() > 0)
            {
                sint_speed.set(sint_speed.intValue() - 1);
            }
        });
        HBox h1 = new HBox(10);
        h1.setAlignment(Pos.CENTER);
        h1.getChildren().addAll(btn_decreaseSpd,lbl_spd,btn_increaseSpd);
        grp_main.getChildren().add(h1);
        subRoute_Player(grp_main);
        Scene scn_main = new Scene(grp_main,400,400);
        scn_main.setOnKeyPressed(e->
        {
            if(e.getCode() == KeyCode.LEFT)
            {
                sdbl_playerX.set(sdbl_playerX.doubleValue() - sint_speed.intValue());
            }
            else if(e.getCode() == KeyCode.RIGHT)
            {
                sdbl_playerX.set(sdbl_playerX.doubleValue() + sint_speed.intValue());
            }
        });
        stg_main.setScene(scn_main);
        stg_main.setResizable(false);
        stg_main.show();
    }
    protected static void subRoute_Player(Group grp_rcvd)
    {
        Rectangle rct_player = new Rectangle();
        rct_player.setFill(Color.BLACK);
        rct_player.setWidth(dbl_playerW);
        rct_player.setHeight(dbl_playerH);
        rct_player.translateXProperty().bind(sdbl_playerX);
        rct_player.translateYProperty().bind(sdbl_playerY);
        grp_rcvd.getChildren().add(rct_player);
    }
    public static void main(String[] args)
    {
        launch(args);
    }
}

除了@McKevin发布的内容外,您还可以使用TranslateTransition进行实际移动。只需在onKeyPressed()处理程序中启动转换,然后在onKeyReleased()处理程序中停止转换。以下代码片段展示了如何在一个方向上做到这一点(当你的玩家达到某个极限时,你仍然需要添加左右之间的区别,并添加对角落情况的处理):

...
private Rectangle rct_player;
private TranslateTransition transTransition;
private boolean isMoving = false;
...
    // Create the translate transition for the rectangle
    transTransition = new TranslateTransition(new Duration(75000), rct_player);
    transTransition.setToY(0);
    transTransition.setToX(1500);
    transTransition.setInterpolator(Interpolator.LINEAR);
    transTransition.setCycleCount(Timeline.INDEFINITE);
    scn_main.setOnKeyPressed(e-> {
        if (!isMoving) {
            transTransition.play();
            isMoving = true;
        }
    });
    scn_main.setOnKeyReleased(e -> {
        transTransition.stop(); 
        isMoving = false;
    });
...

另请参阅https://docs.oracle.com/javase/8/javafx/api/javafx/animation/TranslateTransition.html

这与如何触发OnKeyPressed事件有关。为了可视化这一点,你可以按住键盘上的任何键,你会注意到第一个字符是如何出现的,并在流的其余部分出现时停顿很长时间。

要解决此问题,请使用布尔标志:

isMovingLeft = false;
isMovingRight = false;
if(e.getCode() == KeyCode.LEFT){
     //instead of doing this:
     //sdbl_playerX.set(sdbl_playerX.doubleValue() - sint_speed.intValue());
     isMovingLeft = true;
}
OnKeyPressed(){
   if left is pressed:
       set isMovingLeft to true;
   if right is pressed:
       set isMovingRight to true;
}
onKeyReleased(){
   if left is released:
       set isMovingLeft to false;
   if right is pressed:
       set isMovingRight to false; 
}
//maingameloop i.e: handle method in JavaFX
handle(){
    if(isMovingLeft){
        //apply move left logic
    }
    if(isMovingRight){
        //apply move right logic
    }
}

最新更新