acalgan
acalgan

Reputation: 91

How to detect tap on Flame components?

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?

Upvotes: 2

Views: 2489

Answers (1)

spydon
spydon

Reputation: 11552

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.

Upvotes: 2

Related Questions