多点触控检测在Flutter Flame中

huangapple go评论71阅读模式
英文:

Multi touch detection In Flutter flame

问题

我想为拳击游戏实现游戏控制。

黑色部分分别表示上勾拳和左直拳。为了格挡,玩家应该使用多点触控,其中一个手指应该在屏幕的左半部,另一个手指在右半部。这显然会与其他控件重叠。

在Flame引擎(flutter)中处理多点触控,同时减少与其他控件的冲突的最佳方法是什么?

英文:

I want to implement game control for a boxing game.

Four sections in black represent uppercuts and jabs.
In order to block, the player should use multi-touch, where one figure should be on the left half of the screen and another figure on the right half. This is clearly overlapping other controls.

What is the best way to handle multi-touch while little conflicts with other controls in Flame engine (flutter).

多点触控检测在Flutter Flame中

答案1

得分: 1

因为这在GitHub问题中已经回答过了,如果其他人也遇到了这个问题,我也会在这里写下答案。

你可以在覆盖这些区域的组件上使用TappableTapCallbacks mixin,就像这样:

class MultiTapGame extends FlameGame with HasTappables {
  @override
  Future<void> onLoad() async {
    debugMode = true;
    await add(Controls());
  }
}

class Controls extends Component with HasGameRef {
  bool isLeftDown = false;
  bool isRightDown = false;

  @override
  Future<void> onLoad() async {
    await addAll(
      [
        TappableRegion(
          position: Vector2.all(0),
          size: Vector2(gameRef.size.x * 0.5, gameRef.size.y * 0.75),
          onTapDownCallback: () {
            isLeftDown = true;
            if (isRightDown) {
              print("Block");
            } else {
              print("Left Uppercut");
            }
          },
          onTapUpCallback: () {
            isLeftDown = false;
          },
        ),
        // 其他 TappableRegion 的配置...
      ],
    );
  }
}

class TappableRegion extends PositionComponent with Tappable {
  TappableRegion({
    super.position,
    super.size,
    super.scale,
    super.angle,
    super.nativeAngle,
    super.anchor,
    super.children,
    super.priority,
    this.onTapDownCallback,
    this.onTapUpCallback,
  });

  late RectangleComponent _rectangleComponent;

  @override
  FutureOr<void> onLoad() {
    _rectangleComponent = RectangleComponent(
      size: size,
      paint: Paint()..color = Colors.green,
    );
    return super.onLoad();
  }

  // 其他方法...
}
英文:

Since this was replied to in the GitHub issue, I'll write the answer here too if anyone else stumbles upon this.

You can use Tappable or TapCallbacks mixin on a component that covers those areas, like this:

class MultiTapGame extends FlameGame with HasTappables {
  @override
  Future&lt;void&gt; onLoad() async {
    debugMode = true;
    await add(Controls());
  }
}

class Controls extends Component with HasGameRef {
  bool isLeftDown = false;
  bool isRightDown = false;

  @override
  Future&lt;void&gt; onLoad() async {
    await addAll(
      [
        TappableRegion(
          position: Vector2.all(0),
          size: Vector2(gameRef.size.x * 0.5, gameRef.size.y * 0.75),
          onTapDownCallback: () {
            isLeftDown = true;
            if (isRightDown) {
              print(&quot;Block&quot;);
            } else {
              print(&quot;Left Uppercut&quot;);
            }
          },
          onTapUpCallback: () {
            isLeftDown = false;
          },
        ),
        TappableRegion(
          position: Vector2(gameRef.size.x * 0.5, 0),
          size: Vector2(gameRef.size.x * 0.5, gameRef.size.y * 0.75),
          onTapDownCallback: () {
            isRightDown = true;
            if (isLeftDown) {
              print(&quot;Block&quot;);
            } else {
              print(&quot;Right Uppercut&quot;);
            }
          },
          onTapUpCallback: () {
            isRightDown = false;
          },
        ),
        TappableRegion(
          position: Vector2(0, gameRef.size.y * 0.75),
          size: Vector2(gameRef.size.x * 0.5, gameRef.size.y * 0.25),
          onTapDownCallback: () {
            isLeftDown = true;
            if (isRightDown) {
              print(&quot;Block&quot;);
            } else {
              print(&quot;Left Jab&quot;);
            }
          },
          onTapUpCallback: () {
            isLeftDown = false;
          },
        ),
        TappableRegion(
          position: Vector2(gameRef.size.x * 0.5, gameRef.size.y * 0.75),
          size: Vector2(gameRef.size.x * 0.5, gameRef.size.y * 0.25),
          onTapDownCallback: () {
            isRightDown = true;
            if (isLeftDown) {
              print(&quot;Block&quot;);
            } else {
              print(&quot;Right Jab&quot;);
            }
          },
          onTapUpCallback: () {
            isRightDown = false;
          },
        ),
      ],
    );
  }
}

class TappableRegion extends PositionComponent with Tappable {
  TappableRegion({
    super.position,
    super.size,
    super.scale,
    super.angle,
    super.nativeAngle,
    super.anchor,
    super.children,
    super.priority,
    this.onTapDownCallback,
    this.onTapUpCallback,
  });

  late RectangleComponent _rectangleComponent;

  @override
  FutureOr&lt;void&gt; onLoad() {
    _rectangleComponent = RectangleComponent(
      size: size,
      paint: Paint()..color = Colors.green,
    );
    return super.onLoad();
  }

  void Function()? onTapDownCallback;
  void Function()? onTapUpCallback;

  @override
  bool onTapDown(TapDownInfo info) {
    onTapDownCallback?.call();
    add(_rectangleComponent);
    return super.onTapDown(info);
  }

  @override
  bool onTapUp(TapUpInfo info) {
    onTapUpCallback?.call();
    _rectangleComponent.removeFromParent();
    return super.onTapUp(info);
  }

  @override
  bool onTapCancel() {
    onTapUpCallback?.call();
    _rectangleComponent.removeFromParent();
    return super.onTapCancel();
  }
}

huangapple
  • 本文由 发表于 2023年3月12日 15:57:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75711762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定