Title: Linefill Text Module

Author: David Clark (da_clark at shaw.ca)
Submission date: December 04, 2001

Description: An animated effect. The supplied text is filled with a changing pattern of lines.

Download: linefill_text.py

pygame version required: Any
SDL version required: Any
Python version required: Any

Comments: Usage info is in the leading comments. The example script shows off five possible uses for this module; move through them by clicking or hitting a key.

Messages: 0


#! /usr/bin/env python

## Linefill Text - an animated title text effect.

## Submitted for the pygame font contest by David "Futility" Clark

## Objects built from this class are like standard Font.render()-
## generated surfaces, with a funky twist.  Instead of being
## drawn in a single color, the text is filled with rapidly pulsing
## lines flickering in a random pattern.

## 1. Create the text surface - create a Linefill_Text instance,
##    with the following arguments:
##    text - a text string
##    font_obj - a pygame font object, created with pygame.font.Font()
##    background_color - a RGB tuple. This will be the color outside the
##                       actual letters of the rendered text.
##    line_color - the color of the lines drawn inside the characters.
##                 Again, an RGB tuple.
##    line_bg_color - the color of the spaces between the lines, inside
##                    the characters, as an RBG tuple.
## 2. Call render() on the Linefill object to return a surface with the
##    text all filled with funky lines.
## 3. Blit the surface to the screen.
## 4. Repeat steps 2 and 3 to keep the lines changing.

import pygame, pygame.draw, pygame.font, random

class Linefill_Text:
    def __init__(self, text, font_obj, background_color, line_color,
                 line_bg_color):
        self.text = text
        self.font_obj = font_obj
        self.background_color = background_color
        # find an appropriate colorkey for the text blit.
        if self.background_color != (0, 0, 0):
            colorkey = (0, 0, 0)
        else:
            colorkey = (255, 255, 255)
        self.line_color = line_color
        self.line_bg_color = line_bg_color
        self.text_mask_surface = font_obj.render(self.text, 0, colorkey,
                                            self.background_color)
        self.text_mask_surface.set_colorkey(colorkey)
        self.render_surface = pygame.Surface(self.text_mask_surface.get_size())
        # For speed, precache these values for use in __random_edge_pixel()
        self.width = self.text_mask_surface.get_width()
        self.height = self.text_mask_surface.get_height()
        
    def render(self):
        NUMBER_OF_LINES = 25
        self.render_surface.fill(self.line_bg_color)
        for linenum in range(NUMBER_OF_LINES):
            origin = self.__random_edge_pixel()
            dest = self.__random_edge_pixel()
            pygame.draw.line(self.render_surface, self.line_color,
                             origin, dest)
        self.render_surface.blit(self.text_mask_surface, (0,0))
        return self.render_surface

    def __random_edge_pixel(self):
        # We bias in favour of vertical lines (75%), since text surfaces are
        # always wider than they are tall.
        if random.randrange(4) != 0:
            x = random.randrange(self.width)
            y = random.choice((0, self.height))
        else:
            x = random.choice((0, self.width))
            y = random.randrange(self.height)
        return (x, y)
    
if __name__ == '__main__':
    ## As a test, we'll show five different color-combinations.
    ## The user can click or keypress through them.
    
    pygame.init()
    screen = pygame.display.set_mode((680, 68))

    font = pygame.font.Font(None, 72)

    prompts = ("A subtle effect...",
               "... a more pronounced effect...",
               "... barely visible...",
               "... garish...")
               
    messages = (Linefill_Text("Linefill Text by David Clark",
                              font, (64, 0, 0), (255, 0, 0), (192, 0, 0)),
                Linefill_Text("Linefill Text by David Clark",
                              font, (0, 0, 64), (0, 0, 255), (0, 0, 128)),
                Linefill_Text("Linefill Text by David Clark",
                              font, (0, 0, 0), (64, 64, 0), (0, 0, 0)),
                Linefill_Text("Linefill Text by David Clark",
                              font, (255, 0, 0), (0, 255, 0), (0, 0, 255)))

    for effect in range(len(messages)):
        print prompts[effect]
        finished = 0
        while 1:
            screen.blit(messages[effect].render(), (0, 0))
            pygame.display.update()
            pygame.time.delay(10)
            for event in pygame.event.get():
                if event.type in (pygame.QUIT,
                                  pygame.KEYDOWN,
                                  pygame.MOUSEBUTTONDOWN):
                    finished = 1
                    break
            if finished == 1:
                break

    print "...and with a transparent background."
    message = Linefill_Text("Linefill Text by David Clark",
                            font, (64, 0, 0), (255, 0, 0), (192, 0, 0))
    screen.fill((192, 192, 192), (0, 0, 680, 34))
    screen.fill((64, 64, 64), (0, 34, 680, 34))

    while 1:
        my_surface = message.render()
        my_surface.set_colorkey((64, 0, 0))
        screen.blit(my_surface, (0, 0))
        pygame.display.update()
        pygame.time.delay(10)
        for event in pygame.event.get():
            if event.type in (pygame.QUIT,
                              pygame.KEYDOWN,
                              pygame.MOUSEBUTTONDOWN):
                raise SystemExit

Main - Repository - Submit - News

Feedback