From e3d92b0eeeaa18c9d695c86787dd3f0dcbe27db2 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Mon, 25 Sep 2017 22:16:19 +0200 Subject: [PATCH] Add the initial implementation --- nyan/__main__.py | 89 +++++++++++++++++++++++++++++++++++++++++++++ nyan/cat/0.png | Bin 0 -> 423 bytes nyan/cat/1.png | Bin 0 -> 430 bytes nyan/cat/2.png | Bin 0 -> 426 bytes nyan/cat/3.png | Bin 0 -> 432 bytes nyan/cat/4.png | Bin 0 -> 426 bytes nyan/cat/5.png | Bin 0 -> 435 bytes nyan/sparkle/0.png | Bin 0 -> 153 bytes nyan/sparkle/1.png | Bin 0 -> 161 bytes nyan/sparkle/2.png | Bin 0 -> 160 bytes nyan/sparkle/3.png | Bin 0 -> 158 bytes nyan/sparkle/4.png | Bin 0 -> 145 bytes 12 files changed, 89 insertions(+) create mode 100644 nyan/__main__.py create mode 100644 nyan/cat/0.png create mode 100644 nyan/cat/1.png create mode 100644 nyan/cat/2.png create mode 100644 nyan/cat/3.png create mode 100644 nyan/cat/4.png create mode 100644 nyan/cat/5.png create mode 100644 nyan/sparkle/0.png create mode 100644 nyan/sparkle/1.png create mode 100644 nyan/sparkle/2.png create mode 100644 nyan/sparkle/3.png create mode 100644 nyan/sparkle/4.png diff --git a/nyan/__main__.py b/nyan/__main__.py new file mode 100644 index 0000000..4a6a1f2 --- /dev/null +++ b/nyan/__main__.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 + +from collections import namedtuple +import math +import os.path as path +import random +import sys +import time +from PIL import Image # Requires the Pillow library + +DISP_WIDTH = 150 +DISP_HEIGHT = 16 + + +tail_colors = [ + (0xff, 0x00, 0x00), + (0xff, 0x99, 0x00), + (0xff, 0xff, 0x00), + (0x00, 0xff, 0x00), + (0x00, 0x99, 0xff), + (0x66, 0x33, 0xff), +] + +def read_image(filename): + img = Image.open(filename) + return img + +anim_cat = [] +for i in range(0, 6): + frame = read_image('%s/cat/%d.png' % (path.dirname(__file__), i)) + assert frame.size[0] == DISP_WIDTH + assert frame.size[1] == DISP_HEIGHT + anim_cat.append(frame) +anim_sparkle = [] +for i in range(0, 5): + frame = read_image('%s/sparkle/%d.png' % (path.dirname(__file__), i)) + anim_sparkle.append(frame) + +class Sparkle(object): + def __init__(self): + half_h = anim_sparkle[0].size[1] // 2 + self.x = random.randint(0, DISP_WIDTH) + self.y = random.randint(half_h, DISP_HEIGHT - half_h) + self.frame_index = 0 + +sparkles = [] +while True: + for anim_frame in anim_cat: + if len(sparkles) < 32: + sparkles.append(Sparkle()) + + frame = bytearray(DISP_WIDTH * DISP_HEIGHT * 3) + + # Render the tail + for x in range(DISP_WIDTH): + for y in range(DISP_HEIGHT): + i = y * DISP_WIDTH + x + t = time.time() + col_y = y - (DISP_HEIGHT // 2 - len(tail_colors) // 2) + int(math.sin(x / 6 + t * math.pi) * 4 * math.sin(t * 8)) + if x < 130 and 0 <= col_y < len(tail_colors): + color = tail_colors[col_y] + else: + color = (0x0f, 0x4d, 0x8f) + frame[i*3:i*3+3] = color + + # Paste animated frame + for i in range(DISP_WIDTH * DISP_HEIGHT): + pix = anim_frame.getpixel((i % DISP_WIDTH, i / DISP_WIDTH)) + if pix[3] != 0: + frame[i*3:i*3+3] = pix[:3] + + # Render and update the sparkles + for sp in 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 < DISP_WIDTH and 0 <= pix_y < DISP_HEIGHT: + i = pix_y * DISP_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 + sparkles = list(filter(lambda sp: sp.frame_index < len(anim_sparkle), sparkles)) + + sys.stdout.buffer.write(frame) + time.sleep(1 / 30) diff --git a/nyan/cat/0.png b/nyan/cat/0.png new file mode 100644 index 0000000000000000000000000000000000000000..97fb7da13b2147d188e84253e090587a708509e4 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^(|}ljgAGW2dC{g0q}YQL70(Y)*K0-AbW|YuPggQP7WbviGSTwCNVHDns~Z6hGg7(J2SB8umX=ucxHac ze9pcrf_orU`|0G9DQx?1iuN_k3N>6;^~y2QhQVWd`)_N@kn-?w zXNEb=KY06Bd|dIDg?nAZr;^8V{%d4b3G}^|)e3E0Wyi?O@I&g-mFbLa`S0Fsotvq# zaG%nHnBs|C>z;~gd9%EJAGnpgVe7dMGRM~L-}klPx%J;GSQ z%do=jcRok@nr!c)1zHg?$;X^-K8sr*vr=%)&4*fw#tgy}ry0*Qb$fWExhAI6T2#t7 zwChlbIgie}dFPF|(o6IzkFV5ee-(Rq?^7pkMM^+h60XX?!{ z3McAWbu9YD%BirrT4+UK%;bR|Nh{5CtXZ5Z-0Ki$cbux_P-o9{tjQhh^n$cg;Cmfw z?}h+`U`-s2BY)}0qQj@d`s7Klcm?s-k;_vdwZgDFG0Mq!Z>_LnF$P=j|B-PgL)5?M Y7i}+xxR2f%`~Uy|07*qoM6N<$f*f?W>i_@% literal 0 HcmV?d00001 diff --git a/nyan/cat/2.png b/nyan/cat/2.png new file mode 100644 index 0000000000000000000000000000000000000000..ebde06f8b2f9e9bb7cf386cea9295e607c08eb32 GIT binary patch literal 426 zcmV;b0agBqP)Y0XIoR zK~!ko?U`L}gfI+*owheBXYw4Wa(bohncN2m1V~s)_X*EPNRS^Pg-@PINJ2%HU!0fz zJ%G9|RQ|AQR1J8_4#A2J)sOCba~9FDJz+$|Z7Ob`xd)fmOucc91FMEA=jFbF%FM*f zX21k(P|LUi*augal6RkBYJw)RhHF??sR^i+2o@#s^}T>qY*1AM*unL(bWhzlV?p+n zs(>-s;1vO2#tMDJpxU**tyEP2obDr7abR*eI=8B=uvNiQYF4IRAFVJzb=q1Q0P%;7 zyTa;dp=E`oC!ctk&U0ynw^t1nfW4hPsZ^~Bb#%{)6){sS-~9N1v=iWa8LI|(8j}cC zVA#(5(n$kO?+y!8T;9N7nVD}w{VOi+3aM58O67Ue)@$#MWyYcvwix(JyB~4%3j+a{ UXEd&oIRF3v07*qoM6N<$f)4wxf&c&j literal 0 HcmV?d00001 diff --git a/nyan/cat/3.png b/nyan/cat/3.png new file mode 100644 index 0000000000000000000000000000000000000000..63c6ea4c4eba790e507a93c0fe6d87ab7d3a2efd GIT binary patch literal 432 zcmV;h0Z;ykP)gJT5vTVsSCId)kA`YNp=!jUB6oDy8yVK^0>} zjBy1FItDeb%YeP}>r%Mc3eylYU<=o@b*TlYjR+P6e0&zLav2N(Q0?IQw{%avaK=*f zPL;t}%HS2LDl?YD_JXxpYE=4Kg%F^sr{@TkBcQ5)J)+|fFcBF#)7~62mIJ5`OIp=h z=v)jyC;_Y6n%|r6d9Bj1{6M9u>-8I_8adR_GabvPq;3=7o=PvPaVm>8w-*|xIsz({ zG2yAuN4{!100sbOe(A`hr%#6&Dz+O~9-rli%vjV6Lvv!3gYmt!G9-+0R~m=q@#MHY aV(150Q-*{8$L}rx0000OKGf0XIoR zK~!ko?U_+-gfI+5$L-#zoXI}Y%ITH1XG%XH5Fi0c_bZu^kWdmp3QsdO2&kSFZ(b+= zUO=@ARebq9ss=k{hhX&%)sOCHLjY7EHsTRIGq$f#f-7!$`rsaStQ@Kkmh%ZJcZa*r zfB^t(4{2JLN9%*TOW`vDs@3ToT*Dfwk_Z+BJiiyPrWh>2_15a1YO3p#RgGmRLX=|g zj?Bi|i;mSWR5={e3txk#x+~aAQdNkQVXMutcyCw}OmmbSx=_F0lDgh UB3wY&4*&oF07*qoM6N<$g011HRR910 literal 0 HcmV?d00001 diff --git a/nyan/cat/5.png b/nyan/cat/5.png new file mode 100644 index 0000000000000000000000000000000000000000..42be713ff932eecb0b0c9c78786f5275febff22a GIT binary patch literal 435 zcmV;k0ZjghP)Cw&pdG4S01F~|FTYSZ@&NMmhPN6bpsz#v*Y~jv3O@~!fv*6p z08pvw;e+>CYHxi_6X!}PwfuDX3}8ieuari}X44^$`KrM*JHu2M$hCSX%3V(I04pe9%L`Hm zu9YlQ04s3j+H=-fAHB)tmWx)1Ab;B4R%&3b_(6CNDhr0W>uP)6{^iyP#|j$W&9^TO d56|u&^aHphi-Z1@)t3MO002ovPDHLkV1nexx1s<5 literal 0 HcmV?d00001 diff --git a/nyan/sparkle/0.png b/nyan/sparkle/0.png new file mode 100644 index 0000000000000000000000000000000000000000..7c9c29f3a8e9ad3e2415f0e7f239177e19b5ee66 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^>>$j+1|*LJg>$j+1|*LJg>$j+1|*LJgy$%j?0VLLKN$GS>$j+1|*LJg>$j+1|*LJg&XcYO#gx4d;{MF){R<9 gE4q#Dx>)isEIBX#P)do}1E`Y0)78&qol`;+06I4#asU7T literal 0 HcmV?d00001