Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Failing to get a solution to my problem from other people, I got tired of waiting and wrote this (rather rushed) Text class to deal with the text problems I've been having in Pygame. I wanted the text to update itself, so that it would be unnecessary to keep track of its original position. After playing a lot with it, I found this solution:

class Text(object):

    def __init__(self, value, size, color,
                 left_orientation=False,
                 font=None,
                 x=0, y=0,
                 top=None, bottom=None, left=None, right=None,
                 centerx=None, centery=None):

        self._size = size
        self._color = color
        self._value = value
        self._font = pygame.font.Font(font, self._size)
        self.width, self.height = self._font.size(self._value)
        self.left_orientation = left_orientation

        self.image = self._create_surface()
        self.rect = self.image.get_rect()
        if x: self.rect.x = x
        if y: self.rect.y = y
        if top: self.rect.top = top
        if bottom: self.rect.bottom = bottom
        if left: self.rect.left = left
        if right: self.rect.right = right
        if centerx: self.rect.centerx = centerx
        if centery: self.rect.centery = centery

    def _create_surface(self):
        return self._font.render(self._value, True, self._color)

    def set_value(self, new_value):
        if new_value != self._value:
            self._value = new_value
            self.image = self._create_surface()

            new_rect = self.image.get_rect(x = self.rect.x, y = self.rect.y)
            if self.left_orientation:
                width_diff = new_rect.width - self.rect.width
                new_rect.x = self.rect.x - width_diff
            self.rect = new_rect

    def set_position(self, x_or_x_and_y, y=None):
        if y != None:
            self.rect.x = x_or_x_and_y
            self.rect.y = y
        else:
            self.rect.x = x_or_x_and_y[0]
            self.rect.y = x_or_x_and_y[1]

So, if a text is supposed to increase to the left, all that I have to do is initialize a Text object with the left_orientation parameter set to True and, whatever the rect is, it will update itself to remain at it's original position.

Is this a good solution? If not, what would be a better one?

share|improve this question
up vote 3 down vote accepted

This is copied from my answer to your question "What about my Pong game?".

  1. The Text._size member is only used to create the font, so there is no need to store it in the instance.

  2. Why not make Text a subclass of pygame.sprite.Sprite so that you can draw it using a sprite group?

  3. Lots of code is repeated betwen Text.__init__ and Text.set_value. Why not have the former call the latter?

  4. The Text.__init__ constructor takes many keyword arguments, which you then apply to self.rect like this:

    if top: self.rect.top = top
    ...
    

    The first problem is that the test if top: means that you can't set top to zero. You should write something like this:

    if top is not None: self.rect.top = top
    

    But it would be much simpler to use Python's ** keyword argument mechanism to take any number of keyword arguments, and pass them all to Surface.get_rect.

Applying all these improvements yields the following:

class Text(pygame.sprite.Sprite):
    def __init__(self, text, size, color, font=None, **kwargs):
        super(Text, self).__init__()
        self.color = color
        self.font = pygame.font.Font(font, size)
        self.kwargs = kwargs
        self.set(text)

    def set(self, text):
        self.image = self.font.render(str(text), 1, self.color)
        self.rect = self.image.get_rect(**self.kwargs)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.