矩形碰撞时的圆周运动 [英] Circle movement upon rectangle Collision

查看:151
本文介绍了矩形碰撞时的圆周运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力了解碰撞检测和移动,我遇到了正确降低移动的问题。我的目标是允许玩家在矩形周围移动而不是通过它们移动。我的问题是,一旦玩家到达矩形的边界,他们就无法备份。任何帮助将不胜感激。

I'm working on understanding collision detection and movement and I am having issues getting the movement down correctly. my goal is to allow a player to move around rectangles but not through them. my problem is that once the player reaches the bounds of the rectangle they are unable to backup. any help would be greatly appreciated.

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import static javafx.scene.input.KeyCode.DOWN;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;

public class CircleMovement extends Application {

    //create the panes to handle the game
    BorderPane mainPane = new BorderPane();
    GridPane infoPane = new GridPane();
    Pane gameField = new Pane();
    Scene scene;
    //create circle/movement properties
    double increment = 5.0;
    double radius = 10;
    double x = radius, y = radius;
    //create Rectangle properties
    double Rwidth = 80;
    double Rheight = 20;
    //create player and objects
    Circle player = new Circle(x, y, radius);
    Rectangle r1 = new Rectangle(0, 100, Rwidth, Rheight);//Rectangle(int x, int y, int width, int height)

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

    @Override
    public void start(Stage stage) throws Exception {
        setPanes();
        gameField.getChildren().addAll(r1, player);
        moveCircleOnKeyPress(scene, player);//pass to player movement method

        //set the stage
        stage.setScene(scene);
        stage.show();
    }

    public void moveCircleOnKeyPress(Scene scene, Circle player) {//player movement
        scene.setOnKeyPressed((KeyEvent event) -> {
            switch (event.getCode()) {
                case UP:
                    player.setCenterY(player.getCenterY() - increment);//move player
                    if (player.getBoundsInLocal().intersects(r1.getBoundsInLocal())) {
                        player.centerYProperty().setValue(r1.getY());
                    }
                    break;
                case RIGHT:
                    player.setCenterX(player.getCenterX() + increment);
                    if (player.getBoundsInLocal().intersects(r1.getBoundsInLocal())) {
                        player.centerYProperty().setValue(r1.getY());
                    }
                    break;
                case DOWN:
                    player.setCenterY(player.getCenterY() + increment);
                    if (player.getBoundsInLocal().intersects(r1.getBoundsInLocal())) {
                        player.centerYProperty().setValue(r1.getY());
                    }
                    break;
                case LEFT:
                    player.setCenterX(player.getCenterX() - increment);
                    if (player.getBoundsInLocal().intersects(r1.getBoundsInLocal())) {
                        player.centerYProperty().setValue(r1.getY());
                    }
                    break;
            }
        });
    }

    public void setPanes() {
        infoPane.setMaxSize(200, 200);
        mainPane.setMaxSize(800, 800);
        mainPane.setCenter(gameField);//place the main game inside the center
        mainPane.setRight(infoPane);
        mainPane.setPadding(new Insets(10, 10, 10, 10));
        mainPane.setStyle("-fx-border-color: red");
        gameField.setStyle("-fx-background-color: white");
        gameField.setStyle("-fx-border-color: black");
        gameField.setMaxSize(600, 600);
        scene = new Scene(mainPane, 800, 800);
        player.setFill(Color.RED);

    }
}


推荐答案

由于您使用的是 Shape ,因此最好使用 Shape.intersect(player,r1).getBoundsInLocal()。getWidth() != -1 检测交叉点。此外,不要使用 player.centerYProperty()。setValue(...); ,只需使用 player.setCenterY(...)。你还有几个问题,但最重要的一个是在检测到交叉点后该做什么的想法。一旦检测到交叉路口,您应该回到检测前的距离(仅当您以足够小的步长移动时)。

Since you are using Shape, it's a good idea to use Shape.intersect(player, r1).getBoundsInLocal().getWidth() != -1 to detect intersection. Also, instead of using player.centerYProperty().setValue(...);, just use player.setCenterY(...). You had a couple more problems, but the most important one is the idea of what to do once an intersection is detected. Once an intersection is detected you should go back to the distance just before the detection(only if you are moving in small enough steps).

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import static javafx.scene.input.KeyCode.DOWN;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class CircleMovement extends Application
{

    //create the panes to handle the game
    BorderPane mainPane = new BorderPane();
    GridPane infoPane = new GridPane();
    Pane gameField = new Pane();
    Scene scene;
    //create circle/movement properties
    double increment = 5.0;
    double radius = 10;
    double x = radius, y = radius;
    //create Rectangle properties
    double Rwidth = 80;
    double Rheight = 20;
    //create player and objects
    Circle player = new Circle(x, y, radius);
    Rectangle r1 = new Rectangle(0, 100, Rwidth, Rheight);//Rectangle(int x, int y, int width, int height)

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

    @Override
    public void start(Stage stage) throws Exception
    {
        setPanes();
        gameField.getChildren().addAll(r1, player);
        moveCircleOnKeyPress(scene, player);//pass to player movement method

        //set the stage
        stage.setScene(scene);
        stage.show();
    }

    public void moveCircleOnKeyPress(Scene scene, Circle player)
    {//player movement
        scene.setOnKeyPressed((KeyEvent event) ->
        {
            switch (event.getCode())
            {
                case UP:
                    player.setCenterY(player.getCenterY() - increment);//move player
                    //if (player.getBoundsInLocal().intersects(r1.getBoundsInLocal()))
                    if (Shape.intersect(player, r1).getBoundsInLocal().getWidth() != -1)
                    {
                        player.setCenterY(player.getCenterY() + increment);
                    }
                    break;
                case RIGHT:
                    player.setCenterX(player.getCenterX() + increment);

                    if (Shape.intersect(player, r1).getBoundsInLocal().getWidth() != -1)
                    {
                        player.setCenterX(player.getCenterX() - increment);
                    }
                    break;
                case DOWN:
                    player.setCenterY(player.getCenterY() + increment);
                    if (Shape.intersect(player, r1).getBoundsInLocal().getWidth() != -1)
                    {
                        player.setCenterY(player.getCenterY() - increment);
                    }
                    break;
                case LEFT:
                    player.setCenterX(player.getCenterX() - increment);
                    if (Shape.intersect(player, r1).getBoundsInLocal().getWidth() != -1)
                    {
                        player.setCenterX(player.getCenterX() + increment);
                    }
                    break;
            }
        });
    }

    public void setPanes()
    {
        infoPane.setMaxSize(200, 200);
        mainPane.setMaxSize(800, 800);
        mainPane.setCenter(gameField);//place the main game inside the center
        mainPane.setRight(infoPane);
        mainPane.setPadding(new Insets(10, 10, 10, 10));
        mainPane.setStyle("-fx-border-color: red");
        gameField.setStyle("-fx-background-color: white");
        gameField.setStyle("-fx-border-color: black");
        gameField.setMaxSize(600, 600);
        scene = new Scene(mainPane, 800, 800);
        player.setFill(Color.RED);

    }
}

这篇关于矩形碰撞时的圆周运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆