Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PolygonComponent does not respond to hover and click event regions #3031

Closed
1 task
NathanielAJohnson opened this issue Feb 9, 2024 · 8 comments · Fixed by #3040
Closed
1 task

PolygonComponent does not respond to hover and click event regions #3031

NathanielAJohnson opened this issue Feb 9, 2024 · 8 comments · Fixed by #3040
Labels

Comments

@NathanielAJohnson
Copy link

What happened?

Creating a descendant of PolygonComponent did not respond correctly trigger hover and click events.

What do you expect?

When using over a PolygonComponent it should trigger hover and click events when rotated.

How can we reproduce this?

import 'dart:math';

import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class GameWorld extends World {
  GameWorld(this.gameController);

  GameController gameController;
}

class GameController {}

class SpaceGame extends FlameGame with ScrollDetector, ScaleDetector, KeyboardEvents {
  SpaceGame({
    required super.world,
  }) {
    // camera = CameraComponent.withFixedResolution(width: 800, height: 600);
  }

  @override
  Color backgroundColor() => const Color(0x00000000);

  @override
  Future<void> onLoad() async {
    final vertices = ([Vector2(100, 100), Vector2(100, 50), Vector2(50, 50), Vector2(50, 100)]);

    Random r = Random();
    const vBase = 20.0;
    for (var i = 0; i < 10; ++i) {
      world.add(Actor(vertices,
          velocity: Vector2((r.nextDouble() * vBase) - (vBase / 2), (r.nextDouble() * vBase) - (vBase / 2)),
          position: Vector2((r.nextDouble() * 5000) - 2500, (r.nextDouble() * 5000) - 2500),
          angle: r.nextDouble() * 2 * pi,
          spin: (r.nextDouble() * 2) - 2));
    }
  }

  @override
  KeyEventResult onKeyEvent(
    RawKeyEvent event,
    Set<LogicalKeyboardKey> keysPressed,
  ) {
    if (keysPressed.contains(LogicalKeyboardKey.arrowLeft)) {
      camera.moveBy(Vector2(-10, 0));
    }
    if (keysPressed.contains(LogicalKeyboardKey.arrowRight)) {
      camera.moveBy(Vector2(10, 0));
    }
    if (keysPressed.contains(LogicalKeyboardKey.arrowUp)) {
      camera.moveBy(Vector2(0, -10));
    }
    if (keysPressed.contains(LogicalKeyboardKey.arrowDown)) {
      camera.moveBy(Vector2(0, 10));
    }

    return KeyEventResult.ignored;
  }

  static const zoomPerScrollUnit = 0.02;

  @override
  void onScroll(PointerScrollInfo info) {
    // camera.viewfinder.zoom += info.scrollDelta.global.y.sign * zoomPerScrollUnit;
    // clampZoom();
    print("zoom");
  }

  @override
  void onScaleUpdate(ScaleUpdateInfo info) {
    final currentZoom = camera.viewfinder.zoom;
    final delta = info.delta.global;
    final change = delta.y.sign * zoomPerScrollUnit;
    final newZoom = (currentZoom + change).clamp(0.05, 3.0);
    camera.viewfinder.zoom = newZoom;
    // camera.viewfinder.position.translate(-delta.x, -delta.y);
  }
}

class Actor extends PolygonComponent with HoverCallbacks, TapCallbacks {
  Actor(
    super.vertices, {
    required this.velocity,
    required Vector2 super.position,
    required super.angle,
    required this.spin,
  }) : super(
          size: Vector2.all(100),
          // anchor: Anchor.center,
          paint: Paint()..color = Color(Random().nextInt(0xffffffff)),
        ) {
    color = paint.color;
    debugMode = true;
  }
  final Vector2 velocity;
  final double spin;
  late Color color;

  @override
  void update(double dt) {
    super.update(dt);
    position += velocity * dt;
    // angle += spin * dt;
  }

  @override
  void onHoverEnter() {
    print('hover enter');
    paint.color = Colors.black;
  }

  @override
  void onHoverExit() {
    print('hover exit');
    paint.color = color;
  }

  @override
  bool onTapDown(TapDownEvent event) {
    print('tapped');
    return true;
  }
}

void main() {
  final spaceGame = SpaceGame(world: GameWorld(GameController()));
  runApp(
    GameWidget(game: spaceGame),
  );
}

What steps should take to fix this?

No response

Do have an example of where the bug occurs?

No response

Relevant log output

No response

Execute in a terminal and put output into the code block below

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.16.9, on Ubuntu 23.04 6.2.0-39-generic, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2023.1)
[✓] IntelliJ IDEA Ultimate Edition (version 2023.3)
[✓] VS Code (version unknown)
    ✗ Unable to determine VS Code version.
[✓] Connected device (2 available)
[✓] Network resources

• No issues found!

Affected platforms

Linux, Web

Other information

No response

Are you interested in working on a PR for this?

  • I want to work on this
@spydon
Copy link
Member

spydon commented Feb 14, 2024

What Flame version is this with? As far as I know we've never had a method with this signature in TapCallbacks (but I might be wrong):

  bool onTapDown(TapDownEvent event) {

That bool return is from the old events

@NathanielAJohnson
Copy link
Author

NathanielAJohnson commented Feb 15, 2024

Its the hover events that are an issue. I added the onTapDown event handler to test if it was a problem too (and it is). The version of Flame is 1.15.
from ~/.pub-cache/hosted/pub.dev/flame-1.15.0/lib/src/events/flame_game_mixins/multi_tap_dispatcher.dart

/// Called when the user touches the device screen within the game canvas,
  /// either with a finger, a stylus, or a mouse.
  ///
  /// The handler propagates the [event] to any component located at the point
  /// of touch and that uses the [TapCallbacks] mixin. The event will be first
  /// delivered to the topmost such component, and then propagated to the
  /// components below only if explicitly requested.
  ///
  /// Each [event] has an `event.pointerId` to keep track of multiple touches
  /// that may occur simultaneously.
  @mustCallSuper
  void onTapDown(TapDownEvent event) {
    event.deliverAtPoint(
      rootComponent: game,
      eventHandler: (TapCallbacks component) {
        _record.add(TaggedComponent(event.pointerId, component));
        component.onTapDown(event);
      },
    );
  }

@spydon
Copy link
Member

spydon commented Feb 15, 2024

I see, and you said the RectangleComponent was working like it should?
Definitely seems like a bug.

@NathanielAJohnson
Copy link
Author

NathanielAJohnson commented Feb 15, 2024

RectangleComponent behaves correctly. Here is a screen shot that shows how the PolygonComponent reacts to the mouseover event when the mouse is in the inverse quadrant of the debug mode rectangle.
image

@spydon
Copy link
Member

spydon commented Feb 15, 2024

This seems to be the cause: #2930
Edit: That fixed something else though...

@spydon
Copy link
Member

spydon commented Feb 15, 2024

Alright, now I fixed it! (it wasn't the fault of #2930 at all, it just happened to break it).
@NathanielAJohnson can you try depending on the branch (fix/polygon-component-vertices) and see if it fixes the issue for you?

Replace flame with the following in your pubspec to depend on the branch:

dependencies:
  flame:
    git:
      url: https://github.com/flame-engine/flame.git
      ref: fix/polygon-component-vertices
      path: packages/flame

@NathanielAJohnson
Copy link
Author

This fixed it! I also verified it against anchor : Anchor.center and it works as expected. I changed the polygon to a triangle and it worked as well. Thank you.

@spydon
Copy link
Member

spydon commented Feb 16, 2024

Super, thanks for checking!

spydon added a commit that referenced this issue Feb 16, 2024
…ing (#3040)

If the vertices in the `PolygonComponent` weren't starting at 0,0 they
got the wrong hitbox, but rendered correctly.
This PR fixes that.

Closes: #3031
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants