Skip to content

Commit e8394df

Browse files
committed
sprites now have limited support for Texture and Renderer
1 parent d3e1806 commit e8394df

File tree

7 files changed

+101
-50
lines changed

7 files changed

+101
-50
lines changed

buildconfig/stubs/pygame/sprite.pyi

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ from typing import (
1212
Tuple,
1313
TypeVar,
1414
Union,
15+
overload,
1516
)
1617
from typing_extensions import deprecated # added in 3.13
1718

1819
from pygame.rect import FRect, Rect
1920
from pygame.surface import Surface
2021
from pygame.mask import Mask
22+
from pygame._sdl2.video import Renderer, Texture
2123

2224
from ._common import RectValue, Coordinate
2325

@@ -27,9 +29,9 @@ _Group = AbstractGroup[_SpriteSupportsGroup]
2729
# protocol helps with structural subtyping for typevars in sprite group generics
2830
class _SupportsSprite(Protocol):
2931
@property
30-
def image(self) -> Optional[Surface]: ...
32+
def image(self) -> Optional[Union[Surface, Texture]]: ...
3133
@image.setter
32-
def image(self, value: Optional[Surface]) -> None: ...
34+
def image(self, value: Optional[Union[Surface, Texture]]) -> None: ...
3335
@property
3436
def rect(self) -> Optional[Union[FRect, Rect]]: ...
3537
@rect.setter
@@ -61,9 +63,9 @@ class _SupportsDirtySprite(_SupportsSprite, Protocol):
6163
# concrete sprite implementation class
6264
class Sprite(_SupportsSprite):
6365
@property
64-
def image(self) -> Optional[Surface]: ...
66+
def image(self) -> Optional[Union[Surface, Texture]]: ...
6567
@image.setter
66-
def image(self, value: Optional[Surface]) -> None: ...
68+
def image(self, value: Optional[Union[Surface, Texture]]) -> None: ...
6769
@property
6870
def rect(self) -> Optional[Union[FRect, Rect]]: ...
6971
@rect.setter
@@ -105,7 +107,7 @@ class _HasRect(Protocol):
105107
# image in addition to rect
106108
class _HasImageAndRect(_HasRect, Protocol):
107109
@property
108-
def image(self) -> Optional[Surface]: ...
110+
def image(self) -> Optional[Union[Surface, Texture]]: ...
109111

110112
# mask in addition to rect
111113
class _HasMaskAndRect(_HasRect, Protocol):
@@ -169,7 +171,10 @@ class AbstractGroup(Generic[_TSprite]):
169171
self, *sprites: Union[_TSprite, AbstractGroup[_TSprite], Iterable[_TSprite]]
170172
) -> bool: ...
171173
def update(self, *args: Any, **kwargs: Any) -> None: ...
174+
@overload
172175
def draw(self, surface: Surface) -> List[Union[FRect, Rect]]: ...
176+
@overload
177+
def draw(self, renderer: Renderer) -> List[Union[FRect, Rect]]: ...
173178
def clear(
174179
self,
175180
surface: Surface,
@@ -181,7 +186,7 @@ class Group(AbstractGroup[_TSprite]):
181186
def __init__(
182187
self, *sprites: Union[_TSprite, AbstractGroup[_TSprite], Iterable[_TSprite]]
183188
) -> None: ...
184-
189+
185190
# these are aliased in the code too
186191
@deprecated("Use `pygame.sprite.Group` instead")
187192
class RenderPlain(Group): ...
@@ -227,7 +232,7 @@ class LayeredUpdates(AbstractGroup[_TSprite]):
227232

228233
class LayeredDirty(LayeredUpdates[_TDirtySprite]):
229234
def __init__(self, *sprites: _TDirtySprite, **kwargs: Any) -> None: ...
230-
def draw(
235+
def draw( # type: ignore[override]
231236
self, surface: Surface, bgd: Optional[Surface] = None
232237
) -> List[Union[FRect, Rect]]: ...
233238
# clear breaks Liskov substitution principle in code

docs/reST/ref/sprite.rst

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ extend those when you add a Sprite or Group class.
5050

5151
Sprites are not thread safe. So lock them yourself if using threads.
5252

53+
.. note:: As of version 2.5.1, you can use ``Sprite`` and ``Group`` with ``Renderer``
54+
and ``Texture`` from ``_sdl2.video``, at least partially. Instead of ``Sprite.image``
55+
needing to be a ``Surface``, it needs to be a ``Texture`` to do this. This behavior
56+
is still very experimental, so please report any weirdness to the developers as an
57+
issue on the ``pygame-ce`` github repository. Also note that ``LayeredDirty.draw``
58+
does not currently work in this manner. Other group types might work, but have not
59+
been thorougly tested.
60+
61+
.. versionchanged:: 2.5.1 ``Sprite`` and ``Group``
62+
have some compatibility with ``_sdl2.video``
63+
5364
.. class:: Sprite
5465

5566
| :sl:`Simple base class for visible game objects.`
@@ -64,24 +75,24 @@ Sprites are not thread safe. So lock them yourself if using threads.
6475
adding the Sprite to Groups. For example:
6576

6677
.. code-block:: python
67-
78+
6879
class Block(pygame.sprite.Sprite):
69-
70-
# Constructor. Pass in the color of the block,
80+
81+
# Constructor. Pass in the color of the block,
7182
# and its x and y position
7283
def __init__(self, color, width, height):
7384
# Call the parent class (Sprite) constructor
74-
pygame.sprite.Sprite.__init__(self)
75-
85+
pygame.sprite.Sprite.__init__(self)
86+
7687
# Create an image of the block, and fill it with a color.
7788
# This could also be an image loaded from the disk.
7889
self.image = pygame.Surface([width, height])
7990
self.image.fill(color)
80-
91+
8192
# Fetch the rectangle object that has the dimensions of the image
8293
# Update the position of this object by setting the values of rect.x and rect.y
83-
self.rect = self.image.get_rect()
84-
94+
self.rect = self.image.get_rect()
95+
8596
.. method:: update
8697

8798
| :sl:`method to control sprite behavior`
@@ -291,14 +302,25 @@ Sprites are not thread safe. So lock them yourself if using threads.
291302
.. method:: draw
292303

293304
| :sl:`blit the Sprite images`
294-
| :sg:`draw(Surface) -> List[Rect]`
305+
| :sg:`draw(Surface) -> List[Union[Rect, FRect]]`
306+
| :sg:`draw(Renderer) -> List[Union[Rect, FRect]]`
295307
296-
Draws the contained Sprites to the Surface argument. This uses the
297-
``Sprite.image`` attribute for the source surface, and ``Sprite.rect``
308+
Draws the contained Sprites to the Surface or _sdl2.video.Renderer argument.
309+
310+
Surface
311+
-------
312+
This uses the ``Sprite.image`` attribute for the source surface, and ``Sprite.rect``
313+
for the position.
314+
315+
Renderer
316+
--------
317+
This uses the ``Sprite.image`` attribute for the source Texture, and ``Sprite.rect``
298318
for the position.
299319

300320
The Group keeps sprites in the order they were added, they will be drawn in this order.
301321

322+
.. versionchanged:: 2.5.1 Now accepts a renderer for use with ``_sdl2.video``
323+
302324
.. ## Group.draw ##
303325
304326
.. method:: clear
@@ -667,17 +689,17 @@ Sprites are not thread safe. So lock them yourself if using threads.
667689
collide_circle_ratio, collide_mask
668690

669691
Example:
670-
692+
671693
.. code-block:: python
672694
673695
# See if the Sprite block has collided with anything in the Group block_list
674696
# The True flag will remove the sprite in block_list
675-
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
676-
697+
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)
698+
677699
# Check the list of colliding sprites, and add one to the score for each one
678700
for block in blocks_hit_list:
679701
score +=1
680-
702+
681703
.. ## pygame.sprite.spritecollide ##
682704
683705
.. function:: collide_rect

src_c/cython/pygame/_sdl2/video.pxd

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ cdef extern from "SDL.h" nogil:
9090
SDL_FPoint position
9191
SDL_Color color
9292
SDL_FPoint tex_coord
93-
93+
9494
ctypedef enum SDL_ScaleMode "_pgsdlScaleMode":
9595
SDL_ScaleModeNearest,
9696
SDL_ScaleModeLinear,
@@ -151,8 +151,8 @@ cdef extern from "SDL.h" nogil:
151151
# https://wiki.libsdl.org/SDL_RenderCopyExF
152152
# https://wiki.libsdl.org/SDL_RenderPresent
153153
int SDL_GetRenderDrawColor(SDL_Renderer* renderer,
154-
Uint8* r,
155-
Uint8* g,
154+
Uint8* r,
155+
Uint8* g,
156156
Uint8* b,
157157
Uint8* a)
158158
int SDL_SetRenderDrawColor(SDL_Renderer* renderer,
@@ -227,7 +227,7 @@ cdef extern from "SDL.h" nogil:
227227
SDL_BlendFactor srcAlphaFactor,
228228
SDL_BlendFactor dstAlphaFactor,
229229
SDL_BlendOperation alphaOperation)
230-
230+
231231
ctypedef enum SDL_BlendOperation:
232232
SDL_BLENDOPERATION_ADD = 0x00000001,
233233
SDL_BLENDOPERATION_SUBTRACT = 0x00000002,
@@ -370,7 +370,7 @@ cdef extern from "SDL.h" nogil:
370370
# https://wiki.libsdl.org/SDL_RenderGetIntegerScale
371371
int SDL_RenderSetScale(SDL_Renderer* renderer,
372372
float scaleX,
373-
float scaleY)
373+
float scaleY)
374374
void SDL_RenderGetScale(SDL_Renderer* renderer,
375375
float* scaleX,
376376
float* scaleY)
@@ -382,7 +382,7 @@ cdef extern from "SDL.h" nogil:
382382
int* h)
383383
int SDL_RenderGetIntegerScale(SDL_Renderer* renderer)
384384

385-
int SDL_VERSION_ATLEAST(int major, int minor, int patch)
385+
int SDL_VERSION_ATLEAST(int major, int minor, int patch)
386386

387387
# https://wiki.libsdl.org/SDL_GetWindowPixelFormat
388388
# https://wiki.libsdl.org/SDL_IntersectRect
@@ -414,7 +414,7 @@ cdef extern from "pygame.h" nogil:
414414
ctypedef class pygame.color.Color [object pgColorObject]:
415415
cdef Uint8 data[4]
416416
cdef Uint8 len
417-
417+
418418
ctypedef enum pgColorHandleFlags:
419419
PG_COLOR_HANDLE_SIMPLE
420420
PG_COLOR_HANDLE_STR
@@ -425,7 +425,11 @@ cdef extern from "pygame.h" nogil:
425425
ctypedef class pygame.rect.Rect [object pgRectObject]:
426426
cdef SDL_Rect r
427427
cdef object weakreflist
428-
428+
429+
ctypedef class pygame.rect.FRect [object pgFRectObject]:
430+
cdef SDL_FRect r
431+
cdef object weakreflist
432+
429433
ctypedef class pygame.window.Window [object pgWindowObject]:
430434
cdef SDL_Window *_win
431435
cdef SDL_bool _is_borrowed
@@ -464,7 +468,7 @@ cdef class Renderer:
464468
cdef int _is_borrowed
465469

466470
cpdef object get_viewport(self)
467-
cpdef object blit(self, object source, Rect dest=*, Rect area=*, int special_flags=*)
471+
cpdef object blit(self, object source, object dest=*, object area=*, int special_flags=*)
468472

469473
cdef class Texture:
470474
cdef SDL_Texture* _tex

0 commit comments

Comments
 (0)