2023-05-03
HasCollisionDetection
ミックスインを使うことで物理演算を使わない当たり判定をすることができます。
各コンポーネントに Hitbox を設定すると、衝突時にonCollision
が呼ばれるようになります。
地面を作り、タップした場所にボールを生成するサンプルを作ってみます。 ボールは落下しますが、地面か他のボールに触れると停止します。
まずは地面を作ります。
RectangleHitbox
を使って、四角形の Hitbox を作ります。
class Ground extends RectangleComponent {
Ground({super.position, super.size})
: super(
paint: BasicPalette.gray.paint(),
);
@override
Future<void> onLoad() async {
super.onLoad();
await add(RectangleHitbox());
}
}
次にボールクラスを用意します。
CircleHitbox
を使って、円形の Hitbox を作ります。
またupdate
では落下させるためにy
を増やしています。
onCollision
で落下を止めます。
class Ball extends CircleComponent with CollisionCallbacks {
Ball({super.position})
: super(
radius: 10,
);
var vy = 2.0;
@override
Future<void> onLoad() async {
super.onLoad();
await add(CircleHitbox());
}
@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
super.onCollision(intersectionPoints, other);
if (other is Ground || other is Ball) {
vy = 0;
}
}
@override
void update(double dt) {
super.update(dt);
y += vy;
}
}
あとはゲームクラスで、地面やボールを生成します。
class CollisionGame extends FlameGame with TapCallbacks, HasCollisionDetection {
@override
Future<void> onLoad() async {
super.onLoad();
await add(
Ground(
position: Vector2(0, size.y * 0.9),
size: Vector2(size.x, size.y * 0.1),
),
);
}
@override
void onTapDown(TapDownEvent event) {
super.onTapDown(event);
add(
Ball(position: event.localPosition),
);
}
}
これで当たり判定が動くようになりました。
© 2023 tnantoka