Line data Source code
1 : import 'dart:collection'; 2 : import 'dart:ui'; 3 : 4 : import '../../../extensions.dart'; 5 : import '../../geometry/shape.dart'; 6 : import '../position_component.dart'; 7 : 8 : mixin Hitbox on PositionComponent { 9 : final List<HitboxShape> _hitboxes = <HitboxShape>[]; 10 : 11 2 : UnmodifiableListView<HitboxShape> get hitboxes { 12 4 : return UnmodifiableListView(_hitboxes); 13 : } 14 : 15 3 : void addHitbox(HitboxShape shape) { 16 3 : shape.component = this; 17 6 : _hitboxes.add(shape); 18 : } 19 : 20 0 : void removeHitbox(HitboxShape shape) { 21 0 : _hitboxes.remove(shape); 22 : } 23 : 24 : /// Checks whether the hitbox represented by the list of [HitboxShape] 25 : /// contains the [point]. 26 2 : @override 27 : bool containsPoint(Vector2 point) { 28 2 : return possiblyContainsPoint(point) && 29 8 : _hitboxes.any((shape) => shape.containsPoint(point)); 30 : } 31 : 32 0 : void renderHitboxes(Canvas canvas, {Paint? paint}) { 33 0 : _hitboxes.forEach((shape) => shape.render(canvas, paint ?? debugPaint)); 34 : } 35 : 36 : /// Since this is a cheaper calculation than checking towards all shapes, this 37 : /// check can be done first to see if it even is possible that the shapes can 38 : /// overlap, since the shapes have to be within the size of the component. 39 2 : bool possiblyOverlapping(Hitbox other) { 40 10 : final maxDistance = other.scaledSize.length + scaledSize.length; 41 8 : return other.absoluteCenter.distanceToSquared(absoluteCenter) <= 42 2 : maxDistance * maxDistance; 43 : } 44 : 45 : /// Since this is a cheaper calculation than checking towards all shapes this 46 : /// check can be done first to see if it even is possible that the shapes can 47 : /// contain the point, since the shapes have to be within the size of the 48 : /// component. 49 2 : bool possiblyContainsPoint(Vector2 point) { 50 10 : return absoluteCenter.distanceToSquared(point) <= scaledSize.length2; 51 : } 52 : }