1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
import abc
from ctypes import byref, c_int
from .. import surface, rect, render
from ..stdinc import Uint32
from .err import SDLError
from .surface import subsurface
__all__ = ["Sprite", "SoftwareSprite", "TextureSprite"]
class Sprite(object):
"""A simple 2D object."""
__metaclass__ = abc.ABCMeta
def __init__(self):
"""Creates a new Sprite."""
super(Sprite, self).__init__()
self.x = 0
self.y = 0
self.depth = 0
@property
def position(self):
"""The top-left position of the Sprite as tuple."""
return self.x, self.y
@position.setter
def position(self, value):
"""The top-left position of the Sprite as tuple."""
self.x = value[0]
self.y = value[1]
@property
@abc.abstractmethod
def size(self):
"""The size of the Sprite as tuple."""
return
@property
def area(self):
"""The rectangular area occupied by the Sprite."""
w, h = self.size
return (self.x, self.y, self.x + w, self.y + h)
class SoftwareSprite(Sprite):
"""A simple, visible, pixel-based 2D object using software buffers."""
def __init__(self, imgsurface, free):
"""Creates a new SoftwareSprite."""
super(SoftwareSprite, self).__init__()
self.free = free
if isinstance(imgsurface, surface.SDL_Surface):
self.surface = imgsurface
elif "SDL_Surface" in str(type(imgsurface)):
self.surface = imgsurface.contents
else:
raise TypeError("imgsurface must be an SDL_Surface")
def __del__(self):
"""Releases the bound SDL_Surface, if it was created by the
SoftwareSprite.
"""
imgsurface = getattr(self, "surface", None)
if self.free and imgsurface is not None:
surface.SDL_FreeSurface(imgsurface)
self.surface = None
@property
def size(self):
"""The size of the SoftwareSprite as tuple."""
return self.surface.w, self.surface.h
def subsprite(self, area):
"""Creates another SoftwareSprite from a part of the SoftwareSprite.
The two sprites share pixel data, so if the parent sprite's surface is
not managed by the sprite (free is False), you will need to keep it
alive while the subsprite exists."""
ssurface = subsurface(self.surface, area)
ssprite = SoftwareSprite(ssurface, True)
# Keeps the parent surface alive until subsprite is freed
if self.free:
ssprite._parent = self
return ssprite
def __repr__(self):
return "SoftwareSprite(size=%s, bpp=%d)" % \
(self.size, self.surface.format.contents.BitsPerPixel)
class TextureSprite(Sprite):
"""A simple, visible, texture-based 2D object, using a renderer."""
def __init__(self, texture, free=True):
"""Creates a new TextureSprite."""
super(TextureSprite, self).__init__()
self.texture = texture
flags = Uint32()
access = c_int()
w = c_int()
h = c_int()
ret = render.SDL_QueryTexture(texture, byref(flags), byref(access),
byref(w), byref(h))
if ret == -1:
raise SDLError()
self.free = free
self.angle = 0.0
self.flip = render.SDL_FLIP_NONE
self._size = w.value, h.value
self._center = None
def __del__(self):
"""Releases the bound SDL_Texture."""
if self.free:
if self.texture != None:
render.SDL_DestroyTexture(self.texture)
self.texture = None
@property
def center(self):
"""The center of the TextureSprite as tuple."""
return self._center
@center.setter
def center(self, value):
"""Sets the center of the TextureSprite."""
if value != None:
self._center = rect.SDL_Point(value[0], value[1])
else:
self._center = None
@property
def size(self):
"""The size of the TextureSprite as tuple."""
return self._size
def __repr__(self):
flags = Uint32()
access = c_int()
w = c_int()
h = c_int()
ret = render.SDL_QueryTexture(self.texture, byref(flags),
byref(access), byref(w), byref(h))
if ret == -1:
raise SDLError()
if self.center:
return "TextureSprite(format=%d, access=%d, size=%s, angle=%f, center=%s)" % \
(flags.value, access.value, (w.value, h.value), self.angle,
(self.center.x, self.center.y))
else:
return "TextureSprite(format=%d, access=%d, size=%s, angle=%f)" % \
(flags.value, access.value, (w.value, h.value), self.angle)
|