有開發過遊戲的人應該都有聽過碰撞偵測這名詞,程式使用碰撞偵測的演算法偵測物件是否發生碰撞的事件,而觸發對應的遊戲行為(動畫、得分、扣血…)。
範例素材圖片使用來自 cocos-creator GitHub
在 flame 中我們使用 mixin Collidable 取得 onCollision 以及 onCollisionEnd 碰撞事件的接口。
mixin Collidable on Hitbox {
CollidableType collidableType = CollidableType.active;
void onCollision(Set<Vector2> intersectionPoints, Collidable other) {}
void onCollisionEnd(Collidable other) {}
@override
void onRemove() {
super.onRemove();
findParent<HasCollidables>()?.collidables.remove(this);
}
}
Collidable 又另外綁定在 Hitbox 設定上
mixin Hitbox on PositionComponent {
final List<HitboxShape> _hitboxes = <HitboxShape>[];
我們就來看看要怎麼完善星星遊戲吧。
首先我們需要在遊戲上 mixin HasCollidables 類別
class StarGame extends FlameGame with HasDraggableComponents, HasCollidables {
...
它用來處理畫面上的可碰撞物件
讓我們加入"星星" SpriteComponent
為了定義可碰撞行為,我們需要 mixin Hitbox, Collidable 類別,並使用addHitbox定義碰撞範圍。
下面我們用圓形碰撞演算法定義範圍。
class Star extends SpriteComponent with Hitbox, Collidable {
bool _collision = false;
Star(_game)
: super(
sprite: Sprite(_game.images.fromCache('star.png')),
) {
position = getNewStarPosition();
addHitbox(HitboxCircle());
}
Vector2 getNewStarPosition() {
return Vector2(_rnd.nextDouble() * 800, _rnd.nextDouble() * 100 + 150);
}
}
同樣的內容我們也在 Moster 類別上加入新的碰撞設定
實作onCollision內容,我們可以從方法上取得碰撞的位置以及碰撞的物件
下面我們檢測與 Star 物件發生碰撞的是 Moster,我們先標記發生碰撞
@override
void onCollision(Set<Vector2> intersectionPoints, Collidable other) {
super.onCollision(intersectionPoints, other);
if (other is Moster) {
_collision = true;
}
}
這邊我們先簡單定義當Star與Moster碰撞時會更換星星的位置,從update方法實作內容。
@override
void update(double dt) {
if (_collision) {
position = getNewStarPosition();
_collision = false;
}
super.update(dt);
}

距離一款完整的遊戲還有許多需要研究的方向:
若需要在更進階的學習遊戲的開發方法,可以到 awesome-flame 查看更多的範例介紹。