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

Flutter Flame同类型多对象碰撞管理:气泡射手局部消除实现

实现气泡射手的邻近同类型气泡消除功能

我正在开发一个包含鱼、狗、猫三种圆形气泡的气泡射手Demo,当前发射狗气泡时会消除屏幕上所有同类型气泡,希望改为仅消除被击中气泡邻近的同类型气泡(包括连锁相邻的)。现有碰撞处理代码如下:

@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {     
  super.onCollision(intersectionPoints, other);
  if (other is DogBubble) {
    if (position.distanceTo(other.position) <= radius + other.radius) {
      removeFromParent();
    }
  }
}

之前尝试过仅移除被击中的单个气泡,或是全量清除同类型气泡,都不符合需求,需要实现击中后消除所有连通的邻近同类型气泡。


核心思路

要实现连锁邻近消除,需要通过**广度优先搜索(BFS)**从被击中的气泡出发,遍历所有与之直接或间接相邻的同类型气泡,最后统一移除这些气泡。关键步骤是:

  • 维护全局的气泡列表,方便查找和遍历所有屏幕上的气泡
  • 碰撞触发时,启动BFS收集所有连通的同类型气泡
  • 批量移除收集到的气泡

具体实现步骤

  1. 全局气泡管理
    在游戏主类中维护一个所有气泡的列表,每次生成气泡时加入,移除时同步删除:
class BubbleShooterGame extends FlameGame {
  final List<BaseBubble> bubbles = [];

  // 添加气泡时调用
  void addBubble(BaseBubble bubble) {
    add(bubble);
    bubbles.add(bubble);
  }

  // 移除气泡时调用
  void removeBubble(BaseBubble bubble) {
    bubble.removeFromParent();
    bubbles.remove(bubble);
  }
}
  1. 修改碰撞处理逻辑
    在发射的气泡类的onCollision方法中,触发邻近气泡的收集与移除:
@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {     
  super.onCollision(intersectionPoints, other);
  // 仅处理同类型气泡的碰撞,排除自身
  if (other is DogBubble && other != this) {
    final game = this.game as BubbleShooterGame;
    // 收集所有连通的同类型气泡
    final connectedBubbles = _findConnectedSameTypeBubbles(other, game.bubbles);
    // 批量移除目标气泡
    for (final bubble in connectedBubbles) {
      game.removeBubble(bubble);
    }
    // 移除发射的气泡本身
    removeFromParent();
  }
}
  1. 实现BFS遍历连通气泡
    添加私有方法执行广度优先搜索,找出所有相邻的同类型气泡:
List<BaseBubble> _findConnectedSameTypeBubbles(BaseBubble startBubble, List<BaseBubble> allBubbles) {
  final connected = <BaseBubble>[];
  final visited = <BaseBubble>{};
  final queue = Queue<BaseBubble>();

  queue.add(startBubble);
  visited.add(startBubble);

  while (queue.isNotEmpty) {
    final current = queue.removeFirst();
    connected.add(current);

    // 遍历所有气泡,筛选未访问、同类型且相邻的气泡
    for (final bubble in allBubbles) {
      if (!visited.contains(bubble) && 
          bubble.runtimeType == startBubble.runtimeType &&
          current.position.distanceTo(bubble.position) <= current.radius + bubble.radius) {
        visited.add(bubble);
        queue.add(bubble);
      }
    }
  }

  return connected;
}

代码说明

  • 全局气泡列表:确保能访问到屏幕上所有气泡,避免遗漏连锁相邻的目标
  • BFS遍历:从被击中气泡开始逐层扩散,确保所有直接/间接相邻的同类型气泡都被收集(比如A碰B、B碰C,击中A时A、B、C都会被移除)
  • 批量移除:统一处理移除操作,避免遍历过程中修改列表引发异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:55:08