diff --git a/arcade/hitbox/base.py b/arcade/hitbox/base.py index 5a9c9f0cc..a860a2d24 100644 --- a/arcade/hitbox/base.py +++ b/arcade/hitbox/base.py @@ -67,6 +67,24 @@ def __call__(self, *args: Any, **kwds: Any) -> Self: """ return self.__class__(*args, **kwds) # type: ignore + def create_bounding_box(self, image: Image) -> PointList: + """ + Create points for a simple bounding box around an image. + This is often used as a fallback if a hit box algorithm + doesn't manage to figure out any reasonable points for + an image. + + :param Image image: The image to create a bounding box for. + :return: A tuple of hit box points. + """ + size = image.size + return ( + (-size[0] / 2, -size[1] / 2), + (size[0] / 2, -size[1] / 2), + (size[0] / 2, size[1] / 2), + (-size[0] / 2, size[1] / 2), + ) + class HitBox: """ diff --git a/arcade/hitbox/bounding_box.py b/arcade/hitbox/bounding_box.py index 3af39a834..b0dfee847 100644 --- a/arcade/hitbox/bounding_box.py +++ b/arcade/hitbox/bounding_box.py @@ -20,10 +20,4 @@ def calculate(self, image: Image, **kwargs) -> PointList: :Returns: List of points """ - size = image.size - return ( - (-size[0] / 2, -size[1] / 2), - (size[0] / 2, -size[1] / 2), - (size[0] / 2, size[1] / 2), - (-size[0] / 2, size[1] / 2), - ) + return self.create_bounding_box(image) diff --git a/arcade/hitbox/pymunk.py b/arcade/hitbox/pymunk.py index b933c7ffc..cca46dbef 100644 --- a/arcade/hitbox/pymunk.py +++ b/arcade/hitbox/pymunk.py @@ -51,7 +51,7 @@ def calculate(self, image: Image, detail: Optional[float] = None, **kwargs) -> P # Trace the image finding all the outlines and holes line_sets = self.trace_image(image) if len(line_sets) == 0: - return tuple() + return self.create_bounding_box(image) # Get the largest line set line_set = self.select_largest_line_set(line_sets) diff --git a/arcade/hitbox/simple.py b/arcade/hitbox/simple.py index d2f39b91d..5d1555dfa 100644 --- a/arcade/hitbox/simple.py +++ b/arcade/hitbox/simple.py @@ -29,7 +29,7 @@ def calculate(self, image: Image, **kwargs) -> PointList: bbox = image.getbbox() # If there is no bounding box the image is empty if bbox is None: - return tuple() + return self.create_bounding_box(image) left_border, top_border, right_border, bottom_border = bbox right_border -= 1 diff --git a/tests/unit/htibox/test_black_image.py b/tests/unit/htibox/test_black_image.py new file mode 100644 index 000000000..78624322b --- /dev/null +++ b/tests/unit/htibox/test_black_image.py @@ -0,0 +1,23 @@ +""" +Test fallback for hitbox creation with empty textures. +""" +from PIL import Image +import arcade + +EXPECTED = ((-50.0, -50.0), (50.0, -50.0), (50.0, 50.0), (-50.0, 50.0)) + + +def test_simple(): + tex = arcade.Texture( + Image.new("RGBA", (100, 100)), + hit_box_algorithm=arcade.hitbox.algo_simple, + ) + assert tex.hit_box_points == EXPECTED + + +def test_pymunk(): + tex = arcade.Texture( + Image.new("RGBA", (100, 100)), + hit_box_algorithm=arcade.hitbox.algo_detailed, + ) + assert tex.hit_box_points == EXPECTED