pygame / examples_pygame / draw.py

#!/usr/bin/env python

'''
'''

__docformat__ = 'restructuredtext'
__version__ = '$Id$'

import math
import random
import sys

import pygame
from pygame.locals import *

width, height = 640, 480
max_vel = 1.0

random.seed(42)

class Point(object):
    __slots__ = ['pos', 'vel']

    def __init__(self):
        self.pos = [random.randrange(0, width), random.randrange(0, height)]
        self.vel = [(random.random() - 0.5) * max_vel, 
                    (random.random() - 0.5) * max_vel]

class Shape(object):
    def __init__(self, npoints):
        self.points = []
        self.area = None
        for i in range(npoints):
            self.points.append(Point())
        self.color = (random.randint(0, 255),
                      random.randint(0, 255), 
                      random.randint(0, 255))

    def get_points(self):
        return [(int(p.pos[0]), int(p.pos[1])) for p in self.points]

    def update(self, time):
        for point in self.points:
            point.pos[0] += point.vel[0] * time
            point.pos[1] += point.vel[1] * time
            if point.pos[0] >= width or point.pos[0] < 0:
                point.vel[0] *= -1
            if point.pos[1] >= height or point.pos[1] < 0:
                point.vel[1] *= -1

class Rectangle(Shape):
    def __init__(self, width):
        super(Rectangle, self).__init__(2)
        self.width = width

    def draw(self, surface):
        r = Rect(self.get_points())
        r.width -= r.left
        r.height -= r.top
        return pygame.draw.rect(surface, self.color, r, self.width)

class Line(Shape):
    def __init__(self, width):
        super(Line, self).__init__(2)
        self.width = width

    def draw(self, surface):
        return pygame.draw.line(surface, self.color, 
                                self.get_points()[0],
                                self.get_points()[1], self.width)

class AntialiasLine(Shape):
    def __init__(self):
        super(AntialiasLine, self).__init__(2)

    def draw(self, surface):
        return pygame.draw.aaline(surface, self.color, 
                                  self.get_points()[0],
                                  self.get_points()[1])

class Polygon(Shape):
    def __init__(self, width):
        super(Polygon, self).__init__(random.randint(3, 5))
        self.width = width

    def draw(self, surface):
        return pygame.draw.polygon(surface, self.color, 
                                   self.get_points(), self.width)

class Ellipse(Shape):
    def __init__(self, width):
        super(Ellipse, self).__init__(2)
        self.width = width

    def draw(self, surface):
        r = Rect(self.get_points())
        r.width -= r.left
        r.height -= r.top
        r.normalize()
        if self.width * 2 < r.width and self.width * 2 < r.height:
            return pygame.draw.ellipse(surface, self.color, r, self.width)
        return None

class Arc(Shape):
    def __init__(self, width):
        super(Arc, self).__init__(2)
        self.start_angle = random.random() * (math.pi * 2)
        self.stop_angle = random.random() * (math.pi * 2)
        self.d_start_angle = (random.random() - 0.5) * 0.01
        self.d_stop_angle = (random.random() - 0.5) * 0.01
        self.width = width

    def update(self, time):
        super(Arc, self).update(time)
        self.start_angle += time * self.d_start_angle
        self.start_angle = self.start_angle % (math.pi * 2)
        self.stop_angle += time * self.d_stop_angle
        self.stop_angle = self.stop_angle % (math.pi * 2)

    def draw(self, surface):
        r = Rect(self.get_points())
        r.width -= r.left
        r.height -= r.top
        r.normalize()
        if self.width * 2 < r.width and self.width * 2 < r.height:
            return pygame.draw.arc(surface, self.color, r, 
                                   self.start_angle, self.stop_angle, self.width)
        return None

if __name__ == '__main__':
    pygame.init()

    flags = 0
    depth = 24 
    screen = pygame.display.set_mode((width, height), flags, depth)

    shapes = []

    clock = pygame.time.Clock()
    show_clips = False
    quit = False
    paused = False
    while not quit:
        for event in pygame.event.get():
            if event.type == QUIT:
                quit = True
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    quit = True
                elif event.key == K_SPACE:
                    paused = not paused
                elif event.unicode == 'r':
                    shapes.append(Rectangle(1))
                elif event.unicode == 'R':
                    shapes.append(Rectangle(0))
                elif event.unicode == 'l':
                    shapes.append(Line(1))
                elif event.unicode == 'L':
                    shapes.append(Line(4))
                elif event.unicode == 'p':
                    shapes.append(Polygon(1))
                elif event.unicode == 'P':
                    shapes.append(Polygon(0))
                elif event.unicode == 'e':
                    shapes.append(Ellipse(1))
                elif event.unicode == 'E':
                    shapes.append(Ellipse(0))
                elif event.unicode == 'a':
                    shapes.append(AntialiasLine())
                elif event.unicode == 'q':
                    shapes.append(Arc(1))
                elif event.unicode == 'Q':
                    shapes.append(Arc(4))
                elif event.unicode == 'c':
                    screen.fill((0, 0, 0))
                    screen.set_clip(screen.get_clip().inflate(-50, -50))
                elif event.unicode == 'C':
                    screen.set_clip(screen.get_clip().inflate(50, 50))
                elif event.unicode == 'i':
                    show_clips = not show_clips

        time = clock.tick()
        if not paused:
            print >> sys.stderr, 'FPS %03.2f, % 3d shapes\r' % \
                (clock.get_fps(), len(shapes)),
            
            screen.fill((0, 0, 0))

            update_rect = Rect(width, height, -width, -height)
            for shape in shapes:
                shape.update(time)
                if shape.area:
                    update_rect.union_ip(shape.area)
                shape.area = shape.draw(screen)
                if shape.area:
                    update_rect.union_ip(shape.area)
                if show_clips and shape.area:
                    pygame.draw.rect(screen, (255, 0, 0), shape.area, 1)

            if show_clips:
                pygame.display.flip()
            else:
                update_rect.normalize()
                pygame.display.update([update_rect])
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.