From 587598e8c56183c40d930f5c93bde935b795112c Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Sat, 7 Oct 2017 23:03:06 +0200 Subject: [PATCH] Allow frame delays to be overridden --- nyan/nyancat.py | 84 ++++++++++++++++++++++++++----------------------- nyan/pcm.py | 3 ++ 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/nyan/nyancat.py b/nyan/nyancat.py index 56470d6..8898be9 100644 --- a/nyan/nyancat.py +++ b/nyan/nyancat.py @@ -36,53 +36,59 @@ class Nyancat(object): def __init__(self, width, height): self.width = width self.height = height + self.frame_index = 0 self.sparkles = [] def render(self): - for anim_frame in anim_cat: - if len(self.sparkles) < 32: - self.sparkles.append(Sparkle(self.width, self.height)) + self.frame_index = (self.frame_index + 1) % len(anim_cat) + anim_frame = anim_cat[self.frame_index] - frame = bytearray(self.width * self.height * 3) - # Render the background - for i in range(self.width * self.height): - frame[i*3:i*3+3] = background_color + if len(self.sparkles) < 32: + self.sparkles.append(Sparkle(self.width, self.height)) - # Render the tail - for (x, tail_y) in enumerate(self.plot_tail(self.width - 10)): - for (y, color) in enumerate(tail_colors, tail_y - len(tail_colors) // 2): - if 0 <= y < self.height: - i = y * self.width + x - frame[i*3:i*3+3] = color + frame = bytearray(self.width * self.height * 3) + # Render the background + for i in range(self.width * self.height): + frame[i*3:i*3+3] = background_color - # Copy animated frame - for anim_x in range(anim_frame.size[0]): - for anim_y in range(anim_frame.size[1]): - pix = anim_frame.getpixel((anim_x, anim_y)) - if pix[3] != 0: # Test for alpha - x = (self.width - anim_frame.size[0]) + anim_x - y = (self.height // 2 - anim_frame.size[1] // 2) + anim_y - i = ((y * self.width) + x) * 3 - frame[i:i+3] = pix[:3] + # Render the tail + for (x, tail_y) in enumerate(self.plot_tail(self.width - 10)): + for (y, color) in enumerate(tail_colors, tail_y - len(tail_colors) // 2): + if 0 <= y < self.height: + i = y * self.width + x + frame[i*3:i*3+3] = color - # Render and update the sparkles - for sp in self.sparkles: - for x in range(anim_sparkle[0].size[0]): - for y in range(anim_sparkle[0].size[1]): - pix_x = sp.x + x - anim_sparkle[0].size[0] // 2 - pix_y = sp.y + y - anim_sparkle[0].size[1] // 2 - if 0 <= pix_x < self.width and 0 <= pix_y < self.height: - i = pix_y * self.width + pix_x - pix = anim_sparkle[sp.frame_index].getpixel((x, y)) - if pix[3] != 0: - frame[i*3:i*3+3] = pix[:3] - sp.x -= 3 - sp.frame_index += 1 - # Remove expired sparkles - self.sparkles = list(filter(lambda sp: sp.frame_index < len(anim_sparkle), self.sparkles)) + # Copy animated frame + for anim_x in range(anim_frame.size[0]): + for anim_y in range(anim_frame.size[1]): + pix = anim_frame.getpixel((anim_x, anim_y)) + if pix[3] != 0: # Test for alpha + x = (self.width - anim_frame.size[0]) + anim_x + y = (self.height // 2 - anim_frame.size[1] // 2) + anim_y + i = ((y * self.width) + x) * 3 + frame[i:i+3] = pix[:3] - sys.stdout.buffer.write(frame) - time.sleep(1 / 30) + # Render and update the sparkles + for sp in self.sparkles: + for x in range(anim_sparkle[0].size[0]): + for y in range(anim_sparkle[0].size[1]): + pix_x = sp.x + x - anim_sparkle[0].size[0] // 2 + pix_y = sp.y + y - anim_sparkle[0].size[1] // 2 + if 0 <= pix_x < self.width and 0 <= pix_y < self.height: + i = pix_y * self.width + pix_x + pix = anim_sparkle[sp.frame_index].getpixel((x, y)) + if pix[3] != 0: + frame[i*3:i*3+3] = pix[:3] + sp.x -= 3 + sp.frame_index += 1 + # Remove expired sparkles + self.sparkles = list(filter(lambda sp: sp.frame_index < len(anim_sparkle), self.sparkles)) + + sys.stdout.buffer.write(frame) + self.sleep() + + def sleep(self): + time.sleep(1 / 30) def plot_tail(self, width): pass # Virtual diff --git a/nyan/pcm.py b/nyan/pcm.py index 4a0827f..d58e01f 100644 --- a/nyan/pcm.py +++ b/nyan/pcm.py @@ -31,3 +31,6 @@ class NyancatSignal(Nyancat): for x in range(width): amplitude = sum(map(lambda hist: hist[x * WAVE_FACTOR], self.samples_history)) / len(self.samples_history) * 3 yield int((amplitude * .5 - .5) * self.height) + self.height + + def sleep(self): + pass # Handled by a blocking read from the audio source