【Flutter&Flame游戏 - 拾叁】碰撞检测 | CollisionCallbacks


theme: cyanosis

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 14 天,点击查看活动详情


前言

这是一套 张风捷特烈 出品的 Flutter&Flame 系列教程,发布于掘金社区。如果你在其他平台看到本文,可以根据对于链接移步到掘金中查看。因为文章可能会更新、修正,一切以掘金文章版本为准。本系列源码于 【toly_game】 ,如果本系列对你有所帮助,希望点赞支持,本系列文章一览:

第一季完结,谢谢支持 ~


1. 碰撞检测场景搭建

前面我们 矩形域中心点 的包含关系校验是否碰撞,这样会有很大的误差。Flame 中提供了 CollisionCallbacks ,对碰撞检测进行了封装,支持两个形状间的配置检测。本文我们就来认识一下该如何使用这个 mixin

为了更好地说明碰撞,这里先用图形进行简单示意,本文将在这个场景的基础上进行测试。如下所示,定义一个 Cilrcle 构件和 Line 构件,其中 Line 的位置可以随着触点的拖动而更新:代码详见 【13/01】

如下 TolyGame 中有 LineCircle 两个角色,混入 PanDetector 。覆写 onPanUpdate 方法,在触点更新时,增加 line 的位移。 另外目前 CircleLine 两个构件都只是覆写 render 方法,进行绘制而已,没什么要点,代码就不贴了,详见源码。

```dart class TolyGame extends FlameGame with PanDetector{ late Line line; late Circle circle;

@override Future onLoad()async{ circle = Circle(radius: 40, position: size/2); line = Line(lineWidth: 80,position: size/2-Vector2(140,0)); add(circle); add(line); }

@override void onPanUpdate(DragUpdateInfo info) { line.position+=info.delta.global; } } ```


2. 如何让构件支持碰撞检测

如下所示,直线代表 矩形域 ,圆形代表 圆形域 ,当两个区域发成重叠时,则发生碰撞。代码详见【13/02】

首先说明一点:顶层的 TolyGame 需要混入 HasCollisionDetection 才可以支持碰撞检测。

dart class TolyGame extends FlameGame with HasCollisionDetection,PanDetector{


另外,想让某个 Compoment 支持碰撞检测,需要三个步骤:

    1. 混入 CollisionCallbacks

dart class Circle extends PositionComponent with CollisionCallbacks{

    1. 添加检测区域 Hitbox : 这个区域就是代表着当前构建件的命中区域。

```dart late ShapeHitbox hitbox;

@override Future onLoad() async { hitbox = CircleHitbox(); add(hitbox); } ```

  • 3.覆写碰撞检测回调方法:CollisionCallbacks 中有三个碰撞回调的方法,可以监听到碰撞开始、碰撞结束、发生碰撞三个事件。

如下,在 Circle 构件中,覆写 onCollisionStart 方法,当开始发送碰撞时,将圆的颜色置为 blue;碰撞结束时,将圆的颜色置为 white

dart @override void onCollisionStart( Set<Vector2> intersectionPoints, PositionComponent other, ) { super.onCollisionStart(intersectionPoints, other); _paint.color = Colors.blue; } @override void onCollisionEnd(PositionComponent other) { super.onCollisionEnd(other); _paint.color = Colors.white; }


3.碰撞形状

其实这样看来,碰撞检测最重要的还是碰撞区域的确定。在 Flamecollisions/hitboxes 中只提供了一些常用的形状,比如 圆形多边形矩形屏幕 。感觉还是挺有局限性的,如果能加上 Path 自定义形状就好了。

其中我们在之前已经见识过了 RectangleHitbox ,提供将它的 debugMode 置为 true ,就可以看到边界信息。其实本质上就是为该构件确定一个碰撞检测的区域:


下面我们通过一个案例来测试一下 多边形屏幕边界 的碰撞检测:【13/03】

如下定义一个菱形的 PolygonHitbox ,主要就是根据顶点,确定多边形。这样当一个 CollisionCallbacks 的角色和其碰撞,就可以接收到 onCollisionXXX 的回调。

```dart ---->[Polygon]---- late ShapeHitbox hitbox;

@override Future onLoad() async { hitbox = PolygonHitbox([ Vector2(size.x, size.y/2), Vector2(size.x/2, size.y), Vector2(0, size.y/2), Vector2(size.x/2, 0), ]); add(hitbox); } ```


最后看一下 ScreenHitbox ,它本质上非常简单,就是在最外层添加一个 RectangleHitbox 而已。


总得来说,通过 CollisionCallbacks 实现碰撞的检测,本质就是定义碰撞物的区域。然后根据碰撞的回调处理逻辑而已,其实 CollisionCallbacks 也是比较有局限性的。但相比于之前的 矩形域中心点 的包含关系,可以说上升了一个维度,支持了 之间的碰撞。
本文介绍了一下 Flame 中通过 CollisionCallbacks 实现碰撞检测的方式,下一篇我们将基于这种方式来对前面的案例进行优化。那本文就到这里,明天见 ~

\

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值