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

Flame Engine中如何检测物体与屏幕底部等特定边缘的碰撞?

实现方案

你使用的Flame 1.0.0-releasecandidate.13版本中,可以通过以下两种稳定方案实现屏幕碰撞边缘的识别:


方案1:基于碰撞点坐标计算(无需修改原有ScreenCollidable逻辑)

直接利用碰撞回调返回的交点坐标,结合屏幕尺寸判断碰撞位置,修改onCollision方法如下:

@override
void onCollision(Set<Vector2> intersectionPoints, Collidable other) {
  if (other is ScreenCollidable) {
    _isWallHit = true;
    // 取第一个碰撞交点即可,边缘碰撞的坐标特征非常明确
    final hitPoint = intersectionPoints.first;
    final screenSize = game.size; 
    const epsilon = 1.0; // 浮点计算容错值,可根据实际需求调整为1~2像素

    if ((hitPoint.y - screenSize.y).abs() < epsilon) {
      // 碰撞屏幕底部
      _hitEdge = "bottom";
    } else if (hitPoint.y.abs() < epsilon) {
      // 碰撞屏幕顶部
      _hitEdge = "top";
    } else if (hitPoint.x.abs() < epsilon) {
      // 碰撞屏幕左侧
      _hitEdge = "left";
    } else if ((hitPoint.x - screenSize.x).abs() < epsilon) {
      // 碰撞屏幕右侧
      _hitEdge = "right";
    }
    return;
  }
}

注意需要给你的MyCollidable类混入HasGameRef,才能直接通过game.size获取屏幕尺寸:

class MyCollidable extends PositionComponent with Collidable, HasGameRef {
  // 类原有逻辑
  bool _isWallHit = false;
  String? _hitEdge; // 存储碰撞的边缘类型
}

方案2:手动添加带标记的边缘碰撞盒(稳定性更高)

不使用默认的ScreenCollidable,改为手动创建四个方向的边缘碰撞盒,提前绑定标记,碰撞时直接读取标记即可,无需坐标计算:

  1. 首先在游戏类的onLoad方法中添加四个边缘碰撞盒:
@override
Future<void> onLoad() async {
  final screenSize = size;
  // 分别为四个边缘绑定对应的类型标记
  add(EdgeCollidable.top(screenSize, userData: "top"));
  add(EdgeCollidable.bottom(screenSize, userData: "bottom"));
  add(EdgeCollidable.left(screenSize, userData: "left"));
  add(EdgeCollidable.right(screenSize, userData: "right"));
}
  1. 修改碰撞判断逻辑:
@override
void onCollision(Set<Vector2> intersectionPoints, Collidable other) {
  if (other is EdgeCollidable) {
    _isWallHit = true;
    _hitEdge = other.userData as String; // 直接读取提前绑定的边缘标记
    return;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:09:03