flame-engine / flame

A Flutter based game engine.
https://flame-engine.org
MIT License
9.15k stars 894 forks source link

LongPressGesture produces error #157

Closed carlpatricio closed 4 years ago

carlpatricio commented 4 years ago

Hi guys I need some help regarding with this, I have a button which will change the position of one of my component, the long pressed event of that button it will continuously trigger my func/method. But after I tried to use LongPressGestures I encounter some error

Here's my code:

void main() async{

  Util utility = Util();
  await utility.fullScreen();
  await utility.setOrientation(DeviceOrientation.portraitUp);
  TapGestureRecognizer tapdown = TapGestureRecognizer();
  final Size size = await Flame.util.initialDimensions();
  GoodGame gg = GoodGame(size);
  tapdown.onTapDown = gg.onTapDown;
  runApp(gg.widget);
  utility.addGestureRecognizer(tapdown);
  utility.addGestureRecognizer(createLongPressRecongizer());
}

GestureRecognizer createLongPressRecongizer(){
  return new LongPressGestureRecognizer()
        ..onLongPressMoveUpdate = (LongPressMoveUpdateDetails longPressMoveUpdateDetails) => print(longPressMoveUpdateDetails);
}

Here's the error I got: _══╡ EXCEPTION CAUGHT BY GESTURE LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter (11847): The following assertion was thrown while routing a pointer event: I/flutter (11847): 'package:flutter/src/gestures/long_press.dart': Failed assertion: line 317 pos 12: '_initialButtons I/flutter (11847): == kPrimaryButton': is not true. I/flutter (11847): I/flutter (11847): Either the assertion indicates an error in the framework itself, or we should provide substantially I/flutter (11847): more information in this error message to help you determine and fix the underlying cause. I/flutter (11847): In either case, please report this assertion by filing a bug on GitHub: I/flutter (11847): https://github.com/flutter/flutter/issues/new?template=BUG.md I/flutter (11847): I/flutter (11847): When the exception was thrown, this was the stack: I/flutter (11847): #2 LongPressGestureRecognizer._checkLongPressEnd (package:flutter/src/gestures/long_press.dart:317:12) I/flutter (11847): #3 LongPressGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/long_press.dart:267:9) I/flutter (11847): #4 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:455:9) I/flutter (11847): #5 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:75:13) I/flutter (11847): #6 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:102:11) I/flutter (11847): #7 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19) I/flutter (11847): #8 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) I/flutter (11847): #9 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) I/flutter (11847): #10 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) I/flutter (11847): #11 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7) I/flutter (11847): #15 _invoke1 (dart:ui/hooks.dart:263:10) I/flutter (11847): #16 _dispatchPointerDataPacket (dart:ui/hooks.dart:172:5) I/flutter (11847): (elided 5 frames from class AssertionError and package dart:async) I/flutter (11847): I/flutter (11847): Event: PointerUpEvent#1ec31(position: Offset(267.6, 474.5), timeStamp: 60:21:57.925000, pointer: 1, kind: I/flutter (11847): touch, down: false, pressureMin: 0.0) I/flutter (11847): ════════════════════════════════════════════════════════════════════════════════════════════════════ W/Looper (11847): Slow Looper main: doFrame is 405ms late because of 1 msg, msg 1 took 407ms (h=android.app.ActivityThread$H w=159)

Is there another way to solve this?

gregkorossy commented 4 years ago

Okay, so I had the same problem but finally figured it out. The problem is that Flame internally registers with the pointerRouter but that seems to be not enough (I'm fairly new to Flutter so can't fully understand the internals yet). What I did to resolve this issue is that instead of using the Flame.util.addGestureRecognizer(...) I created a RawGestureDetector at the top of the widget tree that has the game.widget as its child and the desired gesture recognizers as its gestures. Now the LongPressGestureRecognizer works correctly.

Here is a sample:

GoodGame game = new GoodGame();
runApp(new RawGestureDetector(
  child: game.widget,
  behavior: HitTestBehavior.opaque,
  gestures: {
    LongPressGestureRecognizer:
      GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
          () => LongPressGestureRecognizer()
            ..onLongPress = () {
              debugPrint("[LONG] onLongPress");
            }
            ..onLongPressStart = (evt) {
              debugPrint("[LONG] onLongPressStart: ${evt.globalPosition} at ${DateTime.now().millisecondsSinceEpoch}");
            }
            ..onLongPressMoveUpdate = (evt) {
              debugPrint("[LONG] onLongPressMoveUpdate: ${evt.globalPosition} at ${DateTime.now().millisecondsSinceEpoch}");
            }
            ..onLongPressEnd = (evt) {
              debugPrint("[LONG] onLongPressEnd: ${evt.globalPosition} at ${DateTime.now().millisecondsSinceEpoch}");
            }
            ..onLongPressUp = () {
              debugPrint("[LONG] onLongPressUp");
            }, (LongPressGestureRecognizer instance) {
              // you can handle the instance here too
            })
  },
));