June 6, 2016♦
from random import random
from pygame.mixer import Sound
from _send.pgfw.GameChild import GameChild
class Track(GameChild):
def __init__(self, parent, path, volume):
GameChild.__init__(self, parent)
self.path = path
self.volume = volume
self.channel = None
self.frequency = self.get_configuration("title", "pan-frequency")
self.set_sound()
def set_sound(self):
sound = Sound(self.path)
sound.set_volume(self.volume)
self.sound = sound
def play(self):
self.channel = self.sound.play(-1)
def update(self):
if self.channel and random() < self.frequency:
self.parent.set_random_panning(self.channel)
from re import match
from _send.pgfw.GameChild import GameChild
from _send.tartan.Tartan import Tartan
class Tartans(GameChild, dict):
def __init__(self, parent):
GameChild.__init__(self, parent)
self.load()
def load(self):
patterns = file(self.get_resource("tartan", "path"))
while True:
line = patterns.readline()
if not line:
break
name = line.strip()
self[name] = Tartan(self, name, patterns)
from re import match, sub
from itertools import izip, chain
from pygame import Surface, Color, PixelArray
from pygame.image import save
from _send.pgfw.GameChild import GameChild
class Tartan(GameChild, Surface):
def __init__(self, parent, name=None, patterns=None):
GameChild.__init__(self, parent)
self.fields = self.get_game().fields
self.name = name
self.load_configuration()
if patterns is not None:
self.load(patterns)
self.init_surface(0)
# self.generate(store=True)
def load_configuration(self):
config = self.get_configuration("tartan")
self.thread_size = config["thread-size"]
self.sample_size = config["sample-size"]
def load(self, patterns):
self.sett = self.parse_sett(patterns.readline())
self.asymmetric = bool(int(patterns.readline().strip()))
self.palette = self.parse_palette(patterns)
def parse_sett(self, line):
sett = []
size = 0
for stripe in line.strip().split(" "):
identifier, width = match("([A-Z]+)([0-9]+)", stripe).groups(0)
width = int(width)
size += width
sett.append(Stripe(identifier, width))
self.sett_width = size
return sett
def parse_palette(self, patterns):
palette = {}
while True:
line = patterns.readline().strip()
if not line:
break
for color in line.split(";"):
color = color.strip()
if color:
assignment = map(str.strip, color.split("="))
palette[assignment[0]] = Color("#%sFF" % assignment[1][:6])
return palette
def generate(self, scale=None, store=False):
if not scale:
scale = self.get_default_scale()
surface = self.select_surface(scale, store)
self.paint(scale, surface)
if not store:
return surface
def get_default_scale(self):
return self.fields.get(self.name).tartan_scale
def select_surface(self, scale, store):
size = self.get_size(scale)
if store:
self.init_surface(size)
surface = self
else:
surface = Surface((size, size))
return surface
def get_size(self, scale):
sett = self.sett
sett_width = self.sett_width
if not self.asymmetric:
size = scale * (sett_width * 2 - sett[-1].width - sett[0].width)
else:
size = scale * sett_width
return size
def init_surface(self, size):
Surface.__init__(self, (size, size))
def paint(self, scale, surface):
offset, overflow = 0, 0
sett = self.sett
pixels = PixelArray(surface)
for stripe in self.get_stripes_generator(scale):
width = stripe.width
color = self.palette[stripe.identifier]
if overflow:
width -= 1 - overflow
blend = self.blend_colors(previous_color, color, overflow)
self.draw_line(pixels, offset, 1, blend)
offset += 1
if width >= 1:
truncated = int(width)
self.draw_line(pixels, offset, truncated, color)
offset += truncated
overflow = width - truncated
else:
overflow = max(width, 0)
previous_color = color
del pixels
def get_stripes_generator(self, scale):
sett = self.sett
if not self.asymmetric:
return (stripe.get_scaled(scale) for stripe in
chain(sett[:-1], reversed(sett[1:])))
return (stripe.get_scaled(scale) for stripe in sett)
def draw_line(self, pixels, offset, width, color):
thread_size = self.thread_size
operator = thread_size * 2
for y in xrange(offset, min(offset + width, len(pixels[0]))):
for x in xrange(0, len(pixels[0])):
if (x + y) % operator < thread_size:
pixels[x][y] = color
for x in xrange(offset, min(offset + width, len(pixels[0]))):
for y in xrange(0, len(pixels[0])):
if (x + y) % operator >= thread_size:
pixels[x][y] = color
def blend_colors(self, alpha, beta, ratio):
alpha = (component * ratio for component in alpha)
beta = (component * (1 - ratio) for component in beta)
blend = [int(sum(components)) for components in izip(alpha, beta)]
return Color(*blend)
def write_sample(self):
step = self.get_width()
shift = step / 2
count = self.sample_size
size = step * count
offsets = range(-shift, size + step, step)
sample = Surface((size, size))
for x in offsets:
for y in offsets:
sample.blit(self, (x, y))
path = "resource/local/img/tartan/generated/%02i-%s.png" % \
(self.fields.get_index(self.name) + 1,
self.get_filesystem_formatted_name())
save(sample, path)
def get_filesystem_formatted_name(self):
return sub("[^\w-]", "_", self.name.replace(" ", "-"))
class Stripe:
def __init__(self, identifier, width):
self.identifier = identifier
self.width = width
def __repr__(self):
return "<%s at %s (%s %.3f)>" % \
(self.__class__.__name__, hex(id(self)), self.identifier,
self.width)
def get_scaled(self, scale):
return Stripe(self.identifier, self.width * scale)