Files
flame/lib/src/components/mixins/tapable.dart
Lukas Klingsbo 0593e35766 Add hitbox to PositionComponent (#618)
* Move out collision detection methods

* Add possibility to define a hull for PositionComponents

* Add example of how to use hull with tapable

* Update contains point comment

* Fix contains point

* Hull should be based on center position

* Remove collision detection parts

* Added tests

* Use percentage of size instead of absolute size

* Separate hull from PositionComponent

* Clarify hull example

* Fix formatting

* Override correct method

* Use mixin for hitbox

* Update changelog

* Rename HasHitbox to Hitbox

* Clarified names

* Center to edge is considered as 1.0

* Fix test

* Add spaces within braces

* Removed extra spaces in the braces

* Add hitbox docs

* Fix link

* Moved point rotation to Vector2 extension

* Render hitbox within extension

* Fix rebase

* Fix rebase

* Fix formatting
2021-01-20 23:39:01 +01:00

83 lines
2.0 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import '../base_component.dart';
import '../component.dart';
import '../../extensions/offset.dart';
import '../../game/base_game.dart';
mixin Tapable on BaseComponent {
bool onTapCancel() {
return true;
}
bool onTapDown(TapDownDetails details) {
return true;
}
bool onTapUp(TapUpDetails details) {
return true;
}
int _currentPointerId;
bool _checkPointerId(int pointerId) => _currentPointerId == pointerId;
bool handleTapDown(int pointerId, TapDownDetails details) {
if (containsPoint(details.localPosition.toVector2())) {
_currentPointerId = pointerId;
return onTapDown(details);
}
return true;
}
bool handleTapUp(int pointerId, TapUpDetails details) {
if (_checkPointerId(pointerId) &&
containsPoint(details.localPosition.toVector2())) {
_currentPointerId = null;
return onTapUp(details);
}
return true;
}
bool handleTapCancel(int pointerId) {
if (_checkPointerId(pointerId)) {
_currentPointerId = null;
return onTapCancel();
}
return true;
}
}
mixin HasTapableComponents on BaseGame {
void _handleTapEvent(bool Function(Tapable child) tapEventHandler) {
for (Component c in components.toList().reversed) {
bool shouldContinue = true;
if (c is BaseComponent) {
shouldContinue = c.propagateToChildren<Tapable>(tapEventHandler);
}
if (c is Tapable && shouldContinue) {
shouldContinue = tapEventHandler(c);
}
if (!shouldContinue) {
break;
}
}
}
@mustCallSuper
void onTapCancel(int pointerId) {
_handleTapEvent((Tapable child) => child.handleTapCancel(pointerId));
}
@mustCallSuper
void onTapDown(int pointerId, TapDownDetails details) {
_handleTapEvent((Tapable child) => child.handleTapDown(pointerId, details));
}
@mustCallSuper
void onTapUp(int pointerId, TapUpDetails details) {
_handleTapEvent((Tapable child) => child.handleTapUp(pointerId, details));
}
}