【问题标题】:Detecting collision of Node in one StackPane with Node in another StackPane检测一个 StackPane 中的节点与另一个 StackPane 中的节点的冲突
【发布时间】:2021-06-04 18:16:56
【问题描述】:

作为前言,我对 JavaFX 编程非常陌生。 (上学期我们在我的一门课上介绍了 JavaFX,在过去的一个月左右,我一直致力于用 JavaFX 制作一个简单的游戏。)

我遇到的一个问题是尝试检测一个 StackPane 中的窗格与另一个 StackPane 中的窗格的冲突。具体来说,我在 Game 类中有一个“Player”节点(“Player”扩展了扩展 StackPane 的抽象“Sprite”)以及一些“Asset”节点(“Asset”是一个抽象父类,类似于“Sprite”也扩展了 StackPane )。 “Player”和每个“Asset”节点都由 ImageView 和 Pane 对象组成,它们将成为节点的“边界”。

这是我尝试在 Game 类中跟踪碰撞的方式,但它不起作用:

protected void update() {
    // Call playerBoundsHandler in update cycle
    for (Asset asset : this.gameArea.getAssets()) {
        playerBoundsHandler(asset);
    } // for
} // update

private void playerBoundsHandler(Asset asset) {
    for (Pane boundary : asset.getAssetBoundaries()) {
        if (player.getPlayerStandingAreaBox()
        .getBoundsInParent()
        .intersects(boundary.getBoundsInParent())) {
            // do stuff here
        } // if
    } // for
} // playerBoundsHandler

我猜这里使用 getBoundsInParent() 有问题,因为我试图跟踪两个单独节点内的子节点的交集,但我不知道解决方案是什么。我需要用 getBoundsInLocal 或其他方法做些什么吗?

为了清楚起见,这里是 Player 类的相关部分:

/** 
* Player class constructor. 
* Player class extends "Sprite" (abstract class)
* which extends StackPane.
*/
public Player(double xSpawn, double ySpawn) {
    // Add Player Standing Box (a Pane situated at the feet of the Player sprite)  
    this.playerStandingAreaBox = new Pane();
    // width, height, etc. set here
    this.getChildren().add(playerStandingAreaBox);
    this.setAlignment(playerStandingAreaBox, Pos.BOTTOM_CENTER);
} // Player constructor

public Pane getPlayerStandingAreaBox() {
    return this.playerStandingAreaBox;
} // getPlayerStandingAreaBox

Asset 子类的设计与此处的 Player 类几乎相同。如果还需要澄清,这里是“高速公路”类:

public class Highway extends Asset {

    public Highway(double translateX, double translateY) {
        // call super here
        setAssetBoundaries();
    } // Highway constructor

    @Override
    setAssetBoundaries() {
        Pane boundaryOne = new Pane();
        // set boundaryOne settings
        this.getChildren().add(boundaryOne);
        this.assetBoundaries.add(boundaryOne);
        Pane boundaryTwo = new Pane();
        // set boundaryTwo settings
        this.getChildren().add(boundaryTwo);
        this.assetBoundaries.add(boundaryTwo);
    } // setAssetBoundaries
 
    /**
    * assetBoundaries is an ArrayList<Asset> object also inherited.
    * getAssetBoundaries() is inherited from the "Asset" class
    * which returns assetBoundaries.
    */

下面的屏幕截图显示了我的玩家精灵(不要评判糟糕的像素艺术!我已经知道这家伙的右臂看起来很笨拙,步枪看起来很可笑!)他的站立框以红色突出显示,并且“高速公路”资产在最顶部和最底部都以黄色突出显示。当玩家的盒子与高速公路的盒子之一相交时,我想注册。

Player and Highway

【问题讨论】:

  • 我没有阅读您的所有问题,但您可以在以下网址找到相关信息:Checking Collision of Shapes with JavaFX。我的猜测是,要获得更有针对性的答案,您可能需要通过提供minimal reproducible example(完整的、最少的代码,可以复制和粘贴以运行,但不能复制整个应用程序并编写仅演示两个形状的碰撞问题,仅此而已)。
  • 如果他们有不同的父母,比较父母中的界限将不起作用(您正在查看每个人的不同坐标系)。您需要在它们共同的坐标系中比较它们的界限,例如现场。所以,例如player.localToScene(player.getBoundsInLocal())boundary.localToScene(boundary.getBoundsInLocal()).
  • 谢谢 James_D!自从我发布这个问题以来,我一直在追踪这条线索,但还没有弄清楚如何准确地设置它。我已经用你给的东西做我现在想做的事了! @jewelsea 对此感到抱歉。下次我在这里提问时会记住 MRE。
  • 我写了一个demo for understanding layout bounds,它可能会帮助您了解正在发生的事情。这是 JavaFX 2 首次发布时编写的较旧的演示,因此它可能不适用于最新的 JavaFX 版本。

标签: javafx intersection


【解决方案1】:

谢谢,James_D。以下更改完全符合我的要求。

private void playerBoundsHandler(Asset asset) {
    for (Pane boundary : asset.getAssetBoundaries()) {
        Bounds boundaryBoundsInScene = boundary.localToScene(boundary.getBoundsInLocal());
        Bounds playerStandingBoxBoundsInScene = player.getPlayerStandingBoxArea()
            .localToScene(player.getPlayerStandingBoxArea().getBoundsInLocal());
        if (boundaryBoundsInScene.intersects(playerStandingBoundsInScene)) {
            // do stuff here
        } // if
    } // for
} // playerBoundsHandler

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-11
    • 2021-01-01
    • 2021-02-27
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多