How to detect tap on Flame components?

2

I am using Flutter and flame (0.29.3) to build a simple mobile game. I am trying to detect taps on PositionComponent/SpriteComponent. However, I fail to do so. References/tutorials are using addGestureRecognizer but it is deprecated.

I define my PositionComponent is as follows;

class Enemy extends PositionComponent with Tapable {
  Rect enemyRect;

  Enemy(double x, double y) {
    enemyRect = Rect.fromLTWH(x, y, 50, 50);
  }

  @override
  void render(Canvas c) {
    Color color = Color(0XFFFF0000);
    Paint enemyColor = Paint()..color = color;
    c.drawRect(enemyRect, enemyColor);
  }

  void update(double t) {}

  @override
  void onTapUp(TapUpDetails details) {
    print("tap up");
  }

  @override
  void onTapDown(TapDownDetails details) {
    print("tap down");
  }

  @override
  void onTapCancel() {
    print("tap cancel");
  }
}

And, I add PositionComponent to my game.

class GameController extends BaseGame with HasTapableComponents {
  Size screenSize;
  double tileSize;
  Player player;
  Enemy enemy;
  TapableComponent a;

  GameController() {
    initialize();
  }

  void initialize() async {
    resize(await Flame.util.initialDimensions());
    add(enemy = Enemy(200, 200));
  }

  @override
  void render(Canvas c) {
    Rect background = Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);
    Paint backgroundPaint = Paint()..color = Color(0xFFFAFAFA);
    enemy.render(c);
  }

  @override
  void update(double t) {}

  @override
  void resize(Size size) {
    screenSize = size;
    tileSize = screenSize.width / 10;
  }
}

However, it's not working, am I missing something?

flutter
dart
flame
asked on Stack Overflow Mar 14, 2021 by acalgan

1 Answer

1

I think your example code is a mix between v1 code and 0.29.3, if you try with the latest release candidate of Flame: 1.0.0-rc8 then the following should work:

class TapableSquare extends PositionComponent with Tapable {
  static final Paint _white = Paint()..color = const Color(0xFFFFFFFF);
  static final Paint _grey = Paint()..color = const Color(0xFFA5A5A5);


  TapableSquare({Vector2 position})
      : super(
          position: position ?? Vector2.all(100),
          size: Vector2.all(100),
        );

  @override
  void render(Canvas canvas) {
    super.render(canvas);
    canvas.drawRect(size.toRect());
  }

  @override
  bool onTapUp(TapUpDetails details) {...}

  @override
  bool onTapDown(TapDownDetails details) {...}

  @override
  bool onTapCancel() {...}
}

class TapablesGame extends BaseGame with HasTapableComponents {
  @override
  Future<void> onLoad() async {
    add(TapableSquare());
  }
}

Extracted from this example.

EDIT: To make it work for 0.29.3 you should be setting position and size in your Enemy class instead of building your own rect, Tapable can't know about that rect.

answered on Stack Overflow Mar 14, 2021 by spydon • edited Mar 14, 2021 by spydon

User contributions licensed under CC BY-SA 3.0