当前位置: 首页 > 知识库问答 >
问题:

圆和矩形之间的碰撞在角落中不起作用 ( javafx )

子车安和
2023-03-14

问候SOCommunity,

现在我正在尝试学习形状之间的碰撞检测。检测本身工作良好。但物体的重新定位并不完全有效。

所以每当我的圆碰到矩形的角时,重新定位就不起作用了。

这是我的代码:

public class Collision extends Application {

@Override
public void start(Stage stage) {

    Group root = new Group();
    Scene scene = new Scene(root, 600, 600, Color.CADETBLUE);

// Nodes
    Rectangle bounds = new Rectangle(500,500, Color.TRANSPARENT);
    bounds.setStroke(Color.WHITE);
    bounds.setStrokeWidth(5);
    bounds.setTranslateX(50);
    bounds.setTranslateY(50);

    Circle c1 = new Circle(30, Color.WHITE);
    c1.setTranslateX(300);
    c1.setTranslateY(300);

// Events

    // Collision Detection and c1 movement
    EventHandler<MouseEvent> handle = new EventHandler<MouseEvent>() {      

        double difX;    // Circle to mouse difference
        double difY;

        double reloX;   // Circle touches bounds
        double reloY;

        Bounds nodeBounds = c1.getBoundsInLocal();  // Bound Objects for Node and Rect
        Bounds bound = bounds.getBoundsInLocal();

        public void handle(MouseEvent event) {

            // If Pressed save Coordinates
            if(event.getEventType() == MouseEvent.MOUSE_PRESSED) {

                difX = event.getX();
                difY = event.getY();      

            }
            // If Dragged check Collision and relocate
            else if(event.getEventType() == MouseEvent.MOUSE_DRAGGED) {

                c1.setTranslateX( event.getSceneX() - difX );
                c1.setTranslateY( event.getSceneY() - difY );


                if( c1.localToScene(nodeBounds).getMinX() < bounds.localToScene(bound).getMinX() ) {
                    bounds.setStroke(Color.RED);
                    c1.setTranslateX( bound.getMinX() - nodeBounds.getMinX() + 50 );
                }
                else if( c1.localToScene(nodeBounds).getMinY() < bounds.localToScene(bound).getMinY() ) { 
                    bounds.setStroke(Color.RED);
                    c1.setTranslateY( bound.getMinY() - nodeBounds.getMinY() + 50 );
                }
                else if( c1.localToScene(nodeBounds).getMaxX() > bounds.localToScene(bound).getMaxX() ) { 
                    bounds.setStroke(Color.RED);
                    c1.setTranslateX( bound.getMaxX() - nodeBounds.getMaxX() + 50 );
                }
                else if( c1.localToScene(nodeBounds).getMaxY() > bounds.localToScene(bound).getMaxY() ) { 
                    bounds.setStroke(Color.RED);
                    c1.setTranslateY( bound.getMaxY() - nodeBounds.getMaxY() + 50 );
                }                   
                else {
                    bounds.setStroke(Color.WHITE);
                }

            }       


        }
    };

    c1.addEventHandler(MouseEvent.ANY, handle);

//Stage is setUp
    root.getChildren().addAll(bounds, c1);
    stage.setTitle("omfg, srsly !?");
    stage.setScene(scene);
    stage.show();
}

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

请帮助我找出为什么这不起作用,以及我如何让它起作用。

提前感谢:)

共有1个答案

祝允晨
2023-03-14

这是一个应用程序,你可以玩,找出你做错了什么。

主要:

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

/**
 *
 * @author blj0011
 */
public class CollisionDection extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

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

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

控制器:

import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Point2D;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;

/**
 *
 * @author sedj601
 */
public class FXMLDocumentController implements Initializable {

    @FXML private Label lblMain;
    @FXML private Polygon polyOne, polyTwo;    
    @FXML private Circle circle1;
    @FXML private Rectangle rectangle1;

    final ObjectProperty<Point2D> mousePosition = new SimpleObjectProperty<>();

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        polyOne.setOnMousePressed((MouseEvent event) -> {
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));
        });

        polyOne.setOnMouseDragged((MouseEvent event) -> {
            double deltaX = event.getSceneX() - mousePosition.get().getX();
            double deltaY = event.getSceneY() - mousePosition.get().getY();
            polyOne.setLayoutX(polyOne.getLayoutX()+deltaX);
            polyOne.setLayoutY(polyOne.getLayoutY()+deltaY);
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));

            Shape intersect = Shape.intersect(polyOne, polyTwo);

            if(intersect.getBoundsInLocal().getWidth() != -1)
            {
                System.out.println("This object can overlap other the other object!");
                lblMain.setText("Collision detected!");
            }
            else
            {
                intersect.getBoundsInLocal().getWidth();
                lblMain.setText("Collision not detected!");
            }            
        });

        polyTwo.setOnMousePressed((MouseEvent event) -> {
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));
        });

        polyTwo.setOnMouseDragged((MouseEvent event) -> {
            double deltaX = event.getSceneX() - mousePosition.get().getX();
            double deltaY = event.getSceneY() - mousePosition.get().getY();
            polyTwo.setLayoutX(polyTwo.getLayoutX() + deltaX);
            polyTwo.setLayoutY(polyTwo.getLayoutY() + deltaY);
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));

            Shape intersect = Shape.intersect(polyOne, polyTwo);
            {
                if(intersect.getBoundsInLocal().getWidth() != -1)
                {      
                    System.out.println("This object can not overlap other the other object!");
                    polyTwo.setLayoutX(polyTwo.getLayoutX() - deltaX);
                    polyTwo.setLayoutY(polyTwo.getLayoutY() - deltaY);
                    lblMain.setText("Collision detected!");
                }
                else
                {
                    lblMain.setText("Collision not detected!");
                }
            }
        });   

        circle1.setOnMousePressed((MouseEvent event) -> {
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));
        });

        circle1.setOnMouseDragged((MouseEvent event) -> {
            double deltaX = event.getSceneX() - mousePosition.get().getX();
            double deltaY = event.getSceneY() - mousePosition.get().getY();
            circle1.setLayoutX(circle1.getLayoutX() + deltaX);
            circle1.setLayoutY(circle1.getLayoutY() + deltaY);
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));

            Shape intersect = Shape.intersect(rectangle1, circle1);
            {
                if(intersect.getBoundsInLocal().getWidth() != -1)
                {      
                    System.out.println("This object can not overlap other the other object!");
                    circle1.setLayoutX(circle1.getLayoutX() - deltaX);
                    circle1.setLayoutY(circle1.getLayoutY() - deltaY);
                    lblMain.setText("Collision detected!");
                }
                else
                {
                    lblMain.setText("Collision not detected!");
                }
            }
        });   


        rectangle1.setOnMousePressed((MouseEvent event) -> {
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));
        });

        rectangle1.setOnMouseDragged((MouseEvent event) -> {
            double deltaX = event.getSceneX() - mousePosition.get().getX();
            double deltaY = event.getSceneY() - mousePosition.get().getY();
            rectangle1.setLayoutX(rectangle1.getLayoutX() + deltaX);
            rectangle1.setLayoutY(rectangle1.getLayoutY() + deltaY);
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));

            Shape intersect = Shape.intersect(circle1, rectangle1);
            {
                if(intersect.getBoundsInLocal().getWidth() != -1)
                {      
                    System.out.println("This object can not overlap other the other object!");
                    rectangle1.setLayoutX(rectangle1.getLayoutX() - deltaX);
                    rectangle1.setLayoutY(rectangle1.getLayoutY() - deltaY);
                    lblMain.setText("Collision detected!");
                }
                else
                {
                    lblMain.setText("Collision not detected!");
                }
            }
        });   
    }
}

FXML:

<AnchorPane id="AnchorPane" fx:id="apMain" prefHeight="446.0" prefWidth="577.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="collisiondection.FXMLDocumentController">
    <children>
        <Label fx:id="lblMain" layoutX="254.0" layoutY="408.0" minHeight="16" minWidth="69" />
      <Polygon fx:id="polyOne" fill="DODGERBLUE" layoutX="122.0" layoutY="166.0" stroke="BLACK" strokeType="INSIDE">
        <points>
          <Double fx:value="-50.0" />
          <Double fx:value="40.0" />
          <Double fx:value="50.0" />
          <Double fx:value="40.0" />
          <Double fx:value="0.0" />
          <Double fx:value="-60.0" />
        </points>
      </Polygon>
      <Polygon fx:id="polyTwo" fill="DODGERBLUE" layoutX="419.0" layoutY="166.0" stroke="BLACK" strokeType="INSIDE">
        <points>
          <Double fx:value="-50.0" />
          <Double fx:value="40.0" />
          <Double fx:value="50.0" />
          <Double fx:value="40.0" />
          <Double fx:value="0.0" />
          <Double fx:value="-60.0" />
        </points>
      </Polygon>
      <Circle fx:id="circle1" fill="DODGERBLUE" layoutX="113.0" layoutY="372.0" radius="42.0" stroke="BLACK" strokeType="INSIDE" />
      <Rectangle fx:id="rectangle1" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="100.0" layoutX="379.0" layoutY="314.0" stroke="BLACK" strokeType="INSIDE" width="113.0" />
    </children>
</AnchorPane>
 类似资料:
  • 我有一个问题,碰撞检测一个圆和一个矩形。我曾尝试用勾股定理来解决这个问题。但所有查询都不起作用。矩形与圆的矩形包围盒发生碰撞。

  • 在我的自上而下游戏中,当我的玩家通过婴儿床时,我该如何让他发生碰撞?我用的是交叉矩形。 这是我的密码 更新方法 在渲染方法中 这是完整的代码 谁能告诉我矩形碰撞检测的正确实现是什么?没有重叠,我是这个框架的新手。致谢和预付款:)

  • 我正在编写一个游戏,涉及碰撞的一个移动的圆,由用户控制,和一个移动的矩形,由计算机控制。 完整的代码可以在这里找到:游戏 我在圆和矩形之间的碰撞检测方面遇到了麻烦。当矩形是静态的,碰撞检测工作完美。当圆和矩形的边缘在任一边接触时,程序就会按照它应该的方式进行操作。 这是碰撞检测功能。 谢谢。

  • 我花了数小时寻找解决方案:我正在用libgdx开发一个自上而下的小游戏(可能这与我使用的引擎有关)。现在我必须在我的角色(圆形)和墙(矩形)之间实现碰撞检测。如果可以滑动,我希望角色在碰撞时沿着墙滑动。让我解释一下: 如果我向上移动45度,我可能会撞到墙的下面、左边或角落。 如果我与左边相撞,我想停止x运动,只向上移动。如果我离开墙壁,那么我想继续向上移动。与下侧相同(停止y运动) 如果我与角落相

  • 首先,我用Java制作了一个简单的游戏,其中包括一个蓝色矩形,可以用箭头键和七个不同颜色、半径和下落速度的下落圆圈来移动。本质上,每当矩形与这些圆中的一个接触时,矩形将“失去”生命,这将由我尚未绘制的JFrame右上方的3个矩形指示。每当矩形被这些圆中的一个击中时,其中一个矩形将消失,当蓝色矩形再次被击中时,帧中间将出现一个红色的“游戏结束”文本。 现在,虽然我很难得到颜色和速度,以随机的每一次圆

  • 问题内容: Libgdx中是否可以验证多边形和圆之间的碰撞? 我看到了课程,但只发现了Circle和Rectangle的碰撞测试。那其他多边形呢? 如果我需要手动进行操作,那么使用Libgdx的最佳方法是什么? 问题答案: 因此,我设法在Circle和Polygon之间创建了碰撞测试方法。至少,它对我有用。 这是代码: