Skip to content

Commit 2e11c38

Browse files
committed
tests
1 parent c3efcd1 commit 2e11c38

3 files changed

Lines changed: 140 additions & 6 deletions

File tree

‎pyscroll/group.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass
4-
from typing import TYPE_CHECKING, Any, Optional, cast
4+
from typing import TYPE_CHECKING, Any
55

66
from pygame.rect import FRect, Rect
77
from pygame.sprite import LayeredUpdates, Sprite

‎pyscroll/orthographic.py‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323

2424
Blit2 = tuple[Surface, tuple[int | float, int | float]]
25-
Blit3 = tuple[Surface, tuple[int | float, int | float], int]
2625
ColorRGB = tuple[int, int, int]
2726
ColorRGBA = tuple[int, int, int, int]
2827

@@ -749,13 +748,18 @@ def render_sprites(
749748

750749
blit_list.sort()
751750

752-
draw_list: list[Blit2 | Blit3] = []
751+
normal_blits: list[Blit2] = []
752+
753753
for layer, priority, x, y, order, surf, blend in blit_list:
754754
if surf is None:
755755
continue
756+
756757
if blend is None:
757-
draw_list.append((surf, (x, y)))
758+
# safe for blits()
759+
normal_blits.append((surf, (x, y)))
758760
else:
759-
draw_list.append((surf, (x, y), int(blend)))
761+
# must use individual blit() for blend flags
762+
surface.blit(surf, (x, y), special_flags=int(blend))
760763

761-
surface.blits(draw_list, doreturn=False)
764+
if normal_blits:
765+
surface.blits(normal_blits, doreturn=False)

‎tests/test_sprite_manager.py‎

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import pygame
2+
import pytest
3+
from pygame import Rect, Surface
4+
5+
from pyscroll.data import PyscrollDataAdapter
6+
from pyscroll.orthographic import SpriteRenderer
7+
from pyscroll.quadtree import FastQuadTree
8+
9+
10+
class DummyRenderable:
11+
def __init__(self, rect, surface, layer=0, blendmode=None):
12+
self.rect = rect
13+
self.surface = surface
14+
self.layer = layer
15+
self.blendmode = blendmode
16+
17+
18+
class DummyAdapter(PyscrollDataAdapter):
19+
tile_size = (32, 32)
20+
map_size = (10, 10)
21+
visible_tile_layers = [0, 1]
22+
23+
def __init__(self):
24+
super().__init__()
25+
self._tile = Surface((32, 32))
26+
self._tile.fill((255, 0, 0))
27+
28+
self._animation_map = {}
29+
self._animated_tile = {}
30+
self._tracked_gids = set()
31+
32+
def reload_data(self):
33+
pass
34+
35+
def get_animations(self):
36+
return []
37+
38+
def _get_tile_image(self, x, y, l):
39+
return self._tile
40+
41+
def _get_tile_image_by_id(self, id):
42+
return self._tile
43+
44+
def _get_tile_gid(self, x, y, l):
45+
return 0
46+
47+
48+
@pytest.fixture
49+
def adapter():
50+
pygame.init()
51+
return DummyAdapter()
52+
53+
54+
@pytest.fixture
55+
def quadtree():
56+
rects = [
57+
Rect(0, 0, 32, 32),
58+
Rect(32, 0, 32, 32),
59+
Rect(0, 32, 32, 32),
60+
Rect(32, 32, 32, 32),
61+
]
62+
return FastQuadTree(rects, depth=2)
63+
64+
65+
@pytest.fixture
66+
def renderer(adapter, quadtree):
67+
return SpriteRenderer(adapter, quadtree, tall_sprites=0)
68+
69+
70+
@pytest.fixture
71+
def surface():
72+
return Surface((200, 200))
73+
74+
75+
@pytest.fixture
76+
def tile_view():
77+
return Rect(0, 0, 10, 10)
78+
79+
80+
def test_basic_sprite_blit(renderer, surface, tile_view):
81+
sprite = Surface((20, 20))
82+
sprite.fill((0, 255, 0)) # green
83+
r = DummyRenderable(Rect(50, 50, 20, 20), sprite, layer=1)
84+
renderer.render_sprites(surface, offset=(0, 0), tile_view=tile_view, surfaces=[r])
85+
px = surface.get_at((50, 50))
86+
assert px == (0, 255, 0, 255)
87+
88+
89+
def test_blendmode(renderer, surface, tile_view):
90+
sprite = Surface((20, 20), pygame.SRCALPHA)
91+
sprite.fill((0, 0, 255, 255))
92+
r = DummyRenderable(
93+
Rect(10, 10, 20, 20), sprite, layer=2, blendmode=pygame.BLEND_ADD
94+
)
95+
renderer.render_sprites(surface, offset=(0, 0), tile_view=tile_view, surfaces=[r])
96+
px = surface.get_at((10, 10))
97+
assert px[2] > 0
98+
99+
100+
def test_tile_redraw(renderer, surface, tile_view, adapter):
101+
sprite = Surface((32, 32))
102+
sprite.fill((0, 255, 0))
103+
r = DummyRenderable(Rect(0, 0, 32, 32), sprite, layer=0)
104+
renderer.render_sprites(surface, offset=(0, 0), tile_view=tile_view, surfaces=[r])
105+
px_under = surface.get_at((5, 5))
106+
assert px_under in [(0, 255, 0, 255), (255, 0, 0, 255)]
107+
108+
109+
def test_tall_sprite_damage_region(adapter, quadtree, surface, tile_view):
110+
renderer = SpriteRenderer(adapter, quadtree, tall_sprites=16)
111+
sprite = Surface((32, 32))
112+
sprite.fill((0, 255, 0))
113+
r = DummyRenderable(Rect(0, 0, 32, 32), sprite, layer=0)
114+
renderer.render_sprites(surface, offset=(0, 0), tile_view=tile_view, surfaces=[r])
115+
px = surface.get_at((0, 0))
116+
assert px != (0, 0, 0, 255)
117+
118+
119+
def test_sprite_sorting(renderer, surface, tile_view):
120+
s1 = Surface((20, 20))
121+
s1.fill((255, 0, 0)) # red
122+
s2 = Surface((20, 20))
123+
s2.fill((0, 255, 0)) # green
124+
r1 = DummyRenderable(Rect(10, 10, 20, 20), s1, layer=0)
125+
r2 = DummyRenderable(Rect(10, 10, 20, 20), s2, layer=1)
126+
renderer.render_sprites(
127+
surface, offset=(0, 0), tile_view=tile_view, surfaces=[r1, r2]
128+
)
129+
px = surface.get_at((10, 10))
130+
assert px == (0, 255, 0, 255)

0 commit comments

Comments
 (0)