From 82a1cfa7acb34d0ebae50f3539f5c881eea8357d Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Fri, 1 May 2020 17:08:44 -0600 Subject: [PATCH 01/10] Refactored background rendering; added profiling --- homing_missiles.py | 25 ----------- profile/README.md | 9 ++++ profile/terminalfighter_1588373774.prof | Bin 0 -> 130027 bytes profile/terminalfighter_baseline.prof | Bin 0 -> 33938 bytes rifle.py | 25 ----------- terminalfighter.py | 53 ++++++++++++++++++++---- 6 files changed, 54 insertions(+), 58 deletions(-) create mode 100644 profile/README.md create mode 100644 profile/terminalfighter_1588373774.prof create mode 100644 profile/terminalfighter_baseline.prof diff --git a/homing_missiles.py b/homing_missiles.py index 6dcf801..46fa88e 100644 --- a/homing_missiles.py +++ b/homing_missiles.py @@ -103,16 +103,11 @@ def update(self, events): """ def draw(self, screen): - self.draw_background(screen) - self.draw_grid(screen) self.draw_entities(screen) self.draw_target_tags(screen) self.draw_targets(screen) self.targeting_terminal_.draw_terminal(screen) - def draw_background(self, screen): - pygame.draw.rect(screen, BLACK, pygame.Rect((0, 0), screen.get_size())) - def draw_entities(self, screen): self.draw_friendly_projectiles(screen) self.draw_enemy_projectiles(screen) @@ -137,26 +132,6 @@ def draw_main_character(self, screen): main_character.size_) pygame.draw.rect(screen, self.main_character_color_, main_character_rect) - def draw_grid(self, screen): - height = screen.get_height() - width = screen.get_width() - line_separation = 25 - line_width = 1 - - for i in range(line_separation, width, line_separation): - pygame.draw.line(screen, - DARK_GREEN, - (i, 0), - (i, height), - line_width) - - for i in range(line_separation, height, line_separation): - pygame.draw.line(screen, - DARK_GREEN, - (0, i), - (width, i), - line_width) - def draw_target_tags(self, screen): for enemy in self.universe_.enemies(): enemy_color = self.enemy_colors_.get(enemy.get_type(), self.default_enemy_color_) diff --git a/profile/README.md b/profile/README.md new file mode 100644 index 0000000..5a2baa8 --- /dev/null +++ b/profile/README.md @@ -0,0 +1,9 @@ +Profiling +--------- +###Prereqs + +`pip3 install snakeviz` +###How to run +`snakeviz ` + +This will open the profile in your browser \ No newline at end of file diff --git a/profile/terminalfighter_1588373774.prof b/profile/terminalfighter_1588373774.prof new file mode 100644 index 0000000000000000000000000000000000000000..1825c79c8d428811cea45de0ca0f6e7cbb1a2773 GIT binary patch literal 130027 zcmcG137lL-@qZxM+$RZyn?Sh2kpO{kh&zOkKp+=MxWX~a?#{kEGCQ;M%!VwBqFkc< zI0XIzUZ6n%K@9v9MFas6gww1 z>gww1>h5=^3|zO-r)vZ7TesiAUHQuLQpcoS!b-lYyvw9g=cHZQONBzdy%Ls+<*5r* zM_%PS4h!2W_}F$D{$6gK(o#DVrPUxL!P@07U-*M}o@$j$-%SJ8Z8@!{tfm#hwrSnH zz+ap`b;h)Ov8QWlcW>=1l&TKNW{deVve_wvG?oUa_L?$KZN!>3MzU^KAvVa98j#wR z>+TMVLANTc>P^shCQA)R66|-zTR%PNqQM!-^a1H$d3je>(07z z+@D(|lWg2>(zsYpG;H2>L_3~nQ`x^u3Z40`Tv(Wv?JgC<_TIK!IZuk)fug!eHovNp zFLq=*O6}!}0zXN)=KJQX0{`isWNtDHtX+pcuN!tS_}5TX4$ZSfbiH4>k$WOH|s z=Av{ZuS|EMAG`CalI+SB;w0i==__MTFYoqHt7Ir@^Xl6=ts^W~_Uz8JugC@Y^0e+1 zL009p_hCG!Z^C?CuN;6o_yajOpr-WnuRm{2_tNBO=+MQ>8<*+4fSgk_(IFY}RyZ zrz)M9FQTIpLo^HW)b2=vA7)!m*!!f{TP4GO-L1Y~p+aJsX<9ZL7Q;$5ORDo^-f)h& zj!I9rCY*>HU{4ahoe-Yu=rHuwQ~Dj^+KZGv^ozf5yi?1+TO~tEw@ab4qH^u|Hpn2! z%aFVw7-aY(duTH8F$pp^KYHaefB0joWYiw`a{|N+@K>yUeWewhxP3~E*)#IF6)N8e z;wi`zfTubvo6Q$7y0mJe&QtrdR-^zA&06nUAWtcxBE_gAlo=#?W zrZKmy@{sDT?r4;JiXA#8+typjm$Q`;K6OyrH^ZEy*Qvku+WE3O;)v(lYqJi|NQUg0SucC*r*C_^bE*t|%kgkA*=HtRPIg*4 zX-lXhkceiK48&s&K7@}@H;smTF9NFkOl_e+P`6;oqgc|LA8g4tbVd=F`N*z6gJmz)HB*Q6Bcc8Ax^>xwO z)8~FiQdX5? zRh{$h+cJ3ajaJE^qd5_U7qHako#CpU?yNT6U?JqeYhy)#1!IVVN!00UtqriY6)Z@b z0}5d=-=1q|<^1{1Lu zs8UZiNaFmYRw9We&^PT&`X))L;6u1G8$T-BUdWZp*?hS@*A2TS9D={~&3&F>Z?NE_EAQrk*1)WZsn1r?_58$hrrUtZ+w}lTjh(!v>YQ zMtUv4k~Y<_k4!?0o$xuZwmKxLA;B^aTavu(g}fE{-pE7XF+{KX^cu}zyVt6Qds`_Y zoW5(HWG5YOnB#PxS3AJ9(mII}MfFp}#7C={#(}XAyfR6Ook1E~O4pNIqvlc6%ChQ^ zj3qhzjG-YLQn0DOTpysI{>2qo+S&@sAS@*H47e2v_zZ~fI2&ZjK*d#PZ3@9pLV|i7 zzdUfuufwT6hG#K6V5gSKT)a8+Ijz)8{4v~L+DP z^trZn$XD$=7Q_H0wH)>Fp&whZCwpqL$W~8x2WE_P$q(P7ZeS8T@j}mxSFSxU6I}D= z_BU>M_d%IHb)~MeMxTvZjU?43+ct&pZY~t4ghBl@miA=R8@S*#6<6(SBv92>6_w#X zBER))q?b&MN``|#Crn=&L1C^Co|(4B#=L6RnNfw|SQgthRxI0vbps~VGfHX&j7Ivf z5@O;F5n!TkD;!BZFcKaS3@l7MJzS86&yvARf(O2P&gOrq?w^s2x(ua&+KoQbwwhJv zwMOPoXHT)cQYsa+Uxmxs>S)u;*)uTT!OsJ%H2;hZ=y5D5DO(=g))N*gdxphHk;f8q zX%{sTypb{DeD$MlsBeG=ldQ_AkM=@77kQ@Y)kiZ;AnIcsrh@8lIG^&BS+oPu;3f(r zNyW}GG}^EjF2LleEH}d=EGGRZJCcWYBJtNh;_941*spRoGN?wR}Kb<0O*B*STG=VnHac08(LuFzVe{{hyPg4t6HKp!zSK%1n` z=@1H4F>>KVP5^OOhcBW6odnm6Ezf;=Mt?p^=m=!BW<$v7vrczXY`Uwk~p-$`^Ez+7SNn zS4d=zlMEWgBDLwJNUp7HYH2>>=vuU?U{q~w1Z#LAwFZbzroMqqmw@zPt76cz)R#4FwaxI4dKF3P!kV;&UuToY zXW_NW7GTw?Tp`;HXK%O)HrsA2{udVaynhjS;hnB{)GR5k$DbL5o`Bine`Im2p^XO= zW=LlVY;o(t|9thXlc&w!C==L>Ex0Ys%N7*upvcj#G{&Xz_`hI1{x7tuGQOcLv^LZ~ z*p}tn95a7x&p%ovGsP_EYd7O-b+A$Ppkfg_he>ezXDhdb--7D38Bn2J09TRx;gK5+ zV*sW8fIsOZc;ej$pZ)p?8)qbAOFhF#qqJGM3HXXvmNo{g_4wgzsPH_g>hfN-f`5b@5km$&EVOt1vHpAP9 zPP0LoPG{}ss7MV0HzH9PWBYQGjF@7lj0Q}!m^y&)Od^-hYps$&-&0+MTaE?o!?W2! zd3o4r_9C3B27vyFj%hF%mrLy{wC_{Ttaj>fc)VU$)IjLSUGR?@&IWnVLdsO<^D z#8(;WH4ReJAR~yyR20*-7)o~oD7*zSZMotw_MPAI_P}l5X_e8O>=oy)P;OR$~4L{=D zF<3o%s~d5fO&tE*=sABIn2D5hY%wh$mQhKf9DleL?}*r=_liKFSfsVv(RQ^7`)BzH zZ(n-;Uk=GghWyFmbJz>LRvk&Lk5x|&)<_QGv77}rWkGK$L&xfJ!-k;Tge)~swp7Gw zue$(ub{BkeD6ePBi7fBUNDYQ{rL-bn#2BX9`78=nM`&Mid#SV{Os;A^MDuLrEhf5h z7$YiI)ay8B@Ooo|Yl$?AmyrxJ_N86L4H-MgnjlJcmWwHY@L^x&jL)~pATH2=zq)rDLOA!Hc60M_mRa$q)AFnsazs1B7B*K1(RS+rS;&W zF55dJnLhPLFawiT6PRSRyUTJ@cSb>+F{yQHG0jgW(dSKS&~$`9>bclr%mr~U^hAnx$p>fD>Kj2!XCR0MAaTZ0wY$?!DZ3D zLi;_NlulCRoF`iNBjtxRZ-RS{4?Z#K1W*B9H5tOtQajhL4Q0#m^qx|;f)Q>OZC3-? zdME{8+&l$iiMCt#CmOMXO?y&?a;y`Ryl|e0NdFpHs$)j&3nXzL2xqYMj)(o{oXs}L zNQOP5?U6rj0uqM7>9-=kG{^9)=Ik+rro(AyXLqd}nfOj3h^wySmT{amZM3V2q^TEx zzj+5l8*#Nsq~stHd-JjkZZSHd09Fr5T_tB<|>_(WrjgXdW?(Bd+K+M+2{5{Mt#xLsZB<<0qoRXY5fk62 zP6~ljgsR+73OvTfHc9)`Oi+@-{1{BKN;hwvRtk%$$|h_B-@{HM!A;YS`ow-$9R;KF zmiNE*`fpBjYo+t3Y=$0O$aS@K#e>n$d~o2SR}IOaW3=*6EHk(aLoR4w z5E}bnT*eBw8&2Zqv5LhCx0?b4#9HOH-hB~8VpWdAXu1zVFze?BoIQT{I3e>-s2#|9>9MIS&r+Ddt*2=2GKr?0 zU7@=4LUmX6E=%cnj_NoaUz6qbP}W5KqVwEtg6WM9tXt`Wy08eRyDMR((7=4DmzhfK<-r+Uu8GRMdBG z%pP42TUv3l2A7<@hFbJbtQ%CV?X@+Wvqv(zKHG^vW`x#)}UFo~~^JjugG7t+r^32Av2mDFQv%6DiY*9$MO$UmZ#>4fi4;Xf*H) zS0|4-Y_sr>qcVZbpc7b0?aN52Lokn-BH@lGqLX0wPp(*aX&3fiY-UP&yf)X|Dr}Ej z<+UCn9G2B&!`TQK8p_#(NkG@z*aHyLW;037xsFqfJ1(39vC&De(S>)Nx#<>|%5A1k zom<~oMnq!jTXEonD%VhNqiISsGkyY1SvUM(dRw_21M@804C6~D(Ge#E0-HlmGcw7x zxT!`pSMcGHG)|l2#_cd3V0>$fp#%!ZxFLFbp6+AqbPe9Mgyemp0<7CXi~X!4&=(qGS?$@^9yF ze8;)DjAY1HtuCLWx*UN+Ed|7Y5*0{kQZ7k~8|Y1>^}p<0Cc&I9J$lF$ z7+y4y1{)VXnUyn%G)e5h7aFQ3)*>r!3Cpnl!C%g)W@5EVQn8qAflsr*plES4lPqE4 zTVZz9&@s_$zM z%}K*f8%hw5DbTzM0SR7lYfiI@bIPUU6%*Mxl}wUX&NCdAdl(9ty37jCL4W8Z+OXWt z?p$sMAK_|4Y8L;5Orl0WtD0uP^YtwQaw0ur2h7-c+vEu3<0T%Z9Yn z&ntcEEqp{zt|SZ-i42g89n-rLgo%8SOp-P?C7;QWl}eQMm>9Q-e;8I#F@Y$0RT{t~ zYjid%UDvq=9_Yh35Sawq?tNzQ8@tcUNTyHm$SO?BOYo0Qg7{ zU6?XZ?FrJu>wzVqjbn4W3FIDbBf5uYY#~af`k5vp25x<5QG_&{X~yrQ&)A!T_GuBA z+9Z6HCgE6nFpP^sTG3$auh^AL{CJBbW8I+{xCx@o*=$&vItQMHxeL*=vO!qWK8s&~ z{K#-V#72a|zmFzr9nwmIhEj!?oqa`ko%n^4giI4pO_Gp9dpbLLU&CUMr?rX@q*rbx zYM|xbRf9*pKMNzA<$Qj{dJ$DWIm8xeD-0KnUMIn2q}hW=p=aTXT#>*(DR8*FkoWGBX9Q1)ib4DEDV58Moj=9 zNNEC}B*hQu)`4YHVLn$7(j6|t^sAHL^Jm_7!-2i0XCy-=y+n*k}h z#MSs(9UPV;f1hK6k#D#$Y{r&g90H9kxEN4{^GKLA`+U22pHF4Pk*ZJBS${OS1l4#I z)hCnSJ72lzr>_rd%Sa~4?d`mn7sG8T9}vJ8`ioh|??F^BXrp~9f4dI2Y=%QY_w*Cm z`=)nGqmm$fH48Ecj#%{G=H+J(%}54q)#d)oa$C`BhrnONAmiAFagMu)B7IScxh>_? zWA1)$!4)TD0-I5HfGpJHbfnp(hQq{WlFi+wQF9~din&z{ySK6I-bUO^wHwhSb}5tz z1H#^CGnqtQl~|GWtGtJvB%Ty;!!>1|^_+ShOtQ9Z8#J}EOve*P(x2gu*GVwzhCjb> z{GtP}B^6~jlCd=_u>^u-)&S@GS6ZUp(MqOZtbK}W|1B)5#JG!jzFR&TAUTMOGh&U5r zGz2TA$YJk_cwDhXJ_i!3L!p7KlfS-sxC9O@Yz)*4+0a0z&%{t3il zc}vE3B^iJIKU*Wm{y*!C=RLi-H1Z^IGR@9i$eU>rlY|rK+n+k~r@y%b8@fX#{owOg zygMIj1aHOT!F-rNXK?^~Y83a)@$+@Il}T{$*T1ygj~>QpbDQZ?U&Y@czfEA0)%luH zR|oS$@1t-4?aw6;6R|rbL(Mo7HP$+jR9p1Xedy)S!>H0paJvbpKsLNh`p!S`QUv+vr~a9r7pIt#4<7B}il zIO!xCPCBWsQSPQGIW48xp4y}sah}_tPpvamy9RhL$qwI3q+9bdI#h>yyw-~VZ_%GZ zfCrN#z!_m!7U|B5SH1`?CY&LPcWLeS=ri>J+8I<%X}{{m-yf8bjIF+=$KU{(0%pQ^ z-=1rD-yU_Z-9Q=LjHW&p{0LS?JbWy+$caIhjyxv8d-vU2{>MwOVr)hhluclg^}C^m;KsUvm(ova zG}@<=;LrPx`2HuZ2YYOWLvI;A*M7uK7^n|`G=onP;zUNzf*(#w_yyFZlVIC#{$`s8 z9y<)`CCcSa@36PRRuJ9su9PjuoK^;8^lX)hy4o>gv3t--|ino=6IGg`wO z4;VDJ34F5pUHs}R%ekPOiX)EP>DHFX3eZryiZpCOt>hhX0u8ChcX0WHy$McHpZVcK zz^Q*?kxnuDZN_7E624&{@JskdZJJthvNe+%wuYKgJM!2P?!l>v#AkL8TCBsrMf+0d z+|e$g>X2Of={=#M5q&87RVThr$C7*n%2kKpxNF|n-LA-o1PN{7kqzUF{s4A8Pjr}L z9d-#9^xd`7fu|nV?pE!8p`T?u+h}hlq!8tE3^R2a+FK&4hmEj0&rIo!wO=3j$kEuM ziZbd61LDTd*K0dHxX=5G;TAq+)S@j1m99jh4{y!HbAQIk20{H?#U4aQFs zgoz7sw6_kS+c?l_Uqb>fDuvesXz5lZMx4F9Lawn`FD69;F@;IqeM>1!^5jN&O!COG zOj<}LwW3{U1^Hu`N!Q-NJVKP1DIAsG^mWXDF8 z6SM(*vhwC#($Nc7QrJ#S@8XT;-(4KH`D^gc+DxCCVg#WHOtRJnnj^moUWe2=J%LZD z(}P+6I%D1JgvQ{D`^0TKo4_RNOfg_6@Yr--1x?PqXB{X;{<_@|8{Ff17$Sc+d-zo< z>Tz;1ou}2J!{$v&Cn@qRl`KZh|4oD`!XK%UT*zC#sWrCfyKJ%i_ zy?t=T2J}CTb|@y%;^Bx)uJ<5uq zuiY#MFoa;#B3?hKW*4HPudx-f%$P0FCa^8|0YXQr17{YgE}dB-o?siz4*}#VEy1-T z>>nb3=eSI8%v+!9{Q5~{HgA6Y0kfvpnb?4ScTsh;≫3NPg(bJbsuvc>e3oZiCKA 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 bo2;Y(&c-im3bB%f3CN%gD6Z9sjD)4As6RFP}N3 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 JJ=m_@{{fptty};A literal 0 HcmV?d00001 diff --git a/rifle.py b/rifle.py index abd45fc..eb28bb6 100644 --- a/rifle.py +++ b/rifle.py @@ -95,35 +95,10 @@ def update(self, events): """ def draw(self, screen): - self.draw_background(screen) - self.draw_grid(screen) self.draw_entities(screen) self.draw_target_tags(screen) self.targeting_terminal_.draw_terminal(screen) - def draw_background(self, screen): - pygame.draw.rect(screen, BLACK, pygame.Rect((0, 0), screen.get_size())) - - def draw_grid(self, screen): - height = screen.get_height() - width = screen.get_width() - line_separation = 25 - line_width = 1 - - for i in range(line_separation, width, line_separation): - pygame.draw.line(screen, - DARK_GREEN, - (i, 0), - (i, height), - line_width) - - for i in range(line_separation, height, line_separation): - pygame.draw.line(screen, - DARK_GREEN, - (0, i), - (width, i), - line_width) - def draw_entities(self, screen): self.draw_friendly_projectiles(screen) self.draw_enemy_projectiles(screen) diff --git a/terminalfighter.py b/terminalfighter.py index 7a33752..f5b35f0 100644 --- a/terminalfighter.py +++ b/terminalfighter.py @@ -1,7 +1,10 @@ +import cProfile import sys +import time import highscore_service import pygame + from gamemaster import GameMaster from score_counter import ScoreCounter from spawn_controller import SpawnController @@ -14,6 +17,10 @@ GAME_WIDTH = 1000 GAME_HEIGHT = 700 WHITE = 255, 255, 255 +BLACK = 0, 0, 0 +DARK_GREEN = 0, 100, 0 + +PROFILE_FILE_NAME = "profile/terminalfighter" def terminalfighter(screen): @@ -26,8 +33,10 @@ def terminalfighter(screen): spawn_controller = SpawnController(universe, score_counter) gamemaster = GameMaster(universe, spawn_controller, score_counter) # pygame ticks, one tick is 1/1000 second - # 15 pygame ticks per update is approximately 30 updates per second - FRAME_LENGTH_TICKS = 33 + # 15 pygame ticks per update is ~60 updates per second + FRAME_LENGTH_TICKS = 15 + + background_surface = draw_background() prev_frame_start_time = 0 @@ -45,6 +54,7 @@ def terminalfighter(screen): # print("update time : " + str(pygame.time.get_ticks() - update_start_time)) draw_start_time = pygame.time.get_ticks() + screen.blit(background_surface, (0, 0)) gamemaster.draw(screen) # print("draw time : " + str(pygame.time.get_ticks() - draw_start_time)) @@ -99,11 +109,38 @@ def terminalfighter(screen): else: print("WARNING: Cannot keep up with 30FPS update time!") -if __name__ == '__main__': - GAME_WIDTH = 1000 - GAME_HEIGHT = 700 +def draw_background(): + background_surface = pygame.Surface((GAME_WIDTH, GAME_HEIGHT)) + background_surface.fill(BLACK) + + line_separation = 25 + line_width = 1 - screen = pygame.display.set_mode( - (int(GAME_WIDTH), int(GAME_HEIGHT))) + for i in range(line_separation, GAME_WIDTH, line_separation): + pygame.draw.line(background_surface, + DARK_GREEN, + (i, 0), + (i, GAME_HEIGHT), + line_width) - terminalfighter(screen) + for i in range(line_separation, GAME_HEIGHT, line_separation): + pygame.draw.line(background_surface, + DARK_GREEN, + (0, i), + (GAME_WIDTH, i), + line_width) + + return background_surface + + +if __name__ == '__main__': + # Start profiling + pr = cProfile.Profile() + pr.enable() + try: + screen = pygame.display.set_mode( + (int(GAME_WIDTH), int(GAME_HEIGHT))) + terminalfighter(screen) + finally: + pr.disable() + pr.dump_stats("%s_%d.prof" % (PROFILE_FILE_NAME, int(time.time()))) From 8f9d8a91996eaf6d62bd1a915e7d6f91780b7ff2 Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Fri, 1 May 2020 17:10:27 -0600 Subject: [PATCH 02/10] removed unused variable --- homing_missiles.py | 1 - rifle.py | 1 - 2 files changed, 2 deletions(-) diff --git a/homing_missiles.py b/homing_missiles.py index 46fa88e..8f41222 100644 --- a/homing_missiles.py +++ b/homing_missiles.py @@ -9,7 +9,6 @@ pygame.font.init() BLACK = 0, 0, 0 -DARK_GREEN = 0, 100, 0 GREEN = 0, 255, 0 RED = 255, 0, 0 WHITE = 255, 255, 255 diff --git a/rifle.py b/rifle.py index eb28bb6..1608ad0 100644 --- a/rifle.py +++ b/rifle.py @@ -9,7 +9,6 @@ pygame.font.init() BLACK = 0, 0, 0 -DARK_GREEN = 0, 100, 0 GREEN = 0, 255, 0 LIGHT_BLUE = 100, 100, 255 RED = 255, 0, 0 From c0df139b8c691f2aec5d8148023034352c401fb9 Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Sat, 2 May 2020 02:23:33 -0600 Subject: [PATCH 03/10] removing profile directory --- profile/README.md | 9 --------- profile/terminalfighter_1588373774.prof | Bin 130027 -> 0 bytes profile/terminalfighter_baseline.prof | Bin 33938 -> 0 bytes 3 files changed, 9 deletions(-) delete mode 100644 profile/README.md delete mode 100644 profile/terminalfighter_1588373774.prof delete mode 100644 profile/terminalfighter_baseline.prof diff --git a/profile/README.md b/profile/README.md deleted file mode 100644 index 5a2baa8..0000000 --- a/profile/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Profiling ---------- -###Prereqs - -`pip3 install snakeviz` -###How to run -`snakeviz ` - -This will open the profile in your browser \ No newline at end of file diff --git a/profile/terminalfighter_1588373774.prof b/profile/terminalfighter_1588373774.prof deleted file mode 100644 index 1825c79c8d428811cea45de0ca0f6e7cbb1a2773..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130027 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≫3NPg(bJbsuvc>e3oZiCKA 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 bo2;Y(&c-im3bB%f3CN%gD6Z9sjD)4As6RFP}N3 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 JJ=m_@{{fptty};A From 82955a61f65a948d532f34dafac0346d5afd6ba4 Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Sat, 2 May 2020 02:24:58 -0600 Subject: [PATCH 04/10] moved grid rendering back into weapon rifle and homing missle --- gamemaster.py | 10 +++++----- homing_missiles.py | 40 ++++++++++++++++++++++++++++++++++------ maincharacter.py | 5 ++--- rifle.py | 33 +++++++++++++++++++++++++++++++-- terminalfighter.py | 42 +++++++----------------------------------- 5 files changed, 79 insertions(+), 51 deletions(-) diff --git a/gamemaster.py b/gamemaster.py index 1308b16..405d2db 100644 --- a/gamemaster.py +++ b/gamemaster.py @@ -7,25 +7,25 @@ from maincharacter import MainCharacter from not_so_basic_grunt import NotSoBasicGrunt -class GameMaster(): - def __init__(self, universe, spawn_controller, score_counter): +class GameMaster: + def __init__(self, universe, spawn_controller, score_counter, screen_size): self.universe_ = universe self.spawn_controller = spawn_controller self.score_counter_ = score_counter self.main_character_spawn_height_ = self.universe_.height_*0.9 - self.spawn_main_character() + self.spawn_main_character(screen_size) def draw(self, screen): self.universe_.main_character_.draw_view(screen) self.universe_.main_character_.draw_ui(screen) self.score_counter_.draw(screen) - def spawn_main_character(self): + def spawn_main_character(self, screen_size): starting_position = [ self.universe_.width_/2, self.main_character_spawn_height_] the_main_character = MainCharacter( - starting_position, self.universe_) + starting_position, self.universe_, screen_size) self.universe_.create_main_character(the_main_character) def update(self, events): diff --git a/homing_missiles.py b/homing_missiles.py index 8f41222..f19beb6 100644 --- a/homing_missiles.py +++ b/homing_missiles.py @@ -14,6 +14,7 @@ WHITE = 255, 255, 255 YELLOW = 255, 255, 0 GRAY = 88, 88, 88 +DARK_GREEN = 0, 100, 0 EVENT_KEY_a = 97 EVENT_KEY_BACKSPACE = 8 @@ -21,9 +22,8 @@ EVENT_KEY_z = 122 -class HomingMissilesTargetingSystem(): - - def __init__(self, universe): +class HomingMissilesTargetingSystem: + def __init__(self, universe, screen_size): self.universe_ = universe self.current_text_ = "" @@ -44,6 +44,30 @@ def __init__(self, universe): self.word_generator_ = WordGenerator() self.word_length_min_ = 5 self.word_length_range_ = 3 + self.grid = self._initialize_grid(screen_size[0], screen_size[1]) + + @staticmethod + def _initialize_grid(width, height): + background_surface = pygame.Surface((width, height)) + + line_separation = 25 + line_width = 1 + + for i in range(line_separation, width, line_separation): + pygame.draw.line(background_surface, + DARK_GREEN, + (i, 0), + (i, height), + line_width) + + for i in range(line_separation, height, line_separation): + pygame.draw.line(background_surface, + DARK_GREEN, + (0, i), + (width, i), + line_width) + + return background_surface def get_target_id(self, terminal_input): for enemy in self.universe_.enemies(): @@ -102,11 +126,15 @@ def update(self, events): """ def draw(self, screen): + self.draw_grid(screen) self.draw_entities(screen) self.draw_target_tags(screen) self.draw_targets(screen) self.targeting_terminal_.draw_terminal(screen) + def draw_grid(self, screen): + screen.blit(self.grid, (0, 0)) + def draw_entities(self, screen): self.draw_friendly_projectiles(screen) self.draw_enemy_projectiles(screen) @@ -241,13 +269,13 @@ def report_destroyed(self): def register(self, listeners): self.listeners_.append(listeners) -class HomingMissiles(): - def __init__(self, universe): +class HomingMissiles: + def __init__(self, universe, screen_size): self.universe_ = universe self.NAME_ = "Homing Missiles" - self.targeting_system = HomingMissilesTargetingSystem(universe) + self.targeting_system = HomingMissilesTargetingSystem(universe, screen_size) def update(self, events): self.targeting_system.update(events) diff --git a/maincharacter.py b/maincharacter.py index 7f408f2..b293ca5 100644 --- a/maincharacter.py +++ b/maincharacter.py @@ -17,10 +17,9 @@ class MainCharacter(GameObject): - def __init__(self, starting_position, universe): + def __init__(self, starting_position, universe, screen_size): self.position_ = starting_position self.universe_ = universe - self.font_size_ = 22 self.id_ = self.create_ID() self.max_health_ = 100 @@ -32,7 +31,7 @@ def __init__(self, starting_position, universe): self.weapon_label_x_spacing_ = 5 self.weapon_label_y_spacing_ = 10 self.weapons_ = [Rifle(self.universe_), - HomingMissiles(self.universe_)] + HomingMissiles(self.universe_, screen_size)] self.current_weapon_ = self.weapons_[self.selected_weapon_index_] self.health_ = self.max_health_ diff --git a/rifle.py b/rifle.py index 1608ad0..e8fea7f 100644 --- a/rifle.py +++ b/rifle.py @@ -14,6 +14,7 @@ RED = 255, 0, 0 WHITE = 255, 255, 255 GRAY = 88, 88, 88 +DARK_GREEN = 0, 100, 0 EVENT_KEY_a = 97 EVENT_KEY_BACKSPACE = 8 @@ -21,9 +22,9 @@ EVENT_KEY_z = 122 -class RifleTargetingSystem(): +class RifleTargetingSystem: - def __init__(self, universe): + def __init__(self, universe, screen_size): self.universe_ = universe self.current_text_ = "" @@ -42,6 +43,30 @@ def __init__(self, universe): self.word_generator_ = WordGenerator() self.word_length_min_ = 3 self.word_length_range_ = 3 + self.grid = self._initialize_grid(screen_size[0], screen_size[1]) + + @staticmethod + def _initialize_grid(width, height): + background_surface = pygame.Surface((width, height)) + + line_separation = 25 + line_width = 1 + + for i in range(line_separation, width, line_separation): + pygame.draw.line(background_surface, + DARK_GREEN, + (i, 0), + (i, height), + line_width) + + for i in range(line_separation, height, line_separation): + pygame.draw.line(background_surface, + DARK_GREEN, + (0, i), + (width, i), + line_width) + + return background_surface def get_target_id(self, terminal_input): for enemy in self.universe_.enemies(): @@ -94,10 +119,14 @@ def update(self, events): """ def draw(self, screen): + self.draw_grid(screen) self.draw_entities(screen) self.draw_target_tags(screen) self.targeting_terminal_.draw_terminal(screen) + def draw_grid(self, screen): + screen.blit(self.grid, (0, 0)) + def draw_entities(self, screen): self.draw_friendly_projectiles(screen) self.draw_enemy_projectiles(screen) diff --git a/terminalfighter.py b/terminalfighter.py index f5b35f0..3ce6f01 100644 --- a/terminalfighter.py +++ b/terminalfighter.py @@ -4,7 +4,6 @@ import highscore_service import pygame - from gamemaster import GameMaster from score_counter import ScoreCounter from spawn_controller import SpawnController @@ -20,23 +19,21 @@ BLACK = 0, 0, 0 DARK_GREEN = 0, 100, 0 -PROFILE_FILE_NAME = "profile/terminalfighter" def terminalfighter(screen): - pygame.mixer.music.load("TerminalFighterPrototypeTheme.ogg") pygame.mixer.music.play(loops=-1) pygame.mixer.music.set_volume(1.1) print("volume is " + str(pygame.mixer.music.get_volume())) - universe = Universe((GAME_WIDTH, GAME_HEIGHT)) + universe = Universe(screen.get_size()) score_counter = ScoreCounter() spawn_controller = SpawnController(universe, score_counter) - gamemaster = GameMaster(universe, spawn_controller, score_counter) + gamemaster = GameMaster(universe, spawn_controller, score_counter, screen.get_size()) # pygame ticks, one tick is 1/1000 second # 15 pygame ticks per update is ~60 updates per second FRAME_LENGTH_TICKS = 15 - background_surface = draw_background() + background_surface = draw_background(screen.get_width(), screen.get_height()) prev_frame_start_time = 0 @@ -109,38 +106,13 @@ def terminalfighter(screen): else: print("WARNING: Cannot keep up with 30FPS update time!") -def draw_background(): - background_surface = pygame.Surface((GAME_WIDTH, GAME_HEIGHT)) +def draw_background(width, height): + background_surface = pygame.Surface((width, height)) background_surface.fill(BLACK) - line_separation = 25 - line_width = 1 - - for i in range(line_separation, GAME_WIDTH, line_separation): - pygame.draw.line(background_surface, - DARK_GREEN, - (i, 0), - (i, GAME_HEIGHT), - line_width) - - for i in range(line_separation, GAME_HEIGHT, line_separation): - pygame.draw.line(background_surface, - DARK_GREEN, - (0, i), - (GAME_WIDTH, i), - line_width) - return background_surface if __name__ == '__main__': - # Start profiling - pr = cProfile.Profile() - pr.enable() - try: - screen = pygame.display.set_mode( - (int(GAME_WIDTH), int(GAME_HEIGHT))) - terminalfighter(screen) - finally: - pr.disable() - pr.dump_stats("%s_%d.prof" % (PROFILE_FILE_NAME, int(time.time()))) + screen = pygame.display.set_mode((int(GAME_WIDTH), int(GAME_HEIGHT))) + terminalfighter(screen) From 527ceb3772dd7aa1567ed580b40ab5a5c2f98d17 Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Sat, 2 May 2020 02:27:56 -0600 Subject: [PATCH 05/10] fixed rifle --- maincharacter.py | 2 +- rifle.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/maincharacter.py b/maincharacter.py index b293ca5..6a56d0a 100644 --- a/maincharacter.py +++ b/maincharacter.py @@ -30,7 +30,7 @@ def __init__(self, starting_position, universe, screen_size): self.ui_font_ = pygame.font.SysFont("monospace", self.font_size_) self.weapon_label_x_spacing_ = 5 self.weapon_label_y_spacing_ = 10 - self.weapons_ = [Rifle(self.universe_), + self.weapons_ = [Rifle(self.universe_, screen_size), HomingMissiles(self.universe_, screen_size)] self.current_weapon_ = self.weapons_[self.selected_weapon_index_] diff --git a/rifle.py b/rifle.py index e8fea7f..72ee195 100644 --- a/rifle.py +++ b/rifle.py @@ -241,13 +241,12 @@ def register(self, listeners): self.listeners_.append(listeners) -class Rifle(): - - def __init__(self, universe): +class Rifle: + def __init__(self, universe, screen_size): self.universe_ = universe self.NAME_ = "Rifle" - self.targeting_system = RifleTargetingSystem(universe) + self.targeting_system = RifleTargetingSystem(universe, screen_size) def update(self, events): self.targeting_system.update(events) From 2bbcf61d95c8e199175868b246fc88437095b9a9 Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Sat, 2 May 2020 02:38:38 -0600 Subject: [PATCH 06/10] fixing main menu --- main.py | 36 +++++++++++++++++++++++------------- main_menu.py | 23 +++++++++++++---------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/main.py b/main.py index ac0c19e..cb6994a 100644 --- a/main.py +++ b/main.py @@ -1,28 +1,38 @@ +import cProfile import sys +import time import pygame from main_menu import main_menu from terminalfighter import terminalfighter -pygame.init() +GAME_WIDTH = 1000 +GAME_HEIGHT = 700 + +PROFILE_FILE_NAME = "terminalfighter" + def exit_game(screen): sys.exit() -GAME_WIDTH = 1000 -GAME_HEIGHT = 700 - -screen = pygame.display.set_mode( - (int(GAME_WIDTH), int(GAME_HEIGHT))) run_game_state = { - "MENU" : main_menu, - "PLAY" : terminalfighter, - "QUIT" : exit_game + "MENU": main_menu, + "PLAY": terminalfighter, + "QUIT": exit_game } -gamestate = "MENU" - -while True: - gamestate = run_game_state.get(gamestate, exit_game)(screen) +if __name__ == '__main__': + # Start profiling + pr = cProfile.Profile() + pr.enable() + try: + pygame.init() + screen = pygame.display.set_mode((int(GAME_WIDTH), int(GAME_HEIGHT))) + gamestate = "MENU" + while True: + gamestate = run_game_state.get(gamestate, exit_game)(screen) + finally: + pr.disable() + pr.dump_stats("%s_%d.prof" % (PROFILE_FILE_NAME, int(time.time()))) diff --git a/main_menu.py b/main_menu.py index 56ea927..001081c 100644 --- a/main_menu.py +++ b/main_menu.py @@ -18,6 +18,7 @@ HIGH_SCORE_FILE = "HighScore.txt" + class SelectionListener(DestroyListener): def __init__(self): @@ -36,11 +37,13 @@ def reported_destroyed(self, type_gameobject): if not self.selected_: self.selected_ = self.selections_[type_gameobject.id_] -def spawn_main_character(universe): - the_main_character = MainCharacter([universe.width_/2, universe.height_*0.9], universe) + +def spawn_main_character(universe, screen_size): + the_main_character = MainCharacter([universe.width_/2, universe.height_*0.9], universe, screen_size) the_main_character.weapons_ = the_main_character.weapons_[:1] universe.create_main_character(the_main_character) + def spawn_selection(starting_pos, name, universe, selection_listener): the_selection = BasicGrunt(starting_pos, universe) the_selection.speed_ = 0 @@ -50,21 +53,21 @@ def spawn_selection(starting_pos, name, universe, selection_listener): def main_menu(screen): - universe = Universe((GAME_WIDTH, GAME_HEIGHT)) + universe = Universe(screen.get_size()) selection_listener = SelectionListener() ui_font_ = pygame.font.SysFont("monospace", 30) - LABEL_SPACING = 50 - play_position = [GAME_WIDTH*(1/3), GAME_HEIGHT*(1/4)] - quit_position = [GAME_WIDTH*(2/3), GAME_HEIGHT*(1/4)] + label_spacing = 50 + play_position = [screen.get_width() * (1/3), screen.get_height() * (1/4)] + quit_position = [screen.get_width() * (2/3), screen.get_height() * (1/4)] - spawn_main_character(universe) + spawn_main_character(universe, screen.get_size()) spawn_selection(play_position, "PLAY", universe, selection_listener) spawn_selection(quit_position, "QUIT", universe, selection_listener) highscore = highscore_service.get_highscore() # pygame ticks, one tick is 1/1000 second # 15 pygame ticks per update is approximately 30 updates per second - FRAME_LENGTH_TICKS = 33 + FRAME_LENGTH_TICKS = 15 prev_frame_start_time = 0 @@ -90,12 +93,12 @@ def main_menu(screen): play_label = ui_font_.render("PLAY", 1, WHITE) screen.blit(play_label, (play_position[0] - (play_label.get_width()/2), - play_position[1] - LABEL_SPACING)) + play_position[1] - label_spacing)) quit_label = ui_font_.render("QUIT", 1, WHITE) screen.blit(quit_label, (quit_position[0] - (quit_label.get_width()/2), - quit_position[1] - LABEL_SPACING)) + quit_position[1] - label_spacing)) instruction_label = ui_font_.render("TYPE TO SHOOT!", 1, WHITE) screen.blit(instruction_label, From 272e5b27a0bdb70e2f172649a08c36c813e21741 Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Sat, 2 May 2020 18:36:22 -0600 Subject: [PATCH 07/10] added flag to enable profiling --- Pipfile | 1 + Pipfile.lock | 24 +++++++++++++++++++++++- README.md | 4 ++++ main.py | 19 ++++++++++++++----- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Pipfile b/Pipfile index aa2daf7..57823f0 100644 --- a/Pipfile +++ b/Pipfile @@ -5,6 +5,7 @@ verify_ssl = true [dev-packages] autopep8 = "*" +snakeviz = "*" [packages] pygame = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 0ad3c0f..54a65da 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c39558b2034dc33d1500cb41d4e9bf9ca5c032b6c55c46587a0736362bdb7144" + "sha256": "b58fc00637227d3ea389ef4fd2caa988dc5986dae52be4e25ad7246331087694" }, "pipfile-spec": 6, "requires": { @@ -63,6 +63,28 @@ "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" ], "version": "==2.5.0" + }, + "snakeviz": { + "hashes": [ + "sha256:8ce375b18ae4a749516d7e6c6fbbf8be6177c53974f53534d8eadb646cd279b1", + "sha256:92ad876fb6a201a7e23a6b85ea96d9643a51e285667c253a8653643804f7cb68" + ], + "index": "pypi", + "version": "==2.1.0" + }, + "tornado": { + "hashes": [ + "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc", + "sha256:22aed82c2ea340c3771e3babc5ef220272f6fd06b5108a53b4976d0d722bcd52", + "sha256:2c027eb2a393d964b22b5c154d1a23a5f8727db6fda837118a776b29e2b8ebc6", + "sha256:5217e601700f24e966ddab689f90b7ea4bd91ff3357c3600fa1045e26d68e55d", + "sha256:5618f72e947533832cbc3dec54e1dffc1747a5cb17d1fd91577ed14fa0dc081b", + "sha256:5f6a07e62e799be5d2330e68d808c8ac41d4a259b9cea61da4101b83cb5dc673", + "sha256:c58d56003daf1b616336781b26d184023ea4af13ae143d9dda65e31e534940b9", + "sha256:c952975c8ba74f546ae6de2e226ab3cc3cc11ae47baf607459a6728585bb542a", + "sha256:c98232a3ac391f5faea6821b53db8db461157baa788f5d6222a193e9456e1740" + ], + "version": "==6.0.4" } } } diff --git a/README.md b/README.md index 4c56eeb..ae91ffd 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,7 @@ Dev Setup 2. Run `pip install pipenv` to install pipenv 3. Run `pipenv install` to bring in dependencies 4. Launch the game by running `pipenv run python main.py` + +####Profiling + * To view a profile result, run the following command: + `pipenv run snakeviz <.prof file>` diff --git a/main.py b/main.py index cb6994a..b97500e 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ import cProfile import sys import time - +import argparse import pygame from main_menu import main_menu @@ -24,9 +24,15 @@ def exit_game(screen): } if __name__ == '__main__': - # Start profiling + parser = argparse.ArgumentParser() + parser.add_argument("-p", "--profile", action='store_true', + help="Enabling profiling. Profiling output is dumped into terminalfighter_") + args = parser.parse_args() pr = cProfile.Profile() - pr.enable() + if args.profile: + # Start profiling + print("Starting with profiling enabled") + pr.enable() try: pygame.init() screen = pygame.display.set_mode((int(GAME_WIDTH), int(GAME_HEIGHT))) @@ -34,5 +40,8 @@ def exit_game(screen): while True: gamestate = run_game_state.get(gamestate, exit_game)(screen) finally: - pr.disable() - pr.dump_stats("%s_%d.prof" % (PROFILE_FILE_NAME, int(time.time()))) + if args.profile: + pr.disable() + prof_file = "%s_%d.prof" % (PROFILE_FILE_NAME, int(time.time())) + print("Dumping profiling results to %s" % prof_file) + pr.dump_stats(prof_file) From 949f0a8ff81b95f9bef9f6c573a2b973518b8d0c Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Sat, 2 May 2020 18:57:41 -0600 Subject: [PATCH 08/10] renamed surface --- homing_missiles.py | 8 ++++---- rifle.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/homing_missiles.py b/homing_missiles.py index f19beb6..8ebb480 100644 --- a/homing_missiles.py +++ b/homing_missiles.py @@ -48,26 +48,26 @@ def __init__(self, universe, screen_size): @staticmethod def _initialize_grid(width, height): - background_surface = pygame.Surface((width, height)) + grid_surface = pygame.Surface((width, height)) line_separation = 25 line_width = 1 for i in range(line_separation, width, line_separation): - pygame.draw.line(background_surface, + pygame.draw.line(grid_surface, DARK_GREEN, (i, 0), (i, height), line_width) for i in range(line_separation, height, line_separation): - pygame.draw.line(background_surface, + pygame.draw.line(grid_surface, DARK_GREEN, (0, i), (width, i), line_width) - return background_surface + return grid_surface def get_target_id(self, terminal_input): for enemy in self.universe_.enemies(): diff --git a/rifle.py b/rifle.py index 72ee195..a002482 100644 --- a/rifle.py +++ b/rifle.py @@ -47,26 +47,26 @@ def __init__(self, universe, screen_size): @staticmethod def _initialize_grid(width, height): - background_surface = pygame.Surface((width, height)) + grid_surface = pygame.Surface((width, height)) line_separation = 25 line_width = 1 for i in range(line_separation, width, line_separation): - pygame.draw.line(background_surface, + pygame.draw.line(grid_surface, DARK_GREEN, (i, 0), (i, height), line_width) for i in range(line_separation, height, line_separation): - pygame.draw.line(background_surface, + pygame.draw.line(grid_surface, DARK_GREEN, (0, i), (width, i), line_width) - return background_surface + return grid_surface def get_target_id(self, terminal_input): for enemy in self.universe_.enemies(): From 7a0b2a7bfb82af07c9fc829de576798f33b8582a Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Sat, 2 May 2020 19:00:42 -0600 Subject: [PATCH 09/10] updated README with enabling profiling instructions --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index ae91ffd..c948103 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,8 @@ Dev Setup 4. Launch the game by running `pipenv run python main.py` ####Profiling + * To enable profiling, launch the game with the `--profile` option. + e.g. + `pipenv run python main.py --profile` * To view a profile result, run the following command: `pipenv run snakeviz <.prof file>` From e75475e31935e1715b47ff23785e4a63a543ba28 Mon Sep 17 00:00:00 2001 From: Sam Ao Date: Mon, 4 May 2020 21:58:25 -0600 Subject: [PATCH 10/10] minor cleanup --- main.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/main.py b/main.py index 0e12685..fa88d22 100644 --- a/main.py +++ b/main.py @@ -21,9 +21,6 @@ def exit_game(screen): # 16 pygame ticks per update is approximately 62.5 updates per second FRAME_LENGTH_TICKS = 16 -screen = pygame.display.set_mode( - (int(GAME_WIDTH), int(GAME_HEIGHT))) - run_game_state = { "MENU": main_menu, "PLAY": terminalfighter,