Skip to content

Instantly share code, notes, and snippets.

Created September 18, 2016 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/6411668858edb9991ad25b1135e4b56d to your computer and use it in GitHub Desktop.
Save anonymous/6411668858edb9991ad25b1135e4b56d to your computer and use it in GitHub Desktop.
Custom sdl2.ext.System using attrs
import attr
import sdl2.error
import sdl2.sdlttf
import sdl2.pixels
import sdl2.render
import sdl2.ext
from attr.validators import instance_of
class SDLError(Exception):
"""
This exception indicates that there was an issue with the SDL2 library.
"""
def __init__(self, msg=None):
super(SDLError, self).__init__()
if msg is None:
self.msg = sdl2.error.SDL_GetError()
else:
self.msg = msg
def __str__(self):
return repr(self.msg)
class SDLTTFError(Exception):
"""
This exception indicates that there was an issue with SDL2 TTF.
"""
def __init__(self, msg=None):
super(SDLTTFError, self).__init__()
if msg is None:
self.msg = sdl2.sdlttf.TTF_GetError()
else:
self.msg = msg
def __str__(self):
return repr(self.msg)
@attr.s(slots=True)
class Sprite(object):
x = attr.ib(validator=instance_of(int))
y = attr.ib(validator=instance_of(int))
_width = attr.ib(validator=instance_of(int))
_height = attr.ib(validator=instance_of(int))
_depth = attr.ib(validator=instance_of(int))
_renderer = attr.ib(default=None)
_surface = attr.ib(default=None)
_texture = attr.ib(default=None)
@property
def position(self):
"""
The position of the top-left corner of the Sprite
:return:
"""
return self.x, self.y
@position.setter
def position(self, value):
"""
Set position of the Sprite using its top-left corner.
:param value:
:return:
"""
self.x, self.y = value
@property
def shape(self):
"""
Return the size of the Sprite as tuple.
:return:
"""
return self._width, self._height
@property
def depth(self):
"""
Return the render depth of the Sprite.
:return:
"""
return self._depth
@depth.setter
def depth(self, value):
"""
Set the render depth.
:param value:
:return:
"""
self._depth = value
@property
def surface(self):
return self._surface
@property
def texture(self):
return self._texture
@texture.setter
def texture(self, value):
if self._texture is not None:
sdl2.render.SDL_DestroyTexture(self._texture)
self._texture = value
@texture.deleter
def texture(self):
if self._texture is not None:
sdl2.render.SDL_DestroyTexture(self._texture)
@classmethod
def create(cls, position, shape, depth=0,
renderer=None, pixel_format=sdl2.pixels.SDL_PIXELFORMAT_RGBA8888,
access=sdl2.render.SDL_TEXTUREACCESS_STATIC, bpp=32, masks=(0, 0, 0, 0)):
if renderer is not None:
if isinstance(renderer, sdl2.render.SDL_Renderer):
sdl_renderer = renderer
else:
sdl_renderer = renderer.renderer
tex = sdl2.render.SDL_CreateTexture(
sdl_renderer, pixel_format, access, shape[0], shape[1]
)
if tex is None:
raise SDLError()
return cls(
position[0], position[1], shape[0], shape[1], depth,
texture=tex.contents
)
else:
surf = sdl2.surface.SDL_CreateRGBSurface(
0, shape[0], shape[1], bpp, *masks
)
if surf is None:
raise SDLError()
return cls(
position[0], position[1], shape[0], shape[1], depth,
surface=surf.contents
)
def __del__(self):
"""
Frees the resources bound to the sprite.
:return:
"""
if self._surface is not None:
sdl2.surface.SDL_FreeSurface(self._surface)
self._surface = None
if self._texture is not None:
sdl2.render.SDL_DestroyTexture(self._texture)
self._texture = None
def main():
# Initialise SDL2 and SDL2-TTF
sdl2.ext.init()
if sdl2.sdlttf.TTF_Init() != 0:
raise SDLTTFError()
try:
test_text = "Test string\nWith line breaks."
font_color = sdl2.pixels.SDL_Color(0xff, 0xff, 0xff, 0xff)
font_size = 10
font = sdl2.sdlttf.TTF_OpenFont("Courier New.ttf".encode("utf-8"), font_size)
renderer = sdl2.render.SDL_Renderer()
sprite = Sprite.create((0, 0), (100, 100), renderer=renderer)
if font is None:
raise SDLTTFError()
if len(test_text) > 0:
txt_surface = sdl2.sdlttf.TTF_RenderUTF8_Blended(
font, test_text.encode("utf-8"), font_color
)
if txt_surface is None:
raise SDLTTFError()
txt_texture = sdl2.render.SDL_CreateTextureFromSurface(
renderer, txt_surface
)
if txt_texture is None:
raise SDLError()
sdl2.surface.SDL_FreeSurface(txt_surface.contents)
sprite.texture = txt_texture.contents
finally:
# Close down SDL2
sdl2.ext.quit()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment