我的形状动了,但会暂停一会儿

时间:2015-11-24 08:11:02

标签: java animation javafx

我使用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);
    }
}

2 个答案:

答案 0 :(得分:1)

它与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
    }
}

答案 1 :(得分:1)

除了@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