Question

I'm working on a game, and when you lose it basically says game over, but I wanted to change the font, and I don't know how, here's the part of the code I'm focussing on:

def end_game(self):
        """ End the game. """
        end_message = games.Message(value = "You didn't eat the pie, game over!",
                                    size = 70,
                                    color = color.red,
                                    x = games.screen.width/2,
                                    y = games.screen.height/2,
                                    lifetime = 7 * games.screen.fps,
                                    after_death = games.screen.quit)
        games.screen.add(end_message)

what I want is to basically change the font to let's say Calibri

Was it helpful?

Solution

Short Answer

You can't.

Slightly longer answer

LiveWires is designed as a way to start you learning to program. In its attempt to do so, it will try to simplify things for you. At first, a library like LiveWires is helpful: it's doing much of the work for you, letting you concentrate on learning to code (and making a fun game!)

However, at some point such an elaborate system will do things that you might not want it to. In our case, LiveWires is making all text use a "default" font, and it does not appear to give any way to change it.

Even Longer Answer

I was able to determine this by looking at the source code of LiveWires framework itself (it's also written in Python). The LiveWires Message class that you are using inherits from the LiveWires Text class. You can look at the Text class code yourself; it should be in a "livewires" directory in a file called "games.py". I'll show some of the code for the "Text" class below:

class Text(Object, ColourMixin):
    """
    A class for representing text on the screen.

    The reference point of a Text object is the centre of its
    bounding box.
    """

    def __init__(self, screen, x, y, text, size, colour, static=0):

        self.init_text (screen, x, y, text, size, colour, static)

    def init_text (self, screen, x, y, text, size, colour, static=0):
        """
        Arguments:

        screen -- the screen the object is on.
        x -- x-coordinate of centre of bounding box.
        y -- y-coordinate of centre of bounding box.
        text -- the text to display.
        size -- nominal height of the text, in pixels.
        colour -- the colour the text should be.
        """
        if not _have_font:
            raise GameError, "We don't have pygame.font, so can't create text objects"
        self._size = size
        self._colour = colour
        self._text = text
        self._font = pygame.font.Font(None, self._size)
        self._a = 0
        surface = self._create_surface()
        Object.__init__(self, screen, x, y, surface, x_offset=self._x_offset,
                        y_offset=self._y_offset, static=static)
        self.move_to(x,y)

    # There are more methods...

Specifically, I'm looking at this part of the __init__ method...

self._font = pygame.font.Font(None, self._size)
self._a = 0
surface = self._create_surface()

Basically what's going on is every text item in LiveWires is built using a pygame.font.Font object (pygame is the utility that LiveWires uses to actually do a lot of the stuff that it does). LiveWires is using creating the Font object in a specific manner (using None as the first argument) to find a "default" font to use. You can determine what it is using as the default font by doing...

import pygame
print pygame.font.get_default_font()

Getting fonts to work well across different computers can get tricky, so just having all text use a "default" font is a reasonable approach for the authors of the LiveWires source code to take.

You should note that the _font attribute begins with an underscore, which is a convention in Python that basically says "don't play with this!" In other words, it is a bad idea to create the Message object and then try to do...

# Don't do this!
end_message._font = pygame.font.Font('/path/to/my/font/file', size)

While this WOULD replace the font object in the Message class with a different font, if you read the code a bit more, you'd realize that the text had already been rendered in the original (default) font onto a surface; you would be changing the font object too late.

Perhaps there is a solution...

One thing you could try to do is modify the LiveWires code. You could replace the line in the Text class I showed above with...

self._font = pygame.font.Font("/path/to/my/font/file", self._size)

That should load a different font from a font file. Keep in mind that this will changed the font for ALL text in your game, since all text use the same Text class.

If you are planning on changing the LiveWires source code, make sure you keep a copy of the original handy in case you make a mistake and cause the LiveWires source code itself to break.

Building on this solution

If you are able to pull the previous off, then perhaps you could go even further and modify the Text class to allow you to specify the font filename. This would mean you would need to change the Text constructor (the __init__ method) as well as the init_text method. Additionally, any other classes that call these methods (for example, init_text is called from the Message.init_message function in LiveWires).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top