圈不动问题

发布于 2025-01-31 12:13:23 字数 5876 浏览 4 评论 0原文

因此,基本上,我正在制作一个游戏,其中圆圈将在四个方向上移动。当按下“ S”或“右”键时,圆将移动直至到达窗格的最大值。当我按“一个”键或“左”时,圆将移动直至到达窗格的Minx。 “ UP”或“ W”和“ DOWN”或“ Z”键也遵循类似的逻辑。如果它到达窗格的Maxy,它将停止,直到按下另一键,反之亦然。

这是控制器类的代码

    @FXML
    private Pane board;

    private BooleanProperty wPressed = new SimpleBooleanProperty();
    private BooleanProperty aPressed = new SimpleBooleanProperty();
    private BooleanProperty zPressed = new SimpleBooleanProperty();
    private BooleanProperty sPressed = new SimpleBooleanProperty();

    private BooleanBinding keyPressed = wPressed.or(aPressed).or(zPressed).or(sPressed);

    


    private Circle circle = new Circle(20,40,20);




    private Rectangle[][] grid;
    private int size = 960;
    private int spots = 16;
    private int squareSize = size / spots;


    @FXML
    void handleB(ActionEvent event) {

    }

    AnimationTimer timer = new AnimationTimer() {

        double deltaX = 2;
        double deltaY = 2;
        
        @Override
        public void handle(long timestamp) {
            double rectX = circle.getLayoutX();
            Bounds bounds = board.getBoundsInLocal();


           

            double maxX = bounds.getMaxX();
            double maxY = bounds.getMaxY();
            double minX = bounds.getMinX();
            double minY = bounds.getMinY();

           

            if (circle.getLayoutX() >= ( maxX- circle.getRadius())) {
                deltaX = 0;
                //System.out.println(rect.getLayoutX());
            }
            if (circle.getLayoutY() >= (maxY - circle.getRadius())) {
                deltaY = 0;
            }


            if (circle.getLayoutX() <= ( minX + circle.getRadius())) {
                deltaX = 0;
                //System.out.println(rect.getLayoutX());
            }
            if (circle.getLayoutY() <= ( minY + circle.getRadius())) {
                deltaY = 0;
            }

            if(wPressed.get()) {
                circle.setLayoutY(circle.getLayoutY() - deltaY);
            }

            if(zPressed.get()){
                circle.setLayoutY(circle.getLayoutY() + deltaY);
            }

            if(aPressed.get()){
                circle.setLayoutX(circle.getLayoutX() - deltaX);
            }

            if(sPressed.get()){
                circle.setLayoutX(circle.getLayoutX() + deltaX);
            }



        }
    };


    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

        
        grid = new Rectangle[spots][spots];
        for (int i = 0; i < size; i += squareSize) {
            for (int j = 0; j < size; j += squareSize) {
                Rectangle r = new Rectangle(i, j, squareSize, squareSize);
                grid[i / squareSize][j / squareSize] = r;
                // Filling each grid with the cell image
                r.setFill(Color.GRAY);
                r.setStroke(Color.BLACK);
                board.getChildren().add(r);
            }
        }

        board.getChildren().addAll(circle);


        movementSetup();

        keyPressed.addListener(((observableValue, aBoolean, t1) -> {
            if(!aBoolean){
                timer.start();
            } else {
                timer.stop();
            }
        }));




    }




    private void movementSetup() {
        board.setOnKeyPressed(e -> {
            if(e.getCode() == KeyCode.UP || e.getCode() == KeyCode.W ) {
                zPressed.set(false);
                sPressed.set(false);
                aPressed.set(false);
                wPressed.set(true);

            }

            if(e.getCode() == KeyCode.A || e.getCode() == KeyCode.LEFT) {
                zPressed.set(false);
                sPressed.set(false);
                wPressed.set(false);
                aPressed.set(true);
            }

            if(e.getCode() == KeyCode.Z || e.getCode() == KeyCode.DOWN) {
                wPressed.set(false);
                aPressed.set(false);
                sPressed.set(false);
                zPressed.set(true);
            }

            if(e.getCode() == KeyCode.S || e.getCode() == KeyCode.RIGHT) {
                wPressed.set(false);
                aPressed.set(false);
                zPressed.set(false);
                sPressed.set(true);
            }
        });


    }


}

**,我在场景构造器中进行了窗格,我还将其插入anchorpane ** **

文件下面是(ui.fxml)(ui.fxml


<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>

<AnchorPane maxHeight="1000.0" maxWidth="1200.0" minHeight="0.0" minWidth="0.0" prefHeight="1000.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx.game.Controller">
   <children>
      <Pane fx:id="board" maxHeight="960.0" maxWidth="960.0" minHeight="0.0" minWidth="0.0" prefHeight="960.0" prefWidth="960.0">
         <children>
            <Button layoutX="367.0" layoutY="934.0" mnemonicParsing="false" onAction="#handleB" text="Button" />
         </children>
      </Pane>
   </children>
</AnchorPane>


package fx.game;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("ui.fxml"));
        stage.setTitle("Hello World");
        stage.setScene(new Scene(root));
        stage.show();
    }

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

fxml 我可能做错了 任何能给我更好的解决方案的人都将不胜感激

So basically i am making a game in which the circle will move in the four directions. When the "S" or "RIGHT" key is pressed once, the circle will move till it reaches the maxX of the pane. And when i press the "A" key or "LEFT", the circle will move till it reaches minX of pane. The "UP" or "W" and "DOWN" or "Z" keys also follow similar logic. If it get to maxY of pane it stops till another key is pressed and vice versa.

Here is the code for the controller class

    @FXML
    private Pane board;

    private BooleanProperty wPressed = new SimpleBooleanProperty();
    private BooleanProperty aPressed = new SimpleBooleanProperty();
    private BooleanProperty zPressed = new SimpleBooleanProperty();
    private BooleanProperty sPressed = new SimpleBooleanProperty();

    private BooleanBinding keyPressed = wPressed.or(aPressed).or(zPressed).or(sPressed);

    


    private Circle circle = new Circle(20,40,20);




    private Rectangle[][] grid;
    private int size = 960;
    private int spots = 16;
    private int squareSize = size / spots;


    @FXML
    void handleB(ActionEvent event) {

    }

    AnimationTimer timer = new AnimationTimer() {

        double deltaX = 2;
        double deltaY = 2;
        
        @Override
        public void handle(long timestamp) {
            double rectX = circle.getLayoutX();
            Bounds bounds = board.getBoundsInLocal();


           

            double maxX = bounds.getMaxX();
            double maxY = bounds.getMaxY();
            double minX = bounds.getMinX();
            double minY = bounds.getMinY();

           

            if (circle.getLayoutX() >= ( maxX- circle.getRadius())) {
                deltaX = 0;
                //System.out.println(rect.getLayoutX());
            }
            if (circle.getLayoutY() >= (maxY - circle.getRadius())) {
                deltaY = 0;
            }


            if (circle.getLayoutX() <= ( minX + circle.getRadius())) {
                deltaX = 0;
                //System.out.println(rect.getLayoutX());
            }
            if (circle.getLayoutY() <= ( minY + circle.getRadius())) {
                deltaY = 0;
            }

            if(wPressed.get()) {
                circle.setLayoutY(circle.getLayoutY() - deltaY);
            }

            if(zPressed.get()){
                circle.setLayoutY(circle.getLayoutY() + deltaY);
            }

            if(aPressed.get()){
                circle.setLayoutX(circle.getLayoutX() - deltaX);
            }

            if(sPressed.get()){
                circle.setLayoutX(circle.getLayoutX() + deltaX);
            }



        }
    };


    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

        
        grid = new Rectangle[spots][spots];
        for (int i = 0; i < size; i += squareSize) {
            for (int j = 0; j < size; j += squareSize) {
                Rectangle r = new Rectangle(i, j, squareSize, squareSize);
                grid[i / squareSize][j / squareSize] = r;
                // Filling each grid with the cell image
                r.setFill(Color.GRAY);
                r.setStroke(Color.BLACK);
                board.getChildren().add(r);
            }
        }

        board.getChildren().addAll(circle);


        movementSetup();

        keyPressed.addListener(((observableValue, aBoolean, t1) -> {
            if(!aBoolean){
                timer.start();
            } else {
                timer.stop();
            }
        }));




    }




    private void movementSetup() {
        board.setOnKeyPressed(e -> {
            if(e.getCode() == KeyCode.UP || e.getCode() == KeyCode.W ) {
                zPressed.set(false);
                sPressed.set(false);
                aPressed.set(false);
                wPressed.set(true);

            }

            if(e.getCode() == KeyCode.A || e.getCode() == KeyCode.LEFT) {
                zPressed.set(false);
                sPressed.set(false);
                wPressed.set(false);
                aPressed.set(true);
            }

            if(e.getCode() == KeyCode.Z || e.getCode() == KeyCode.DOWN) {
                wPressed.set(false);
                aPressed.set(false);
                sPressed.set(false);
                zPressed.set(true);
            }

            if(e.getCode() == KeyCode.S || e.getCode() == KeyCode.RIGHT) {
                wPressed.set(false);
                aPressed.set(false);
                zPressed.set(false);
                sPressed.set(true);
            }
        });


    }


}

** I did the pane in scenebuilder which i inserted it into an anchorpane as well**

The fxml file is below (ui.fxml)


<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>

<AnchorPane maxHeight="1000.0" maxWidth="1200.0" minHeight="0.0" minWidth="0.0" prefHeight="1000.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx.game.Controller">
   <children>
      <Pane fx:id="board" maxHeight="960.0" maxWidth="960.0" minHeight="0.0" minWidth="0.0" prefHeight="960.0" prefWidth="960.0">
         <children>
            <Button layoutX="367.0" layoutY="934.0" mnemonicParsing="false" onAction="#handleB" text="Button" />
         </children>
      </Pane>
   </children>
</AnchorPane>

Lastly the main class


package fx.game;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("ui.fxml"));
        stage.setTitle("Hello World");
        stage.setScene(new Scene(root));
        stage.show();
    }

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

Am really bad at game development
I might be doing it completely wrong
Anyone who can give me a better solution will be appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鱼窥荷 2025-02-07 12:13:23

从我有限的理解和测试中,board.setonkeypressed没有响应关键事件,我改用scene。您还应该考虑OnkeyRealed

我不知道为什么您要启动并停止计时器,只需启动它,并且在每个方面,评估状态并进行所需的更改。

您的动作逻辑似乎也已经消失了。获取当前位置,根据需要应用任何动作,然后确定新位置是​​否在可接受的界限之外,根据需要调整位置,然后更新圆形位置。

我还发现bunds board将根据孩子的位置进行更新,这使得很难进行范围检查,而是我计算了预期的基于预期的大小。 spots 的数量

...

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class App extends Application {

    private BooleanProperty wPressed = new SimpleBooleanProperty();
    private BooleanProperty aPressed = new SimpleBooleanProperty();
    private BooleanProperty zPressed = new SimpleBooleanProperty();
    private BooleanProperty sPressed = new SimpleBooleanProperty();

    private BooleanBinding keyPressed = wPressed.or(aPressed).or(zPressed).or(sPressed);

    private Circle circle = new Circle(20, 20, 20);

    private Rectangle[][] grid;
    private int size = 960;
    private int spots = 16;
    private int squareSize = size / spots;
    AnimationTimer timer = new AnimationTimer() {

        double deltaX = 2;
        double deltaY = 2;

        @Override
        public void handle(long timestamp) {
            double rectX = circle.getLayoutX();
            Bounds bounds = board.getBoundsInLocal();

            double width = squareSize * spots;
            double height = squareSize * spots;

            double diameter = circle.getRadius() * 2;

            double x = circle.getLayoutX();
            double y = circle.getLayoutY();

            if (wPressed.get()) {
                y -= deltaY;
            }

            if (zPressed.get()) {
                y += deltaY;
            }

            if (aPressed.get()) {
                x -= deltaX;
            }

            if (sPressed.get()) {
                x += deltaX;
            }

            if (x >= (width - diameter)) {
                x = width - diameter;
            }
            if (x < 0) {
                x = 0;
            }

            if (y > (height - diameter)) {
                y = height - diameter;
            }
            if (y < 0) {
                y = 0;
            }

            circle.setLayoutX(x);
            circle.setLayoutY(y);

        }
    };

    private Pane board = new AnchorPane();

    @Override
    public void start(Stage stage) {
        stage.setTitle("Dice Game");

        setup();

        Scene scene = new Scene(board);
        movementSetup(scene);
        stage.setScene(scene);
        stage.sizeToScene();
        stage.show();
    }

    private void movementSetup(Scene scene) {

        scene.setOnKeyPressed(e -> {
            zPressed.set(false);
            sPressed.set(false);
            aPressed.set(false);
            wPressed.set(false);
            if (e.getCode() == KeyCode.UP || e.getCode() == KeyCode.W) {
                wPressed.set(true);
            } else if (e.getCode() == KeyCode.A || e.getCode() == KeyCode.LEFT) {
                aPressed.set(true);
            }else if (e.getCode() == KeyCode.Z || e.getCode() == KeyCode.DOWN) {
                zPressed.set(true);
            }else if (e.getCode() == KeyCode.S || e.getCode() == KeyCode.RIGHT) {
                sPressed.set(true);
            }
        });

    }

    protected void setup() {
        grid = new Rectangle[spots][spots];
        for (int i = 0; i < size; i += squareSize) {
            for (int j = 0; j < size; j += squareSize) {
                Rectangle r = new Rectangle(i, j, squareSize, squareSize);
                grid[i / squareSize][j / squareSize] = r;
                // Filling each grid with the cell image
                r.setFill(Color.GRAY);
                r.setStroke(Color.BLACK);
                board.getChildren().add(r);
            }
        }

        board.getChildren().addAll(circle);

        timer.start();
    }

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

}

SquareSize也许可以看一下游戏开发的Javafx (或其他“ Javafx游戏开发博客”可能会提供更好的想法

From my limited understanding and testing, board.setOnKeyPressed isn't responding to key events, I used the Scene instead. You should also be taking into account onKeyReleased.

I don't know why you're starting and stoping the timer, just start it and on each, evaluate the state and make the changes that are required.

Your movement logic seems to be off as well. Get the circles current location, apply any movement to it as required, then determine if the new position is outside the acceptable bounds, adjust the position as needed and then update the circles position.

I also found that the Bounds the board would update based on the position of it's children, which made it hard to do bounds checking on, instead, I calculate the expected size based on the squareSize and the number of spots

For example...

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class App extends Application {

    private BooleanProperty wPressed = new SimpleBooleanProperty();
    private BooleanProperty aPressed = new SimpleBooleanProperty();
    private BooleanProperty zPressed = new SimpleBooleanProperty();
    private BooleanProperty sPressed = new SimpleBooleanProperty();

    private BooleanBinding keyPressed = wPressed.or(aPressed).or(zPressed).or(sPressed);

    private Circle circle = new Circle(20, 20, 20);

    private Rectangle[][] grid;
    private int size = 960;
    private int spots = 16;
    private int squareSize = size / spots;
    AnimationTimer timer = new AnimationTimer() {

        double deltaX = 2;
        double deltaY = 2;

        @Override
        public void handle(long timestamp) {
            double rectX = circle.getLayoutX();
            Bounds bounds = board.getBoundsInLocal();

            double width = squareSize * spots;
            double height = squareSize * spots;

            double diameter = circle.getRadius() * 2;

            double x = circle.getLayoutX();
            double y = circle.getLayoutY();

            if (wPressed.get()) {
                y -= deltaY;
            }

            if (zPressed.get()) {
                y += deltaY;
            }

            if (aPressed.get()) {
                x -= deltaX;
            }

            if (sPressed.get()) {
                x += deltaX;
            }

            if (x >= (width - diameter)) {
                x = width - diameter;
            }
            if (x < 0) {
                x = 0;
            }

            if (y > (height - diameter)) {
                y = height - diameter;
            }
            if (y < 0) {
                y = 0;
            }

            circle.setLayoutX(x);
            circle.setLayoutY(y);

        }
    };

    private Pane board = new AnchorPane();

    @Override
    public void start(Stage stage) {
        stage.setTitle("Dice Game");

        setup();

        Scene scene = new Scene(board);
        movementSetup(scene);
        stage.setScene(scene);
        stage.sizeToScene();
        stage.show();
    }

    private void movementSetup(Scene scene) {

        scene.setOnKeyPressed(e -> {
            zPressed.set(false);
            sPressed.set(false);
            aPressed.set(false);
            wPressed.set(false);
            if (e.getCode() == KeyCode.UP || e.getCode() == KeyCode.W) {
                wPressed.set(true);
            } else if (e.getCode() == KeyCode.A || e.getCode() == KeyCode.LEFT) {
                aPressed.set(true);
            }else if (e.getCode() == KeyCode.Z || e.getCode() == KeyCode.DOWN) {
                zPressed.set(true);
            }else if (e.getCode() == KeyCode.S || e.getCode() == KeyCode.RIGHT) {
                sPressed.set(true);
            }
        });

    }

    protected void setup() {
        grid = new Rectangle[spots][spots];
        for (int i = 0; i < size; i += squareSize) {
            for (int j = 0; j < size; j += squareSize) {
                Rectangle r = new Rectangle(i, j, squareSize, squareSize);
                grid[i / squareSize][j / squareSize] = r;
                // Filling each grid with the cell image
                r.setFill(Color.GRAY);
                r.setStroke(Color.BLACK);
                board.getChildren().add(r);
            }
        }

        board.getChildren().addAll(circle);

        timer.start();
    }

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

}

nb: I'm a complete JavaFX noob, so there's probably better ways to approach this issue and maybe having a look at things like Introduction to JavaFX for Game Development (or other "javafx game development blogs" might provide better ideas

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文