Search code examples
flutterdartdrag-and-dropdraggableflame

Flame-engine, Draggable component doesn't work


I am completely newbie in flutter world specially flame-engine. Maybe it's a simple issue. But currently I couldn't figure it out. So please help me!

The main issue is my Draggable component doesn't work all event handler functions seem like doesn't not work correctly. Do you have any idea?

Draggable component code:

import 'package:flame/components.dart';
import 'package:flame/input.dart';

// Zooh bolomjtoi component
class DrawerComponent extends PositionComponent with Draggable {
  late final mainRectangle;

  Vector2? dragDeltaPosition;
  bool get isDragging => dragDeltaPosition != null;

  @override
  Future<void>? onLoad() async {
    final bg = await Sprite.load('drawer.png');
    final localSize = Vector2(350, 210);
    final mainRectangle = SpriteComponent(size: localSize, sprite: bg);
    mainRectangle.position = isDragging ? (dragDeltaPosition)! : Vector2(0, 0);
    add(mainRectangle);
  }

  @override
  bool onDragStart(DragStartInfo info) {
    print("Drag ehelleee..");
    dragDeltaPosition = info.eventPosition.game - position;
    return false;
  }

  @override
  bool onDragUpdate(DragUpdateInfo info) {
    print("Drag update..");
    if (isDragging) {
      final localCoords = info.eventPosition.game;
      position.setFrom(localCoords - dragDeltaPosition!);
    }
    return false;
  }

  @override
  bool onDragEnd(DragEndInfo info) {
    print("Drag end...");
    dragDeltaPosition = null;
    return false;
  }

  @override
  bool onDragCancel() {
    dragDeltaPosition = null;
    return false;
  }
}

Main FlameGame class:

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:furniture/drawer.dart';

class Core extends FlameGame with HasDraggables {
  late final SpriteComponent mainRectangle;

  @override
  Future<void>? onLoad() async {
    final bg = await Sprite.load('example.jpeg');
    final localSize = Vector2(super.size.x * 0.7, super.size.y * 0.6);
    final mainRectangle = SpriteComponent(size: localSize, sprite: bg);

    mainRectangle.position = Vector2(super.size.x * 0.15, super.size.y * 0.2);
    mainRectangle.angle = 0;
    add(mainRectangle);
    add(DrawerComponent());
  }
}

Flutter main class:

import 'package:flame/game.dart';
import 'package:flutter/material.dart';
import 'package:furniture/core.dart';

void main() {
  final game = Core();
  runApp(GameWidget(game: game));
}

Solution

  • I think your problem is into your onLoad() because you don't declare the values correctly, I have this example for you:

    class Sushi extends SpriteComponent with Draggable, HasGameRef<JapaneseChef>{
      /// Sushi constructor
      Sushi( this._img, this._position, this._isMove, this._isDraggable,){
        position = _position;
        size = Vector2(250,250);
      }
    
      late final String _img;
      late final Vector2 _position;
      late Vector2 _dragDeltaPosition;
      late final bool _isMove;
      late final bool _isDraggable;
    
      /// Get delta position
      Vector2 get dragDeltaPosition => _dragDeltaPosition;
    
      set dragDeltaPosition(Vector2? dragDeltaPosition) {
        if(dragDeltaPosition != null){
          _dragDeltaPosition = dragDeltaPosition;
        }
      }
    
      @override
      Future<void>? onLoad() async{
        final spriteSushi = await Sprite.load(_img);
        sprite = spriteSushi;
        changePriorityWithoutResorting(5);
        return super.onLoad();
      }
    
      @override
      void update(double dt) {
        if (_isMove) {
          position.x -= 0.6;
          if (position.x < -size.x) {
            remove(this);
          }
        }
    
        super.update(dt);
      }
    
      @override
      bool onDragStart(int pointerId, DragStartInfo info) {
        if(_isDraggable) {
          dragDeltaPosition = info.eventPosition.game - position;
        }
        return false;
      }
    
      @override
      bool onDragCancel(int pointerId) {
        dragDeltaPosition = null;
        return super.onDragCancel(pointerId);
      }
    
      @override
      bool onDragUpdate(int pointerId, DragUpdateInfo info) {
        if (parent is! JapaneseChef) {
          return true;
        }
        final dragDeltaPosition = this.dragDeltaPosition;
    
        position.setFrom(info.eventPosition.game - dragDeltaPosition);
        return false;
      }
    
      @override
      bool onDragEnd(int pointerId, DragEndInfo info) {
        dragDeltaPosition = null;
        return false;
      }
    
    }
    

    Also, you can see the example from Flame engine

    Example result