有開發過遊戲的人應該都有聽過碰撞偵測
這名詞,程式使用碰撞偵測
的演算法偵測物件是否發生碰撞的事件,而觸發對應的遊戲行為(動畫、得分、扣血…)。
範例素材圖片使用來自 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 查看更多的範例介紹。