Skip to content

Improve SpriteList annotations + color_normalized validation #2067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
32 changes: 22 additions & 10 deletions arcade/sprite_list/sprite_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
gl,
)
from arcade.gl import Texture2D, Program
from arcade.types import Color, RGBA255
from arcade.types import Color, RGBA255, RGBOrANormalized, RGBANormalized
from arcade.gl.types import OpenGlFilter, BlendFunction, PyGLenum
from arcade.gl.buffer import Buffer
from arcade.gl.vertex_array import Geometry
Expand Down Expand Up @@ -252,7 +252,7 @@ def __iter__(self) -> Iterator[SpriteType]:
"""Return an iterable object of sprites."""
return iter(self.sprite_list)

def __getitem__(self, i):
def __getitem__(self, i: int) -> SpriteType:
return self.sprite_list[i]

def __setitem__(self, index: int, sprite: SpriteType) -> None:
Expand Down Expand Up @@ -294,7 +294,7 @@ def visible(self) -> bool:
return self._visible

@visible.setter
def visible(self, value: bool):
def visible(self, value: bool) -> None:
self._visible = value

@property
Expand Down Expand Up @@ -325,20 +325,28 @@ def color(self) -> Color:
return Color.from_normalized(self._color)

@color.setter
def color(self, color: RGBA255):
def color(self, color: RGBA255) -> None:
self._color = Color.from_iterable(color).normalized

@property
def color_normalized(self) -> Tuple[float, float, float, float]:
def color_normalized(self) -> RGBANormalized:
"""
Get or set the spritelist color in normalized form (0.0 -> 1.0 floats).
This property works the same as :py:attr:`~arcade.SpriteList.color`.
"""
return self._color

@color_normalized.setter
def color_normalized(self, value):
self._color = value
def color_normalized(self, value: RGBOrANormalized) -> None:
try:
r, g, b, *_a = value
assert len(_a) <= 1
except (ValueError, AssertionError) as e:
raise ValueError(
"color_normalized must unpack as 3 or 4 float values"
) from e

self._color = r, g, b, _a[0] if _a else 1.0

@property
def alpha(self) -> int:
Expand All @@ -350,7 +358,7 @@ def alpha(self) -> int:
return int(self._color[3] * 255)

@alpha.setter
def alpha(self, value: int):
def alpha(self, value: int) -> None:
# value = clamp(value, 0, 255)
self._color = self._color[0], self._color[1], self._color[2], value / 255

Expand All @@ -367,7 +375,7 @@ def alpha_normalized(self) -> float:
return self._color[3]

@alpha_normalized.setter
def alpha_normalized(self, value: float):
def alpha_normalized(self, value: float) -> None:
# value = clamp(value, 0.0, 1.0)
self._color = self._color[0], self._color[1], self._color[2], value

Expand Down Expand Up @@ -1039,7 +1047,11 @@ def draw(
vertices=self._sprite_index_slots,
)

def draw_hit_boxes(self, color: RGBA255 = (0, 0, 0, 255), line_thickness: float = 1):
def draw_hit_boxes(
self,
color: RGBA255 = (0, 0, 0, 255),
line_thickness: float = 1.0
) -> None:
"""Draw all the hit boxes in this list"""
# NOTE: Find a way to efficiently draw this
for sprite in self.sprite_list:
Expand Down
9 changes: 8 additions & 1 deletion tests/unit/spritelist/test_spritelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,14 @@ def test_color():
sp.alpha = 172
assert sp.alpha == 172
assert sp.alpha_normalized == pytest.approx(172/255, rel=0.01)
sp.alpha_normalized == 1.0

# Setting float RGBA works
sp.color_normalized = 0.1, 0.2, 0.3, 0.4
assert sp.color_normalized == pytest.approx((0.1, 0.2, 0.3, 0.4), rel=0.1)

# Setting float RGB works
sp.color_normalized = 0.5, 0.6, 0.7
assert sp.color_normalized == pytest.approx((0.5, 0.6, 0.7, 1.0), rel=0.1)

# Alpha Normalized
sp.alpha_normalized = 0.5
Expand Down
Loading