Search code examples
flutterswipegesturerectflame

How to have a Rect move constantly in a linear fashion flutter/flame


I have been having trouble trying to implement a method that moves a Rect in flutter using the flame game engine. The ultimate goal is to swipe in a direction and have the Rect move in that direction at a constant velocity. I found this code:

  void dragUpdate(DragUpdateDetails d)
  {
    final delta = d.delta;
    final size = gameController.screenSize;
    double translateX = delta.dx;
    double translateY = delta.dy;

    // Make sure that the player never goes outside of the screen in the X-axis
    if (playerRect.right + delta.dx >= size.width) {
      translateX = size.width - playerRect.right;
    } else if (playerRect.left + delta.dx <= 0) {
      translateX = -playerRect.left;
    }
    // Make sure that the player never goes outside of the screen in the Y-axis
    if (playerRect.bottom + delta.dy >= size.height) {
      translateY = size.height - playerRect.bottom;
    } else if (playerRect.top + delta.dy <= 0) {
      translateY = -playerRect.top;
    }

    playerRect = playerRect.translate(translateX, translateY);
  }

which at least allows for the free movement of the Rect on screen in regards to finger position. I tried messing with the "translate()" method to have the x/y increment/decrement depending on the delta provide, but to no avail. Any hint or point in the right direction would be greatly appreciate.


Solution

  • Instead of using both the HorizontalDragDetector and VerticalDragDetector, you can use the MultiTouchDragDetector and the code will be a lot simpler.

    class MyGame extends BaseGame with MultiTouchDragDetector {
      Rect _rect = const Rect.fromLTWH(0, 0, 50, 50);
      Offset _velocity = Offset.zero;
    
      MyGame();
    
      @override
      void onReceiveDrag(DragEvent event) {
        event.onEnd = onDragEnd;
      }
    
      void onDragEnd(DragEndDetails details) {
        _velocity = details.velocity.pixelsPerSecond;
      }
    
      @override
      void update(double dt) {
        super.update(dt);
        final timeStepMovement = _velocity * dt;
        _rect = _rect.shift(timeStepMovement);
      }
    
      @override
      void render(Canvas canvas) {
        super.render(canvas);
        canvas.drawRect(_rect, BasicPalette.white.paint);
      }
    }