Title: Static Text Class

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

Description: An animated effect that draws text filled with tv-style static.

Download: static_text.py

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

Comments: This code was super slow until Pete Shinners rewrote the __create_static_surface function - thanks Pete! Usage instructions are in the header comments - you need to keep calling render() on the Static_Text object to make it animate.

Messages: 0


#! /usr/bin/env python

## Static Text - a tv-static-filled text class

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

## This code creates a Static_Text object, which you can use as follows:
## static_obj = Static_Text(text_string, font_object, background_color)
## The arguments are as follows:
## text_string - The text you want to display
## font_object - A font object created with pygame.font.Font()
## background_color - an RBG color tuple. This will be the color of the
##                    area surrounding the text, and can be used as a
##                    colorkey if you want the background to show through.
## Calling static_obj.render() will randomize the static pattern showing
## through the letters in the text string. If you call this function in a
## loop, you get a tv-static effect that looks pretty good.

## Huge thanks to Pete Shinners, without whom this code would have been
## unusably slow.

import pygame,  pygame.font, random

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

class Static_Text:
    static_surface = None
    def __init__(self, text, font_obj, background_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 != BLACK:
            colorkey = BLACK
        else:
            colorkey = WHITE
        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())

        # create our static-filled surface
        self.realwidth = self.text_mask_surface.get_width()
        self.realheight = self.text_mask_surface.get_height()
        self.__create_static_surface()
    
           
    def render(self):
        x_offset = random.randrange(30)-30
        y_offset = random.randrange(30)-30
        for x in range(x_offset, self.realwidth, self.width):
            for y in range(y_offset, self.realheight, self.height):
                self.render_surface.blit(Static_Text.static_surface, (x, y))
        self.render_surface.blit(self.text_mask_surface, (0,0))
        return self.render_surface


    def __create_static_surface(self):
        # The idea here is to create a single static-filled surface, 30
        # pixels high and 30 wide. This static surface will be used for
        # all instances of Static_Text - we blit out a random portion,
        # and use that portion to tile behind the text string. We use
        # local storage for a couple of functions, which gains us
        # initialization speed at the expense of readability. Sorry.
        
        if Static_Text.static_surface: return
        self.width = self.height = 30
        start_time = pygame.time.get_ticks()
        my_surf = pygame.Surface((self.width, self.height), 0)
        colors = my_surf.map_rgb(BLACK), my_surf.map_rgb(WHITE)
        C = random.choice
        S = my_surf.set_at
        yrange = range(self.height)
        for x in range(self.width):
            for y in yrange:
                S((x,y),C(colors)) #no globals or lookups in a tight tight loop
        Static_Text.static_surface = my_surf
    
    
if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((654, 68))

    font = pygame.font.Font(None, 72)
               
    message = Static_Text("Static Text by David Clark", font, (0, 0, 0))
                
    while 1:
        screen.blit(message.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):
                raise SystemExit

Main - Repository - Submit - News

Feedback