LoginSignup
2
0

More than 1 year has passed since last update.

Flutter flame のサンプルコードを紐解く

Posted at

サンプルコードの動かし方

以下をクローンします。他のサンプルもありますが、以下のコードが最もシンプル?だと思われます。

サンプルコードの動き

  • 起動すると、黒い画面に四角がくるくる回っている
  • 四角をクリックすると、四角が消える
  • 四角以外の場所をクリックすると、くるくる回る四角が増える

ソースコードの中身

main 関数

  • main関数内では、いつものMaterialAppではなくGameWidgetが呼ばれています。
  • GameWidgetには引数としてMyGame(後述)クラスが渡されています。
main.dart
void main() {
  runApp(
    GameWidget(
      game: MyGame(),
    ),
  );
}

わかったこと

  • ゲームを開始するときはGameWidgetを使う。

疑問

  • 最初はMaterialAppでスタートし、例えばボタンをクリックしたらGameWidgetを呼ぶとかもできるのか?
  • 画面の大きさはどのように指定するか?

MyGame クラス

  • MyGame クラスは FlameGame を継承して作られています。
  • また、MyGame クラスは HasTappableComponents を mixin して作られています。
  • onLoadをオーバーライドして、ゲーム開始時に四角(Squareクラス)が1つある状態にしています。
  • onTapDownをオーバーライドして、タップダウンイベントがあったときに四角を追加する処理を実行しています。
main.dart
/// This example simply adds a rotating white square on the screen.
/// If you press on a square, it will be removed.
/// If you press anywhere else, another square will be added.
class MyGame extends FlameGame with HasTappableComponents {
  @override
  Future<void> onLoad() async {
    add(Square(size / 2));
  }

  @override
  void onTapDown(TapDownEvent event) {
    super.onTapDown(event);
    if (!event.handled) {
      final touchPoint = event.canvasPosition;
      add(Square(touchPoint));
    }
  }
}

わかったこと

  • 必要なジェスチャー(HasTappableComponents)は mixin で指定する。
  • onLoadでゲーム開始時に実行したい処理を実行できる。
  • mixin したジェスチャーに応じてイベント処理を定義できる。
  • event.canvasPositionでクリック(タップ)した場所を取得している。

疑問

  • 他にはどのようなジェスチャーが対応している?
  • event.handledとは?

Square クラス

  • RectangleComponentを継承して作られている。
  • TapCallbacksを mixin して作られている。
  • RectangleComponentpositionsizeanchorが指定できる。
  • 定期的に実行されるupdate関数でくるくるさせている。
  • RectangleComponentangleフィールドを持っていて、それを更新すると角度が変わる。
  • onLoadSquareが生成された際に真ん中の赤い四角と角にある青い四角を追加している。
  • onTapDownで自身を消したあとに、event.handledtrueにセットしている。
main.dart
class Square extends RectangleComponent with TapCallbacks {
  static const speed = 3;
  static const squareSize = 128.0;
  static const indicatorSize = 6.0;

  static Paint red = BasicPalette.red.paint();
  static Paint blue = BasicPalette.blue.paint();

  Square(Vector2 position)
      : super(
          position: position,
          size: Vector2.all(squareSize),
          anchor: Anchor.center,
        );

  @override
  void update(double dt) {
    super.update(dt);
    angle += speed * dt;
    angle %= 2 * math.pi;
  }

  @override
  Future<void> onLoad() async {
    super.onLoad();
    add(
      RectangleComponent(
        size: Vector2.all(indicatorSize),
        paint: blue,
      ),
    );
    add(
      RectangleComponent(
        position: size / 2,
        size: Vector2.all(indicatorSize),
        anchor: Anchor.center,
        paint: red,
      ),
    );
  }

  @override
  void onTapDown(TapDownEvent event) {
    removeFromParent();
    event.handled = true;
  }
}

わかったこと

  • GameWiget->FlameGame->XXXComponent という関係性で構成されている。
  • updateでコンポーネントごとに定期的に実行したい処理を書ける。
  • Square以外の場所がタップされた場合は、MyGameonTapDownのみが実行される。
  • Squareがタップされた場合は、SquareonTapDownが実行されたあと、MyGameonTapDownが実行される。
    • このときevent.handledtrueにセットされているため、MyGameonTapDownでのSquare追加処理がスキップされている。

疑問

  • 他のはどのようなコンポーネント、ジェスチャーがあるか?
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0