Search code examples
fluttertouchflame

Update touch position (slide) during time with Flame (Flutter)


in my game with Flame I have a space ship, and I want it to follow where I'm pressing with my finger. For the moment it goes to the first spot I touch until I leave the finger from the screen, but if I move keeping it on, it continues to follow where I initially pressed. Is there a way to update where my finger is(using HasTappableComponents)? Or should I change approach?

class SpaceFlame extends FlameGame with HasTappableComponents {
  late Ship ship;
  late TapHandler tapHandler;
  @override
  Future<void> onLoad() async {
    ship = Ship()
      ..position = Vector2(size.x / 2, size.y / 2)
      ..size = Vector2(64, 64)
      ..setSpeed(100);
    tapHandler = TapHandler();
    ship.anchor = Anchor.center;
    await addAll([
      Background(Palette.background),
      ship,
      tapHandler,
    ]);
  }

  @override
  void render(Canvas canvas) {
    canvas.drawRect(canvasSize.toRect(), Paint()..color = Palette.buttonBlu);
  }

  @override
  void update(double dt) {
    // TODO: implement update
    if (tapHandler.tapped) {
      print('tapped');
      Vector2 moveDirection = Vector2(
          tapHandler.tapPosition.x - ship.position.x,
          tapHandler.tapPosition.y - ship.position.y);
      ship.setMoveDirection(moveDirection);
    } else {
      ship.setMoveDirection(Vector2.zero());
    }
    super.update(dt);
  }
}

class TapHandler extends PositionComponent with TapCallbacks {
  TapHandler() : super(anchor: Anchor.center);

  bool tapped = false;
  Vector2 _tapPosition = Vector2.zero();

  final _paint = Paint()..color = const Color(0x00000000);

  @override
  void onGameResize(Vector2 canvasSize) {
    super.onGameResize(canvasSize);

    size = canvasSize;

    position = canvasSize / 2;
  }

  Vector2 get tapPosition => _tapPosition;

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

  @override
  void onTapDown(TapDownEvent event) {
    print('object');
    tapped = true;
    _tapPosition = event.canvasPosition;
  }
}


Solution

  • When you keep your finger on the screen and drag it the even is no longer a tap, but a drag.

    To react to this event you need to use HasDraggableComponents on the game and DragCallbacks on the component. Then you need to implement onDragUpdate in your component and set the position to the position that the event reports for the drag.