SFML community forums
Bindings - other languages => Python => Topic started by: Cheery on January 08, 2011, 06:02:50 pm
-
I wanted to draw 9-patches so I created a class for it by subclassing Drawable so it'd work like usual sprites.
Only later I noticed there's lots of methods for doing transformations with the drawable. How to get them affect my sprite patch?
# -*- coding: utf-8 -*-
from PySFML import sf
class Patch(sf.Drawable):
def __init__(self, image):
sf.Drawable.__init__(self)
self.image = image
width = image.GetWidth()
height = image.GetHeight()
for x in range(1, width):
if image.GetPixel(x, 0).a > 0:
right = x + 1
if image.GetPixel(width - x, 0).a > 0:
left = width - x
for y in range(1, height):
if image.GetPixel(0, y).a > 0:
bottom = y + 1
if image.GetPixel(0, height - y).a > 0:
top = height - y
row = 1, left, right, width
col = 1, top, bottom, height
self.sprites = [sf.Sprite(image) for _ in range(9)]
self.borders = top-1, height-bottom, left-1, width-right
for i in range(9):
x, y = i % 3, i / 3
rect = sf.IntRect(
row[x],
col[y],
row[x+1],
col[y+1]
)
self.sprites[i].SetSubRect(rect)
self.position = 0, 0
self.Resize(width, height)
def Resize(self, width, height):
self.width = width
self.height = height
top, bottom, left, right = self.borders
row = [left, width - left - right, right]
col = [top, height - top - bottom, bottom]
for i in range(9):
x, y = i % 3, i / 3
self.sprites[i].Resize(row[x], col[y])
self.SetPosition(*self.position)
def SetPosition(self, x, y):
self.position = x, y
top, bottom, left, right = self.borders
row = [x, x+left, x+self.width-right]
col = [y, y+top, y+self.height-bottom]
for i in range(9):
x, y = i % 3, i / 3
self.sprites[i].SetPosition(row[x], col[y])
def Render(self, target):
for sprite in self.sprites:
target.Draw(sprite)
-
I just decided to drop sprites and applied little bit of opengl.
# -*- coding: utf-8 -*-
from PySFML import sf
from OpenGL.GL import (
glBegin,
glDisable,
glEnd,
glTexCoord2f,
glTranslatef,
glVertex2f,
GL_TEXTURE_2D,
GL_QUADS,
)
class Patch(sf.Drawable):
def __init__(self, image):
sf.Drawable.__init__(self)
self.SetImage(image)
def SetImage(self, image):
self.image = image
width = image.GetWidth()
height = image.GetHeight()
for x in range(1, width):
if image.GetPixel(x, 0).a > 0:
right = x + 1
if image.GetPixel(width - x, 0).a > 0:
left = width - x
for y in range(1, height):
if image.GetPixel(0, y).a > 0:
bottom = y + 1
if image.GetPixel(0, height - y).a > 0:
top = height - y
row = 1, left, right, width
col = 1, top, bottom, height
self.borders = top-1, height-bottom, left-1, width-right
self.subrects = [
sf.IntRect(
row[i%3],
col[i/3],
row[i%3+1],
col[i/3+1],
)
for i in range(9)
]
self.width = width
self.height = height
def Resize(self, width, height):
self.width = width
self.height = height
def Render(self, target):
image = self.image
width = self.width
height = self.height
top, bottom, left, right = self.borders
row = [0, left, self.width-right, self.width]
col = [0, top, self.height-bottom, self.height]
if image and image.GetWidth() and image.GetHeight():
image.Bind()
for i, subrect in enumerate(self.subrects):
x = i%3
y = i/3
rect = image.GetTexCoords(subrect)
glBegin(GL_QUADS)
glTexCoord2f(rect.Left, rect.Top); glVertex2f(row[x], col[y])
glTexCoord2f(rect.Left, rect.Bottom); glVertex2f(row[x], col[y+1])
glTexCoord2f(rect.Right, rect.Bottom); glVertex2f(row[x+1], col[y+1])
glTexCoord2f(rect.Right, rect.Top); glVertex2f(row[x+1], col[y])
glEnd()
else:
glBegin(GL_QUADS)
glVertex2f(0, 0)
glVertex2f(0, height)
glVertex2f(width, height)
glVertex2f(width, 0)
glEnd()
-
There's no need to inherit Drawable, actually I believe that Laurent didn't intend end-users to do it at all.
-
There's no need to inherit Drawable, actually I believe that Laurent didn't intend end-users to do it at all.
Then he wouldn't write the following in the documentation: ;)
Deriving your own class from sf::Drawable is possible [...]. To create a derived drawable class, all you have to do is to override the virtual Render function.
One of the main benefits of creating your own drawable class is that you can build hierarchies of drawable objects. Indeed, when you draw a drawable inside the Render function of another drawable, the former inherits the transformations and color of the latter and combines them with its own attributes. This way, you can apply global transformations/color to a set of drawables as if it was a single entity.
However, the real problem is not to use Drawable as a base class for drawable objects, but to make everything drawable. A player, a projectile etc. don't have to inherit Drawable, if you separate graphics and logics.