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,改为手动创建四个方向的边缘碰撞盒,提前绑定标记,碰撞时直接读取标记即可,无需坐标计算:
- 首先在游戏类的
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")); }
- 修改碰撞判断逻辑:
@override void onCollision(Set<Vector2> intersectionPoints, Collidable other) { if (other is EdgeCollidable) { _isWallHit = true; _hitEdge = other.userData as String; // 直接读取提前绑定的边缘标记 return; } }
内容的提问来源于stack exchange,提问作者crayden
相关产品推荐
相关产品推荐

