From 244386280ae79d2e8d16b5eef2f9b77f3264b215 Mon Sep 17 00:00:00 2001 From: yaroslavsokolov Date: Mon, 25 Jan 2021 20:50:18 +0300 Subject: [PATCH 1/2] Reflections commit --- Objects.py | 29 +++++++++++++++++++++- __pycache__/Objects.cpython-38.pyc | Bin 2147 -> 3529 bytes __pycache__/raytracing.cpython-38.pyc | Bin 2725 -> 2990 bytes __pycache__/settings.cpython-38.pyc | Bin 1000 -> 1300 bytes __pycache__/somemath.cpython-38.pyc | Bin 2715 -> 2715 bytes loading/load1.png | Bin 1471 -> 0 bytes loading/load2.png | Bin 1469 -> 0 bytes loading/load3.png | Bin 1485 -> 0 bytes loading/load4.png | Bin 1505 -> 0 bytes loading/load5.png | Bin 1520 -> 0 bytes loading/load6.png | Bin 1533 -> 0 bytes main.py | 33 +++++++++++++++----------- raytracing.py | 19 +++++++++++---- settings.py | 7 +++++- 14 files changed, 68 insertions(+), 20 deletions(-) delete mode 100644 loading/load1.png delete mode 100644 loading/load2.png delete mode 100644 loading/load3.png delete mode 100644 loading/load4.png delete mode 100644 loading/load5.png delete mode 100644 loading/load6.png diff --git a/Objects.py b/Objects.py index fb0a789..47f5392 100644 --- a/Objects.py +++ b/Objects.py @@ -1,5 +1,5 @@ import pygame - +import settings class Scene: def __init__(self, *args): @@ -48,4 +48,31 @@ def __init__(self, center=(0, 0, 0), rotation=(0, 0, 0)): Camera.matrix = None +class LoadingSprite(pygame.sprite.Sprite): + def __init__(self, group): + super().__init__(group) + self.index = 0 + self.image = settings.LOADING[self.index] + self.rect = self.image.get_rect() + + def update(self): + self.index = (self.index + 1) % 6 + self.image = settings.LOADING[self.index] + + +class Text(pygame.sprite.Sprite): + def __init__(self, group, text, pos, size, color): + super().__init__(group) + self.index = 0 + font = pygame.font.Font(None, size) + text = font.render(text, False, color) + self.image = text + self.rect = self.image.get_rect().move(*pos) + + +class Logo(pygame.sprite.Sprite): + def __init__(self, group, pos): + super().__init__(group) + self.image = settings.LOADING[6] + self.rect = self.image.get_rect().move(*pos) diff --git a/__pycache__/Objects.cpython-38.pyc b/__pycache__/Objects.cpython-38.pyc index 392cc77f1a3715f887a27f10aedd471d2732711e..fa7e1197b857181c96dc10298315e24f1bfd42dc 100644 GIT binary patch delta 1442 zcmb7EO>Yxd6n&pFW5*uS$|S17f>ssMq$MpXl!7V<5())HVL`i@&D8Q6EL%xzy_q10 z26>T4uwpYm0Gl04enxj)&kltR?ARm0xi2^vlnqaMckaFK^PY3w9L)c>H2SC6tTVLt z@4|nZ0b>Ug%r=E!6+L?lW0>KaEI$15nBQPV7`e}k+!L`tq>M(S5lKXz@e%om6r#Y? z5Y-TAM0GQV=+a!u`d;7PlW~A#!!(g>9_4Dth2{iuCysJ;!|$+Y{zd-GFJH-T%Kx>x zf~&FYN0^kw+^|?YVt2XWM(hW%G}5Sj7OO{0u~=iRuA1wEw&`tm?+k4(Ps_LbLjc@buW5knbCY?Zk%VSQiDA&US{WwFIaQVX7cY z^Bm`7mA`)b+Vz_oH!9uRYIoBr=%#sM(@tI~ve93{dbC1!?O1?*MEJ-YA zVYWtwc0P}uQHt>f_jt&67iOy|->9YXsi>{}fEl*t3%rr+gOSRZr;9m0Lu$e;F%0GQ<>7kz2C(KxX|V%| zTZ$otKk#ucsXQIDPE}s!{xy|%_|G9-GfVi|)$&|$rZo>Y;DHERVIvGeztw2fKLGJf B8s7i_ delta 181 zcmX>p{aBzrl$V!_0SHPa@g_`UVPJR+;vfTNAjbiSi(P<33PTEG4nq`!J3|Un3UdoX z3Uf146eEzwlEMn)u>yHaKptBPJCMf?g39#7+|(i_pjeRvh>!yjYLokU)p$67Ob%u~5k4M14gg0|AQ=Dv diff --git a/__pycache__/raytracing.cpython-38.pyc b/__pycache__/raytracing.cpython-38.pyc index f0a12e2449924cd7d656e385e38983e7f486f9ac..eba5c5d50bd5538218ef19c0fc37ffac9bbc33cb 100644 GIT binary patch delta 1442 zcmZWpy>A>v6yG=dy|?#a<1fXDjZG5g2u1<}vP}pGDkF&`?-g(IpZoKoJ!D1*xE-fNm=aBxH$#^c1|ecLZd1Z{F|C%=>X09QIS1byKYSKGJ^pk2=w?rsp3-C~ zMbFY#OzF2+3Oz%Xl~G_tfigIgRj#LI&y=-)WIkj)t7prhyTeLTma^p&%1q&&fp$iA zM(>W@(?GlZ`t7H=hW?GU6NUkt01+KYeLS}s;Y2GEAu>^0Mj~)UN3Moa#0Nq41uRdw zTamoBk9SFKN)a}qz>}RDar8;IBV>^M0*5f2t+M$eQA3L^u4D{}1{Ty{0$&e&aFDOT z2oy36lkNvk8PUeIf-CtEiPSI?p!`w;vom{^GP$h@9q7{^2WHro@r~R`x=~}V8459l8o4K;Tg|8;B_?1&ujw;ogn_9Nau z7Sm*>AWsrUeyEiR+1FqgyJ%n+eeCI3M%^`71xA<{%7%>ZU^shdEY==}BA!7VF`v2S z{8bP*vp--)-jWgW!i|21>xN;7P2^6={0*>BEkrkFvQY~DSy zM0xb}-55W-b`s0OBKlnKc9LA@vFN8je1+`^ z$9xGd-^%`Q7mkR-F`-`OdUBWuDj!Z;BxT&*N&+Y8w4zohw{!dY<_=C=lKaJ{E>KuT zt>UZgk6jTAwLwrx1X=!%-^a6qX}3CjuNhs%*`Lyq36yhie(0Z|c$rgnhMkI|JGH+7 DNc=te delta 1251 zcmZ8g%WfP+6s=qRoSuh`?Z|<=Cb8r&K{mujkqNeAVZ@3&WCt%sNOsRu$L{g;^!RoS z#8QupH2Hv-ma@nqN){~Ggatc30tv{f7VNWR&w^W(V351j=hUsotvaV~y`28xOzo>` zHDL7o@wB?LR6eeq-`Sx^FacfG)XcjqfhK@%TU~zt4O?&7Cbot1h&3JI3Xj+oz9b#1p{{Q*}*lzHd({E^O}>G*FexX zquh3wL>LlBJsF`YVJf}bp~U#1Dqh0PN+8p%IQq7qqEv;;520Rs$LEfeBQb18K4rBb#K9EE34}IbM{o$t2I2 zv~nkh5g(CAX_Gv=9qt%S9&?UGz{mMX5BA+<3fp+kzbu)WD}N0oYeC>=+L%} zO7Y6Nx~rUQklfo+PBQ4qSh?At^?54MqZ!K14oI;jQmMw))1*I;(Up=sTb!&n^8<*7x7)+3BHn~B|vbuygP z@IFDK@}CP$H|y_37%5m+fK7gPUGaT7>i$BL?=LnhBF@?vlTTzP-qaaB)lfeHW7HCb zT6K1opqTOBg{7ZY{0=NGQrzHpgGf2%-!uTvQ*Jsszo> sD|(go!X*6PCUxCsew@FYq+-yGR)Mb91;GVXh0-FZgxUiEq!mcGos~(HG{#O3R7FKf zuQ^oa0tg9?`~(ocWW^6?B#wv^D9k2N5A15bnfdnHv1jZf`)$U1l*?rZuJRx6xoaJI zrTw3n0RdVgW$jsw3JTmHPnlqX3j+*cqFG=H8!X|-A(@fcs$0#Wr&X_-2OFFNA`4)^ zP>ZdS7S;TxJY+u8kWP>m!%fAo9Fe1t1s8JQK^_Wi6Z8FH7=ckJ9us4jkHf@qK8fO~ zZtoCW~+qPQht7)8@VSESwv}GjJX*z-*hh95E)xVGb^~sh9vJCV@R9zTeRk z@TsDg)_u-8zYdRP#1_@$U@`P2+6r1Si4c-K@~rTh0@fx1I zBY<6FKH3hyAg9>;f})k!!ke*`-sG1TGK;lJ(%fp)qou4aY9LsIkyw9?j*YPE_6vm# zT_(-aIUaM8-k^6@T&=mLA&=nmSiftm<6hK(K3mj;*2bfKq9^NX({Hq7^={|itL1!f#%NHkMb{*6*c%+4Ysdfc0a0qaMOYIg9lM?9}9v?k;(Q;82IT U)EMjxb?69ny9~EwrUxAU0VEK$DF6Tf delta 478 zcmX|-%Ps^#6o$L1`mVb%W8BAWTrx~%Wg`(nBv@eKmQ*Z+zZWATXsj))dm$yBfmvC4 z5gSjS_tvO0olI5g2%~muiKlf%O!PKD4xg0oF7Q3~Ooo`25vKQz>P$xSSJ@Yvukx&>7Fb1@d`>ie zn5y%2W~&=s+VeD%FdZ@wEs}@~n?jfyRBRIou^Ih}#>j01zkh$(OK!9;^3*5aEc9rn z4QQ@Fc~RBHknK|HsvR-A-kTRMAZ7xDSst+bA} uHx9O>`Vebs$z1f_jHFCWW%bHxWA5_h74Dny3e9(Wt%J)0X6Bo#cN70uj$e-e diff --git a/__pycache__/somemath.cpython-38.pyc b/__pycache__/somemath.cpython-38.pyc index 8f6b8f3eadb27f1fd4a4e481e66078412db26d93..a4116082d4e37c5bb98d2824b030d7a3c4a67632 100644 GIT binary patch delta 20 acmbO&I$M-Gl$V!_0SIoq=G(|UfeQdJO9c!7 delta 20 acmbO&I$M-Gl$V!_0SIo-=H19WfeQdHdj!4! diff --git a/loading/load1.png b/loading/load1.png deleted file mode 100644 index abd282f6071eb884a40b20a6ac3fb3270ca6b765..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1471 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bO2I}#X;^)4C~IxyaaMs(j9#r85lP9 zbN@+XWnf@t2=EDU1&ZIkef#m_$IqTUd;a|S=g*(NfB*jb_wWDz{{y8)!Dt8!?-0oT z`0FgJ`2_>h{7422!Qa_cfw9e5;1OBOz`%DHgc*+Sd;ttZ2~QWt5D)LS6Hn$HHsE31y=3LT|Lw6SWxB3p zNqROc_z;tH{_%nKnjHRuqv}7+Kbr67zEa51xO`gLsz*24;^$>wI;K3O@Rs}he_7j= z?mg#NuR8ba@iU4wN;c(Y@w;ajHh$dTA~3P;PqUGP(2S0wK1}Bhyk8J=W8?w!l$m|H4(Dq{Mj+;mMk~XqgDQ}bS{$ik^ zv_3-cWnzHKzUVtwUi91uKN8w&;v#%LdrG7Hv1y-QCC)q|++kuDI@w0kE>QSK#m;9o zpVm}td}i_R@zPnB=PJdmuoOAvwvM9m|fMe(jAnQJYD@<);T3K0RTV0&fx$6 diff --git a/loading/load2.png b/loading/load2.png deleted file mode 100644 index 8802ded8f05e7ed84e49bb3cdfb741cb26bc45e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1469 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bO2I}#X;^)4C~IxyaaMs(j9#r85lP9 zbN@+XWnf@t2=EDU1&Y6Y`}W&_o=E1vU+C+^yuXFJM2 zp7}ZDW6(zPmu!`+dmNcn__CiR|8H%c^-;OgdDcsRE_Rc{la8&PB`LXQk>pjKxJNwC yqV8O^>6WoM76bIp@#F~Z_+Q;mbW~Fp`HLD;f+jzSAxvXEamT;r;gV-APRbJPr>-r!3v~ z|M#Y=G8wnj1pe&2`7x$q;uC52i}QcB?)#A-w=dK%XS1Q((M9JD-Pyh|^y`dZWj-(6 zXXpB6Z)GcfdQ9@_jLE$gQ?$+;Oq*kOX~tJSnfum#Q^RK5&71R_D@~MRfkC%N$MX-X z?l(!kzLB#g=FA_##X`jfhbQ$+mzb9FCSm3@iS;MHFh{gmiFq5@v|awBb=W}e{b!TA z>wcQ5O1gb4IO+bZ*~T}&0H{&Vhb`s;sIeuI9~UH!O+yk{L}ANzN_OfJ0D_O0zYsol5gVtC6cyq-ON zwc-1-oYhrtGNy&Hons8qd6jdgs4Z8H@9WX_Swbhdt6Yoz^F#Vr3c_nnWPYks&lzm_=e!o_B~c*bA0wpn&* z9PB|oX#ZX&%gGPuU_v{U`E*L(Rjp$o3MA4zr|<+BceBByTj7KdxlTW2E%nLOJNLg7T;JM`L^A z1hbF$_JS1YTQ$cz3Y#a}`~PThU;m(ee#=`gXZ`m_d|s+5CtD=^Iq9 zamW3C*}-Qb^*w?T@$e**9rgh%RQTy%QsBQ=YVPcJ`?~^-rY)FBY!)`{hB1 z@#nJ^YO5@+-K#Cg_@Mbr;Y#5e_k5X|$!CmB3RhIVD7>q?~P0`1$kauV24@|Ni~w&!4}4|Ni^;@Bjb*Kn0^< zGz5lg2>i-9xfz&G7)pZtf`O@hBm;)v@9e6;c;+ndh%9Dc;5!V$jK}j=qyPmaN?apK zg7ec#$`gxH8440J^GfvcQcDy}^bGaP{`zsg00yF`r;B5VhxgkFo<&C#1Xyyj8NdAh ze`F();N+#^JKhxjtWd2#LnNlQiCuYwqi%Zl0z7H}>Oj1}q-*<_mo%BqF<@)D~ jjN?UXD-XEWb=Cf7RZi6BiU^Lr2+DPyu6{1-oD!MlBSEK+1B}!Z)N`mv#O3D+9 zQW**oGxJLH@={9_O!N%(%>Mduz5oVdn5TWZjMDaQmy(F%Oajyee=7hY##UR(cupE zya%OM=k2=A<`;K7DB40IB7=Lm#}B{w2i3Wcp4b-75r1fvn*8g)%Ub4+f(Km7P3s?7 z=pXv({bo)4^_BVsT*qe5JH)YwH(YJQp^g3z9h2uBZu`gb&b0r3Uo6K#UGBTPetZ-N z=yZSJVPWB4Kf$oA)m$*3^LW$F$NwC^$I9Jq@UmfgKKsu$;WHL_Hrp7dR_Iim|Ic*X z|3rLcPIB=vWdpOOKXb23tv8Lcj(N1T?PpK;1L@w6JeylvkA)o0dvxmK2HtS4Yke~s z_q51oG+h6%U7MAK7S|tX_AYj3^3RZYqO$L*MVnR4;=&bI9&7h8ZxxJ|5x;G+ rrZ8s0%Na~ohfGo)&D{4RQ1dU-4M&a4*<~%;KpD}~)z4*}Q$iB}Pb}$R diff --git a/main.py b/main.py index 0881ae3..9ec9cbd 100644 --- a/main.py +++ b/main.py @@ -1,28 +1,33 @@ import pygame from pygame import gfxdraw from settings import * -from somemath import * +from tracersystem import * from raytracing import trace -def retrace(): - screen.fill(BACKGROUND_COLOR) - trace(screen) - pygame.display.flip() - if __name__ == "__main__": pygame.init() screen = pygame.display.set_mode(SIZE) + load_group = pygame.sprite.Group() + load = LoadingSprite(load_group) + crText = Text(load_group, "Thanks for @PatientZero from Habr.com", (70, 5), 24, "white") + title = Text(load_group, "Pygame Ray Tracing", (5, 70), 72, "red") + tutor = Text(load_group, "Press R to trace/retrace image", (5, HEIGHT - 15), 24, "white") + logo = Logo(load_group, (WIDTH / 2 - 60, HEIGHT / 2 - 60)) isRunning = True clock = pygame.time.Clock() - retrace() + for i in range(120): + traced = getEvents(screen, trace) + if traced: + break + screen.fill(BACKGROUND_COLOR) + load_group.draw(screen) + load_group.update() + pygame.display.flip() + clock.tick(10) + if not traced: + retrace(screen, trace) while isRunning: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - isRunning = False - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_r: - retrace() + getEvents(screen, trace) pygame.display.flip() clock.tick(FPS) - pygame.quit() diff --git a/raytracing.py b/raytracing.py index f80ac98..fbd3f89 100644 --- a/raytracing.py +++ b/raytracing.py @@ -1,30 +1,41 @@ import pygame +import sys from pygame import gfxdraw from settings import * from somemath import * from Objects import * - +from tracersystem import * def trace(screen): O = camera.center Camera.matrix = rotMatrix(*degToRad(Camera.rotation)) for x in range(-WIDTH // 2, WIDTH // 2): for y in range(-HEIGHT // 2, HEIGHT // 2): + getEvents(screen, trace) D = toViewport((x, y)) D = rotateCam(D) - color = TraceRay(O, D, 1, inf) + color = TraceRay(O, D, 1, inf, 3) xc, yc = coord((x, y)) gfxdraw.pixel(screen, xc, yc, normalizeRGB(color)) pygame.display.flip() -def TraceRay(O, D, t_min, t_max): +def TraceRay(O, D, t_min, t_max, depth): close_sphere, close_t = ClosestIntersection(O, D, t_min, t_max) if close_sphere == None: return BACKGROUND_COLOR P = sumPV(O, multi(close_t, D)) N = subDot(P, close_sphere.center) N = multi((1 / sqrt(dot(N, N))), N) - return multi(ComputeLighting(P, N, antiV(D), close_sphere.specular), close_sphere.color) + local_color = multi(ComputeLighting(P, N, antiV(D), close_sphere.specular), close_sphere.color) + + r = close_sphere.reflective + if depth <= 0 or r <= 0: + return local_color + + R = ReflectRay(antiV(D), N) + reflected_color = TraceRay(P, R, 0.001, inf, depth - 1) + + return normalizeRGB(sumPV(multi((1 - r), local_color), multi(r, reflected_color))) def ClosestIntersection(O, D, t_min, t_max): close_t = inf diff --git a/settings.py b/settings.py index 3bb7067..3fb29fd 100644 --- a/settings.py +++ b/settings.py @@ -1,10 +1,15 @@ from Objects import * +import os -WIDTH, HEIGHT = SIZE = 300, 300 +WIDTH, HEIGHT = SIZE = 500, 500 viewport_size = 1 Z_PROJECTION = 1 FPS = 30 BACKGROUND_COLOR = (0, 0, 0) +LOADING = tuple(map(pygame.image.load, + map(os.path.abspath, + [f"img/load{i}.png" for i in range(1, 7)] + + [os.path.abspath("img/logo.png")]))) SCENE = Scene( Sphere( From 08b3b646d8d92ee1e1529803b802c1647f8410b7 Mon Sep 17 00:00:00 2001 From: yaroslavsokolov Date: Mon, 25 Jan 2021 20:50:42 +0300 Subject: [PATCH 2/2] Reflections commit --- filereader.py | 0 img/load1.png | Bin 0 -> 1471 bytes img/load2.png | Bin 0 -> 1469 bytes img/load3.png | Bin 0 -> 1485 bytes img/load4.png | Bin 0 -> 1505 bytes img/load5.png | Bin 0 -> 1520 bytes img/load6.png | Bin 0 -> 1533 bytes img/logo.png | Bin 0 -> 4023 bytes tracersystem.py | 18 ++++++++++++++++++ 9 files changed, 18 insertions(+) create mode 100644 filereader.py create mode 100644 img/load1.png create mode 100644 img/load2.png create mode 100644 img/load3.png create mode 100644 img/load4.png create mode 100644 img/load5.png create mode 100644 img/load6.png create mode 100644 img/logo.png create mode 100644 tracersystem.py diff --git a/filereader.py b/filereader.py new file mode 100644 index 0000000..e69de29 diff --git a/img/load1.png b/img/load1.png new file mode 100644 index 0000000000000000000000000000000000000000..abd282f6071eb884a40b20a6ac3fb3270ca6b765 GIT binary patch literal 1471 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bO2I}#X;^)4C~IxyaaMs(j9#r85lP9 zbN@+XWnf@t2=EDU1&ZIkef#m_$IqTUd;a|S=g*(NfB*jb_wWDz{{y8)!Dt8!?-0oT z`0FgJ`2_>h{7422!Qa_cfw9e5;1OBOz`%DHgc*+Sd;ttZ2~QWt5D)LS6Hn$HHsE31y=3LT|Lw6SWxB3p zNqROc_z;tH{_%nKnjHRuqv}7+Kbr67zEa51xO`gLsz*24;^$>wI;K3O@Rs}he_7j= z?mg#NuR8ba@iU4wN;c(Y@w;ajHh$dTA~3P;PqUGP(2S0wK1}Bhyk8J=W8?w!l$m|H4(Dq{Mj+;mMk~XqgDQ}bS{$ik^ zv_3-cWnzHKzUVtwUi91uKN8w&;v#%LdrG7Hv1y-QCC)q|++kuDI@w0kE>QSK#m;9o zpVm}td}i_R@zPnB=PJdmuoOAvwvM9m|fMe(jAnQJYD@<);T3K0RTV0&fx$6 literal 0 HcmV?d00001 diff --git a/img/load2.png b/img/load2.png new file mode 100644 index 0000000000000000000000000000000000000000..8802ded8f05e7ed84e49bb3cdfb741cb26bc45e8 GIT binary patch literal 1469 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bO2I}#X;^)4C~IxyaaMs(j9#r85lP9 zbN@+XWnf@t2=EDU1&Y6Y`}W&_o=E1vU+C+^yuXFJM2 zp7}ZDW6(zPmu!`+dmNcn__CiR|8H%c^-;OgdDcsRE_Rc{la8&PB`LXQk>pjKxJNwC yqV8O^>6WoM76bIp@#F~Z_+Q;mbW~Fp`HLD;f+jzSAxvXEamT;r;gV-APRbJPr>-r!3v~ z|M#Y=G8wnj1pe&2`7x$q;uC52i}QcB?)#A-w=dK%XS1Q((M9JD-Pyh|^y`dZWj-(6 zXXpB6Z)GcfdQ9@_jLE$gQ?$+;Oq*kOX~tJSnfum#Q^RK5&71R_D@~MRfkC%N$MX-X z?l(!kzLB#g=FA_##X`jfhbQ$+mzb9FCSm3@iS;MHFh{gmiFq5@v|awBb=W}e{b!TA z>wcQ5O1gb4IO+bZ*~T}&0H{&Vhb`s;sIeuI9~UH!O+yk{L}ANzN_OfJ0D_O0zYsol5gVtC6cyq-ON zwc-1-oYhrtGNy&Hons8qd6jdgs4Z8H@9WX_Swbhdt6Yoz^F#Vr3c_nnWPYks&lzm_=e!o_B~c*bA0wpn&* z9PB|oX#ZX&%gGPuU_v{U`E*L(Rjp$o3MA4zr|<+BceBByTj7KdxlTW2E%nLOJNLg7T;JM`L^A z1hbF$_JS1YTQ$cz3Y#a}`~PThU;m(ee#=`gXZ`m_d|s+5CtD=^Iq9 zamW3C*}-Qb^*w?T@$e**9rgh%RQTy%QsBQ=YVPcJ`?~^-rY)FBY!)`{hB1 z@#nJ^YO5@+-K#Cg_@Mbr;Y#5e_k5X|$!CmB3RhIVD7>q?~P0`1$kauV24@|Ni~w&!4}4|Ni^;@Bjb*Kn0^< zGz5lg2>i-9xfz&G7)pZtf`O@hBm;)v@9e6;c;+ndh%9Dc;5!V$jK}j=qyPmaN?apK zg7ec#$`gxH8440J^GfvcQcDy}^bGaP{`zsg00yF`r;B5VhxgkFo<&C#1Xyyj8NdAh ze`F();N+#^JKhxjtWd2#LnNlQiCuYwqi%Zl0z7H}>Oj1}q-*<_mo%BqF<@)D~ jjN?UXD-XEWb=Cf7RZi6BiU^Lr2+DPyu6{1-oD!MlBSEK+1B}!Z)N`mv#O3D+9 zQW**oGxJLH@={9_O!N%(%>Mduz5oVdn5TWZjMDaQmy(F%Oajyee=7hY##UR(cupE zya%OM=k2=A<`;K7DB40IB7=Lm#}B{w2i3Wcp4b-75r1fvn*8g)%Ub4+f(Km7P3s?7 z=pXv({bo)4^_BVsT*qe5JH)YwH(YJQp^g3z9h2uBZu`gb&b0r3Uo6K#UGBTPetZ-N z=yZSJVPWB4Kf$oA)m$*3^LW$F$NwC^$I9Jq@UmfgKKsu$;WHL_Hrp7dR_Iim|Ic*X z|3rLcPIB=vWdpOOKXb23tv8Lcj(N1T?PpK;1L@w6JeylvkA)o0dvxmK2HtS4Yke~s z_q51oG+h6%U7MAK7S|tX_AYj3^3RZYqO$L*MVnR4;=&bI9&7h8ZxxJ|5x;G+ rrZ8s0%Na~ohfGo)&D{4RQ1dU-4M&a4*<~%;KpD}~)z4*}Q$iB}Pb}$R literal 0 HcmV?d00001 diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0a58845dd52b7fdcce9ffcf69b77215fea9a44bd GIT binary patch literal 4023 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 literal 0 HcmV?d00001 diff --git a/tracersystem.py b/tracersystem.py new file mode 100644 index 0000000..08ee3c8 --- /dev/null +++ b/tracersystem.py @@ -0,0 +1,18 @@ +import pygame +import sys +from settings import * + +def getEvents(screen, trace): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit(0) + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_r: + retrace(screen, trace) + return True + +def retrace(screen, trace): + screen.fill(BACKGROUND_COLOR) + trace(screen) + pygame.display.flip()