onCollisionEnd callbacks for Collidable and HitboxShape (#792)

* Add onCollisionEnd for HitboxShape and Collidable

* Add tests for collision callbacks

* Detect multiple collsions with same collidable in test

* Remove unused import

* Break out duplicated code

* Fix formatting

* Use correct hash set

* Update examples/lib/stories/collision_detection/multiple_shapes.dart

Co-authored-by: Erick <erickzanardoo@gmail.com>

* Update examples/lib/stories/collision_detection/multiple_shapes.dart

Co-authored-by: Erick <erickzanardoo@gmail.com>

* Use hashValues instead of _combineHashCodes

* hashValues is order dependent so we need to sort the objects first

* Add section about onCollisionEnd

* Fix missed hashValues

* Use xor instead of hashValues

* Update examples/lib/stories/collision_detection/collision_detection.dart

Co-authored-by: Luan Nico <luanpotter27@gmail.com>

Co-authored-by: Erick <erickzanardoo@gmail.com>
Co-authored-by: Luan Nico <luanpotter27@gmail.com>
This commit is contained in:
Lukas Klingsbo
2021-05-18 16:21:49 +02:00
committed by GitHub
parent 52a0239ab5
commit e4281d6471
11 changed files with 253 additions and 35 deletions

View File

@ -18,9 +18,9 @@ abstract class MyCollidable extends PositionComponent
final delta = Vector2.zero();
double angleDelta = 0;
bool _isDragged = false;
final _activePaint = Paint()..color = Colors.amber;
late final Color _defaultDebugColor = debugColor;
bool _isHit = false;
late final Paint _activePaint;
final Color _defaultColor = Colors.blue.withOpacity(0.8);
final Set<Collidable> _activeCollisions = {};
final ScreenCollidable screenCollidable;
MyCollidable(
@ -34,17 +34,17 @@ abstract class MyCollidable extends PositionComponent
anchor = Anchor.center;
}
@override
Future<void> onLoad() async {
_activePaint = Paint()..color = _defaultColor;
}
@override
void update(double dt) {
super.update(dt);
if (_isDragged) {
return;
}
if (!_isHit) {
debugColor = _defaultDebugColor;
} else {
_isHit = false;
}
delta.setFrom(velocity * dt);
position.add(delta);
angleDelta = dt * rotationSpeed;
@ -63,6 +63,7 @@ abstract class MyCollidable extends PositionComponent
@override
void render(Canvas canvas) {
super.render(canvas);
renderShapes(canvas, paint: _activePaint);
if (_isDragged) {
final localCenter = (size / 2).toOffset();
canvas.drawCircle(localCenter, 5, _activePaint);
@ -71,25 +72,34 @@ abstract class MyCollidable extends PositionComponent
@override
void onCollision(Set<Vector2> intersectionPoints, Collidable other) {
_isHit = true;
final isNew = _activeCollisions.add(other);
if (isNew) {
_activePaint.color = collisionColor(other).withOpacity(0.8);
}
}
@override
void onCollisionEnd(Collidable other) {
_activeCollisions.remove(other);
if (_activeCollisions.isEmpty) {
_activePaint.color = _defaultColor;
}
}
Color collisionColor(Collidable other) {
switch (other.runtimeType) {
case ScreenCollidable:
debugColor = Colors.teal;
break;
return Colors.teal;
case CollidablePolygon:
debugColor = Colors.blue;
break;
return Colors.deepOrange;
case CollidableCircle:
debugColor = Colors.green;
break;
return Colors.green;
case CollidableRectangle:
debugColor = Colors.cyan;
break;
return Colors.cyan;
case CollidableSnowman:
debugColor = Colors.amber;
break;
return Colors.amber;
default:
debugColor = Colors.pink;
return Colors.pink;
}
}
@ -152,20 +162,18 @@ class CollidableCircle extends MyCollidable {
}
class SnowmanPart extends HitboxCircle {
static const startColor = Colors.white;
final hitPaint = Paint()
..color = startColor
..strokeWidth = 1
..style = PaintingStyle.stroke;
final startColor = Colors.blue.withOpacity(0.8);
final hitPaint = Paint();
SnowmanPart(double definition, Vector2 relativeOffset, Color hitColor)
: super(definition: definition) {
this.relativeOffset.setFrom(relativeOffset);
hitPaint..color = startColor;
onCollision = (Set<Vector2> intersectionPoints, HitboxShape other) {
if (other.component is ScreenCollidable) {
hitPaint..color = startColor;
} else {
hitPaint..color = hitColor;
hitPaint.color = hitColor.withOpacity(0.8);
}
};
}
@ -196,9 +204,6 @@ class CollidableSnowman extends MyCollidable {
class MultipleShapes extends BaseGame
with HasCollidables, HasDraggableComponents {
@override
bool debugMode = true;
final TextPaint fpsTextPaint = TextPaint(
config: TextPaintConfig(
color: BasicPalette.white.color,
@ -219,7 +224,7 @@ class MultipleShapes extends BaseGame
add(screenCollidable);
add(snowman);
var totalAdded = 1;
while (totalAdded < 10) {
while (totalAdded < 20) {
lastToAdd = createRandomCollidable(lastToAdd, screenCollidable);
final lastBottomRight =
lastToAdd.toAbsoluteRect().bottomRight.toVector2();