Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
195 lines (155 sloc) 5.64 KB
import random
import pygame
from vector import Vector
from math import radians
from colorsys import hsv_to_rgb
DIM = (800, 600)
ESCAPE_EVENTS = set([pygame.KEYDOWN, pygame.MOUSEMOTION, pygame.MOUSEBUTTONDOWN, pygame.QUIT])
JOINTS = 3
WAIT_TIME = 500 # 10 seconds
class Joint(object):
def __init__(self, length, sharpness = 180):
self.length = length
self.sharpness = sharpness
self.step = random.randrange(-sharpness, sharpness) % 360
self.start = random.randrange(360)
self.angle = self.start
def getPos(self):
return Vector.polar(radians(self.angle), self.length)
def rotate(self):
"""Rotates the joint and returns True if it did a full circle already."""
self.angle = (self.angle + self.step) % 360
return self.angle == self.start
class ShapeDrawer(object):
def __init__(self, surface, pos, size, joints):
self.surface = surface
self.size = size
self.pos = Vector(pos)
self.initJoints(joints)
color = hsv_to_rgb(random.random(), random.random() * 0.6 + 0.2, 1)
self.color = pygame.Color(*[int(v * 255) for v in color])
self.lines = 0
self.total_length = 0
def initJoints(self, count):
sharpness = random.randint(3, 120)
self.joints = []
for _ in xrange(count):
self.joints.append(Joint(self.size / float(count), sharpness))
self.last_point = tuple(self.getPos())
def __iter__(self):
return self
def getPos(self):
return sum((j.getPos() for j in self.joints), self.pos)
def getMaxStep(self):
return max(j.sharpness for j in self.joints)
def next(self):
"""Draws a next line and returns relative line length."""
done = [j.rotate() for j in self.joints]
point = self.getPos()
pygame.draw.aaline(self.surface, self.color, tuple(point), self.last_point)
length = (point - self.last_point).mag()
self.last_point = tuple(point)
self.lines += 1
self.total_length += length
if all(done): # We are done here...
raise StopIteration
return length / self.size
class ShapeFader(object):
"""Shape fading process"""
def __init__(self, surface):
self.surface = surface
self.surface.set_colorkey(None)
self.size = self.surface.get_size()
self.tick = 0
def step(self):
if self.tick % 3 == 0 and self.tick < 300:
rotate(self.surface, self.surface, 3, 1.02)
self.surface.blit(black, (0, 0))
self.tick += 1
def writeStats(drawer):
"""Draws shape stats on a transparent surface"""
sharptext = font.render("Sharpness: %s" % drawer.getMaxStep(), True, (255, 180, 0))
linestext = font.render("Number of lines: %s" % drawer.lines, True, (255, 180, 0))
lengthtext = font.render("Total length: %s" % int(drawer.total_length), True, (255, 180, 0))
avg = int(drawer.total_length) / drawer.lines
averagetext = font.render("Average line length: %s" % avg, True, (255, 180, 0))
surface = pygame.Surface((300, 100))
surface.set_colorkey((0, 0, 0))
surface.blit(sharptext, (20, 20))
surface.blit(linestext, (20, 40))
surface.blit(lengthtext, (20, 60))
surface.blit(averagetext, (20, 80))
return surface
def rotate(surface, source, tick, scale = 1, rate = 2000.0):
"""Rotates surface based on tick and blits it centered."""
angle = (1 - (tick / rate) % 1) * 360
rect = source.get_rect()
rotated = pygame.transform.rotozoom(source, angle, scale)
rect.center = rotated.get_rect().center
surface.blit(rotated, (0, 0), rect)
pygame.init()
screen = pygame.display.set_mode(DIM, pygame.FULLSCREEN)
screen.fill((0, 0, 0))
pygame.event.clear()
pygame.mouse.set_visible(False)
timer = pygame.time.Clock()
font = pygame.font.SysFont('georgia', 13, bold = "True")
black = pygame.Surface(DIM, flags = pygame.SRCALPHA)
black.fill((0, 0, 0, 5))
tick = 0
wait_time = 30
last_shape = None
shape = None
stats = None
drawer = None
running = True
while running:
timer.tick(50)
tick += 1
# Setting...
if wait_time > 0:
# Waiting...
wait_time -= 1
elif drawer:
# Image is being drawed
try:
timemod = drawer.next()
except StopIteration:
# Image done, change state...
stats = writeStats(drawer)
wait_time = WAIT_TIME
rot_start_tick = tick
last_shape = None
drawer = None
else:
wait_time = round(2 * timemod)
else:
if shape:
# Fading last shape
rotate(shape, shape, tick - rot_start_tick)
shape.blit(stats, (0, 0))
last_shape = ShapeFader(shape)
stats = None
# Setting a new drawer...
shape = pygame.Surface(DIM)
shape.set_colorkey((0, 0, 0))
drawer = ShapeDrawer(shape, (400, 300), 300, JOINTS)
wait_time = 20
# Drawing...
if last_shape:
# Blend last shape as background
last_shape.step()
screen.blit(last_shape.surface, (0, 0))
if shape:
if not drawer:
# Rotate
rotate(screen, shape, tick - rot_start_tick)
else:
screen.blit(shape, (0, 0))
if stats:
screen.blit(stats, (0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type in ESCAPE_EVENTS:
pygame.quit()
running = False
Jump to Line
Something went wrong with that request. Please try again.