You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX Timeline动画中线条碰撞检测问题求助

解决JavaFX Timeline动画中线条碰撞检测的问题

你的问题根源很明确:当前的碰撞检测代码只在动画启动前执行了一次,这时候线条还没开始移动,自然没法捕捉到动画过程中的碰撞。要实现动画过程中的实时碰撞检测,有两种常用的方案:


方案1:监听动画时间变化,实时检测碰撞

给Timeline的currentTimeProperty()添加监听器,每次动画时间更新(也就是每一帧刷新时)都执行一次碰撞检测逻辑:

Line line = new Line(100, 200, 200, 200);
Line line1 = new Line(350,50,350,300);

Timeline animation = new Timeline(
    new KeyFrame(Duration.seconds(1.5), new KeyValue(line.endXProperty(), 400))
);
animation.setCycleCount(1);

// 添加时间变化监听器,每帧执行碰撞检测
animation.currentTimeProperty().addListener((obs, oldTime, newTime) -> {
    if (line.getBoundsInParent().intersects(line1.getBoundsInParent())) {
        System.out.println("Collision!");
        // 可在这里添加碰撞后的逻辑,比如停止动画
        // animation.stop();
    }
});

animation.play();

Pane root = new Pane(line, line1);
// 后续Stage初始化代码...

方案2:在KeyFrame中添加帧回调逻辑

如果想更灵活控制检测时机,可以创建一个高频执行的KeyFrame,把碰撞检测逻辑放到里面:

Line line = new Line(100, 200, 200, 200);
Line line1 = new Line(350,50,350,300);

// 创建每帧执行的碰撞检测KeyFrame(约60帧/秒)
KeyFrame collisionCheckFrame = new KeyFrame(Duration.millis(16),
    event -> {
        if (line.getBoundsInParent().intersects(line1.getBoundsInParent())) {
            System.out.println("Collision!");
        }
    }
);

Timeline animation = new Timeline(
    new KeyFrame(Duration.seconds(1.5), new KeyValue(line.endXProperty(), 400)),
    collisionCheckFrame // 加入碰撞检测帧
);
animation.setCycleCount(1);
animation.play();

Pane root = new Pane(line, line1);
// 后续Stage初始化代码...

额外优化提示

  • 如果你需要精确的线段相交检测(而非包围盒碰撞),可以用JavaFX的Shape.intersect()方法,避免包围盒相交但线条本身不相交的“假碰撞”:
    Shape intersection = Shape.intersect(line, line1);
    if (!intersection.getBoundsInParent().isEmpty()) {
        System.out.println("精确碰撞!");
    }
    
  • 若动画复杂度较高,可适当降低检测频率(比如每2帧检测一次),减少性能消耗。

内容的提问来源于stack exchange,提问作者Gilthoniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:29:14