mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-11-01 01:18:38 +08:00 
			
		
		
		
	addShape -> addHitbox (#882)
This commit is contained in:
		| @ -45,7 +45,7 @@ You can add new shapes to the `Hitbox` just like they are added in the below `Co | |||||||
| The `Collidable` mixin is added to a `PositionComponent` that has a `HitBox` and it is used for | The `Collidable` mixin is added to a `PositionComponent` that has a `HitBox` and it is used for | ||||||
| detecting collisions with other `Collidable`s. If you do not add a shape to your `Hitbox` component | detecting collisions with other `Collidable`s. If you do not add a shape to your `Hitbox` component | ||||||
| it will never collide with anything. If you want the component to have a default rectangular shape | it will never collide with anything. If you want the component to have a default rectangular shape | ||||||
| that fills the size of your component you can simply do `addShape(HitboxRectangle())`. | that fills the size of your component you can simply do `addHitbox(HitboxRectangle())`. | ||||||
|  |  | ||||||
| To make your component collidable you would start off something like this: | To make your component collidable you would start off something like this: | ||||||
|  |  | ||||||
| @ -59,7 +59,7 @@ class MyCollidable extends PositionComponent with Hitbox, Collidable { | |||||||
|       Vector2(0, -1), |       Vector2(0, -1), | ||||||
|       Vector2(-1, 0), |       Vector2(-1, 0), | ||||||
|     ]); |     ]); | ||||||
|     addShape(shape); |     addHitbox(shape); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| @ -165,11 +165,11 @@ There are currently three shapes: [Polygon](#Polygon), [Rectangle](#Rectangle) a | |||||||
| [Cirlce](#Circle). | [Cirlce](#Circle). | ||||||
|  |  | ||||||
| ### HitboxShape | ### HitboxShape | ||||||
| A HitboxShape is a Shape defined from the center position of the component that it is attached to | A `HitboxShape` is a `Shape` defined from the center position of the component that it is attached | ||||||
| and it has the same bounding size and angle as the component. You can set `localPosition` to have | to and it has the same bounding size and angle as the component. You can set `localPosition` to have | ||||||
| the position of the shape deviate from the center of the component. A HitboxShape is the type of | the position of the shape deviate from the center of the component. A `HitboxShape` is the type of | ||||||
| shape that you add to your Hitbox, or Collidable. Usually these types of shapes are the only ones | shape that you add to your `Hitbox`, or `Collidable`. Usually these types of shapes are the only | ||||||
| that you need to use. | ones that you need to use. | ||||||
|  |  | ||||||
| #### HitboxPolygon | #### HitboxPolygon | ||||||
| It should be noted that if you want to use collision detection or `containsPoint` on the `Polygon`, | It should be noted that if you want to use collision detection or `containsPoint` on the `Polygon`, | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ class MovableSquare extends SquareComponent | |||||||
|   late Timer timer; |   late Timer timer; | ||||||
|  |  | ||||||
|   MovableSquare() : super(priority: 1) { |   MovableSquare() : super(priority: 1) { | ||||||
|     addShape(HitboxRectangle()); |     addHitbox(HitboxRectangle()); | ||||||
|     timer = Timer(3.0) |     timer = Timer(3.0) | ||||||
|       ..stop() |       ..stop() | ||||||
|       ..callback = () { |       ..callback = () { | ||||||
| @ -89,7 +89,7 @@ class Rock extends SquareComponent with Hitbox, Collidable, Tappable { | |||||||
|     this.position.setFrom(position); |     this.position.setFrom(position); | ||||||
|     size.setValues(50, 50); |     size.setValues(50, 50); | ||||||
|     paint = unpressedPaint; |     paint = unpressedPaint; | ||||||
|     addShape(HitboxRectangle()); |     addHitbox(HitboxRectangle()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ class MyCollidable extends PositionComponent | |||||||
|           size: Vector2.all(100), |           size: Vector2.all(100), | ||||||
|           anchor: Anchor.center, |           anchor: Anchor.center, | ||||||
|         ) { |         ) { | ||||||
|     addShape(HitboxCircle()); |     addHitbox(HitboxCircle()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
| @ -45,7 +45,7 @@ class MyCollidable extends PositionComponent | |||||||
|   @override |   @override | ||||||
|   void render(Canvas canvas) { |   void render(Canvas canvas) { | ||||||
|     super.render(canvas); |     super.render(canvas); | ||||||
|     renderShapes(canvas); |     renderHitboxes(canvas); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|  | |||||||
| @ -63,7 +63,7 @@ abstract class MyCollidable extends PositionComponent | |||||||
|   @override |   @override | ||||||
|   void render(Canvas canvas) { |   void render(Canvas canvas) { | ||||||
|     super.render(canvas); |     super.render(canvas); | ||||||
|     renderShapes(canvas, paint: _activePaint); |     renderHitboxes(canvas, paint: _activePaint); | ||||||
|     if (_isDragged) { |     if (_isDragged) { | ||||||
|       final localCenter = (size / 2).toOffset(); |       final localCenter = (size / 2).toOffset(); | ||||||
|       canvas.drawCircle(localCenter, 5, _activePaint); |       canvas.drawCircle(localCenter, 5, _activePaint); | ||||||
| @ -134,7 +134,7 @@ class CollidablePolygon extends MyCollidable { | |||||||
|       Vector2(0, -1.0), |       Vector2(0, -1.0), | ||||||
|       Vector2(-0.8, -0.8), |       Vector2(-0.8, -0.8), | ||||||
|     ]); |     ]); | ||||||
|     addShape(shape); |     addHitbox(shape); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -145,7 +145,7 @@ class CollidableRectangle extends MyCollidable { | |||||||
|     Vector2 velocity, |     Vector2 velocity, | ||||||
|     ScreenCollidable screenCollidable, |     ScreenCollidable screenCollidable, | ||||||
|   ) : super(position, size, velocity, screenCollidable) { |   ) : super(position, size, velocity, screenCollidable) { | ||||||
|     addShape(HitboxRectangle()); |     addHitbox(HitboxRectangle()); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -157,7 +157,7 @@ class CollidableCircle extends MyCollidable { | |||||||
|     ScreenCollidable screenCollidable, |     ScreenCollidable screenCollidable, | ||||||
|   ) : super(position, size, velocity, screenCollidable) { |   ) : super(position, size, velocity, screenCollidable) { | ||||||
|     final shape = HitboxCircle(); |     final shape = HitboxCircle(); | ||||||
|     addShape(shape); |     addHitbox(shape); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -196,9 +196,9 @@ class CollidableSnowman extends MyCollidable { | |||||||
|     final top = SnowmanPart(0.4, Vector2(0, -0.8), Colors.red); |     final top = SnowmanPart(0.4, Vector2(0, -0.8), Colors.red); | ||||||
|     final middle = SnowmanPart(0.6, Vector2(0, -0.3), Colors.yellow); |     final middle = SnowmanPart(0.6, Vector2(0, -0.3), Colors.yellow); | ||||||
|     final bottom = SnowmanPart(1.0, Vector2(0, 0.5), Colors.green); |     final bottom = SnowmanPart(1.0, Vector2(0, 0.5), Colors.green); | ||||||
|     addShape(top); |     addHitbox(top); | ||||||
|     addShape(middle); |     addHitbox(middle); | ||||||
|     addShape(bottom); |     addHitbox(bottom); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ | |||||||
|  - Add `SpriteButton.asset` |  - Add `SpriteButton.asset` | ||||||
|  - Add `NineTileBox.asset` |  - Add `NineTileBox.asset` | ||||||
|  - Rename `Camera.cameraSpeed` to `Camera.speed` |  - Rename `Camera.cameraSpeed` to `Camera.speed` | ||||||
|  |  - Rename `addShape` to `addHitbox` in `Hitbox` mixin | ||||||
|  |  | ||||||
| ## [1.0.0-releasecandidate.13] | ## [1.0.0-releasecandidate.13] | ||||||
|  - Fix camera not ending up in the correct position on long jumps |  - Fix camera not ending up in the correct position on long jumps | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ class ScreenCollidable extends PositionComponent | |||||||
|   Future<void> onLoad() async { |   Future<void> onLoad() async { | ||||||
|     await super.onLoad(); |     await super.onLoad(); | ||||||
|     size = gameRef.size; |     size = gameRef.size; | ||||||
|     addShape(HitboxRectangle()); |     addHitbox(HitboxRectangle()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   final _zeroVector = Vector2.zero(); |   final _zeroVector = Vector2.zero(); | ||||||
|  | |||||||
| @ -6,17 +6,19 @@ import '../../geometry/shape.dart'; | |||||||
| import '../position_component.dart'; | import '../position_component.dart'; | ||||||
|  |  | ||||||
| mixin Hitbox on PositionComponent { | mixin Hitbox on PositionComponent { | ||||||
|   final List<HitboxShape> _shapes = <HitboxShape>[]; |   final List<HitboxShape> _hitboxes = <HitboxShape>[]; | ||||||
|  |  | ||||||
|   UnmodifiableListView<HitboxShape> get shapes => UnmodifiableListView(_shapes); |   UnmodifiableListView<HitboxShape> get hitboxes { | ||||||
|  |     return UnmodifiableListView(_hitboxes); | ||||||
|   void addShape(HitboxShape shape) { |  | ||||||
|     shape.component = this; |  | ||||||
|     _shapes.add(shape); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void removeShape(HitboxShape shape) { |   void addHitbox(HitboxShape shape) { | ||||||
|     _shapes.remove(shape); |     shape.component = this; | ||||||
|  |     _hitboxes.add(shape); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void removeHitbox(HitboxShape shape) { | ||||||
|  |     _hitboxes.remove(shape); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /// Checks whether the hitbox represented by the list of [HitboxShape] |   /// Checks whether the hitbox represented by the list of [HitboxShape] | ||||||
| @ -24,11 +26,11 @@ mixin Hitbox on PositionComponent { | |||||||
|   @override |   @override | ||||||
|   bool containsPoint(Vector2 point) { |   bool containsPoint(Vector2 point) { | ||||||
|     return possiblyContainsPoint(point) && |     return possiblyContainsPoint(point) && | ||||||
|         _shapes.any((shape) => shape.containsPoint(point)); |         _hitboxes.any((shape) => shape.containsPoint(point)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void renderShapes(Canvas canvas, {Paint? paint}) { |   void renderHitboxes(Canvas canvas, {Paint? paint}) { | ||||||
|     _shapes.forEach((shape) => shape.render(canvas, paint ?? debugPaint)); |     _hitboxes.forEach((shape) => shape.render(canvas, paint ?? debugPaint)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /// Since this is a cheaper calculation than checking towards all shapes, this |   /// Since this is a cheaper calculation than checking towards all shapes, this | ||||||
|  | |||||||
| @ -158,7 +158,7 @@ abstract class PositionComponent extends BaseComponent { | |||||||
|   @override |   @override | ||||||
|   void renderDebugMode(Canvas canvas) { |   void renderDebugMode(Canvas canvas) { | ||||||
|     if (this is Hitbox) { |     if (this is Hitbox) { | ||||||
|       (this as Hitbox).renderShapes(canvas); |       (this as Hitbox).renderHitboxes(canvas); | ||||||
|     } |     } | ||||||
|     canvas.drawRect(size.toRect(), debugPaint); |     canvas.drawRect(size.toRect(), debugPaint); | ||||||
|     debugTextPaint.render( |     debugTextPaint.render( | ||||||
|  | |||||||
| @ -75,8 +75,8 @@ Set<Vector2> intersections( | |||||||
|   if (!collidableA.possiblyOverlapping(collidableB)) { |   if (!collidableA.possiblyOverlapping(collidableB)) { | ||||||
|     // These collidables can't have any intersection points |     // These collidables can't have any intersection points | ||||||
|     if (hasActiveCollision(collidableA, collidableB)) { |     if (hasActiveCollision(collidableA, collidableB)) { | ||||||
|       for (final shapeA in collidableA.shapes) { |       for (final shapeA in collidableA.hitboxes) { | ||||||
|         for (final shapeB in collidableB.shapes) { |         for (final shapeB in collidableB.hitboxes) { | ||||||
|           _handleShapeCollisionEnd(shapeA, shapeB); |           _handleShapeCollisionEnd(shapeA, shapeB); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @ -86,8 +86,8 @@ Set<Vector2> intersections( | |||||||
|  |  | ||||||
|   final result = <Vector2>{}; |   final result = <Vector2>{}; | ||||||
|   final currentResult = <Vector2>{}; |   final currentResult = <Vector2>{}; | ||||||
|   for (final shapeA in collidableA.shapes) { |   for (final shapeA in collidableA.hitboxes) { | ||||||
|     for (final shapeB in collidableB.shapes) { |     for (final shapeB in collidableB.hitboxes) { | ||||||
|       currentResult.addAll(shapeA.intersections(shapeB)); |       currentResult.addAll(shapeA.intersections(shapeB)); | ||||||
|       if (currentResult.isNotEmpty) { |       if (currentResult.isNotEmpty) { | ||||||
|         result.addAll(currentResult); |         result.addAll(currentResult); | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ class TestBlock extends PositionComponent with Hitbox, Collidable { | |||||||
|           size: size, |           size: size, | ||||||
|         ) { |         ) { | ||||||
|     collidableType = type; |     collidableType = type; | ||||||
|     addShape( |     addHitbox( | ||||||
|       HitboxRectangle(), |       HitboxRectangle(), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ class TestBlock extends PositionComponent with Hitbox, Collidable { | |||||||
|           position: position, |           position: position, | ||||||
|           size: size, |           size: size, | ||||||
|         ) { |         ) { | ||||||
|     addShape(hitbox); |     addHitbox(hitbox); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool hasCollisionWith(Collidable otherCollidable) { |   bool hasCollisionWith(Collidable otherCollidable) { | ||||||
|  | |||||||
| @ -98,7 +98,7 @@ void main() { | |||||||
|         Vector2(-1, 0), |         Vector2(-1, 0), | ||||||
|         Vector2(0, 1), |         Vector2(0, 1), | ||||||
|       ]); |       ]); | ||||||
|       component.addShape(hitbox); |       component.addHitbox(hitbox); | ||||||
|  |  | ||||||
|       final point = component.position + component.size / 4; |       final point = component.position + component.size / 4; | ||||||
|       expect(component.containsPoint(point), true); |       expect(component.containsPoint(point), true); | ||||||
| @ -110,7 +110,7 @@ void main() { | |||||||
|       component.anchor = Anchor.topLeft; |       component.anchor = Anchor.topLeft; | ||||||
|       component.size.setValues(2.0, 2.0); |       component.size.setValues(2.0, 2.0); | ||||||
|       final hitbox = HitboxRectangle(); |       final hitbox = HitboxRectangle(); | ||||||
|       component.addShape(hitbox); |       component.addHitbox(hitbox); | ||||||
|  |  | ||||||
|       expect(component.containsPoint(Vector2(1, 1)), true); |       expect(component.containsPoint(Vector2(1, 1)), true); | ||||||
|       expect(component.containsPoint(Vector2(1, -1)), true); |       expect(component.containsPoint(Vector2(1, -1)), true); | ||||||
| @ -124,7 +124,7 @@ void main() { | |||||||
|       component.anchor = Anchor.bottomRight; |       component.anchor = Anchor.bottomRight; | ||||||
|       component.size.setValues(2.0, 2.0); |       component.size.setValues(2.0, 2.0); | ||||||
|       final hitbox = HitboxRectangle(); |       final hitbox = HitboxRectangle(); | ||||||
|       component.addShape(hitbox); |       component.addHitbox(hitbox); | ||||||
|  |  | ||||||
|       expect(component.containsPoint(Vector2(1, 1)), true); |       expect(component.containsPoint(Vector2(1, 1)), true); | ||||||
|       expect(component.containsPoint(Vector2(1, -1)), true); |       expect(component.containsPoint(Vector2(1, -1)), true); | ||||||
| @ -138,7 +138,7 @@ void main() { | |||||||
|       component.anchor = Anchor.topLeft; |       component.anchor = Anchor.topLeft; | ||||||
|       component.size.setValues(2.0, 2.0); |       component.size.setValues(2.0, 2.0); | ||||||
|       final hitbox = HitboxRectangle(); |       final hitbox = HitboxRectangle(); | ||||||
|       component.addShape(hitbox); |       component.addHitbox(hitbox); | ||||||
|  |  | ||||||
|       expect(component.containsPoint(Vector2(0.0, 0.0)), false); |       expect(component.containsPoint(Vector2(0.0, 0.0)), false); | ||||||
|       expect(component.containsPoint(Vector2(0.9, 0.9)), false); |       expect(component.containsPoint(Vector2(0.9, 0.9)), false); | ||||||
| @ -151,7 +151,7 @@ void main() { | |||||||
|       component.position.setValues(1.0, 1.0); |       component.position.setValues(1.0, 1.0); | ||||||
|       component.anchor = Anchor.topLeft; |       component.anchor = Anchor.topLeft; | ||||||
|       component.size.setValues(2.0, 2.0); |       component.size.setValues(2.0, 2.0); | ||||||
|       component.addShape(HitboxPolygon([ |       component.addHitbox(HitboxPolygon([ | ||||||
|         Vector2(1, 0), |         Vector2(1, 0), | ||||||
|         Vector2(0, -1), |         Vector2(0, -1), | ||||||
|         Vector2(-1, 0), |         Vector2(-1, 0), | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Lukas Klingsbo
					Lukas Klingsbo