Pygame Tutorial
Pygame Tutorial
ThesenoteswerepreparedbytheGPNtutorsfortheGameinaDayworkshop.Thelatest versionofthesenotesareavailableonlineathttp://sydney.edu.au/it/gpn
Introduction
PygameisasetofPythonmodulesdesignedforwritingcomputergames.Today,wewillbe usingPygametowriteourowngames.Wevesplitupthegameintosmallerstepsto complete.Youcandownloadalltheresourcesforthisgameat: http://sydney.edu.au/it/gpn/game.shtml
GettingStarted
Tostartoff,weneedtogetPygametoopenawindowthatwewillbeabletoplaythe gamein. Firstweneedtoimportthepygamemodule,sothatwecanuseit.Thiswillbethefirstline ofthefile. i m p o r t p y g a m e Thenwellneedtoinitialisepygame. p y g a m e . i n i t ( ) Savethisinafilethatwecanrun.Makesureyoudon'tcallit'pygame.py',asthiswould causeproblems!(Itwouldtrytoimportitselfas"pygame"inourfirststep!) Wecannowstartsettingupourscreen. Weneedtodecidethewidthandheightwewantthegamewindowtobe.Wellsavethese invariablescalledWIDTHandHEIGHT.Theseparticularvariablenamesareincapitalsas aconvention,toshowthattheyareconstants,i.e.,thatthevaluesinthemwontchange. (Wedontintendthesizeofthegamewindowtochangewhilstplayingthegame.) W I D T H = 6 4 0 H E I G H T = 4 8 0 s c r e e n = p y g a m e . d i s p l a y . s e t _ m o d e ( ( W I D T H , H E I G H T ) ) Beforewecandoanythingelse,weneedtounderstandsomebasiccontrolflowinPython. Completethecheckpointon i f s t a t e m e n t s
CHECKPOINT!CompletetheChallengequestionsoni f s t a t e m e n t s !
Nowthatwevegotawindowsetup,wealsowanttobeabletocloseit!Sincewewantthe windowtostayopenuntilwecloseit,welluseawhileloop.Wellsetavariablecalled q u i t (initiallysetto F a l s e ).Aslongas q u i t is F a l s e ,theloopwillkeeprunning.Oncewe setitto T r u e ,thewhileloopwillexit,andtheprogramwillfinish,withthe p y g a m e . q u i t ( ) command. Thiswillbethemainloop(thew h i l e q u i t ! = T r u e : )ofourprogram.Notethatin Python,spacingisimportant!Askatutorifyougetstuck. f i n i s h = F a l s e w h i l e f i n i s h ! = T r u e : f o r e v e n t i n p y g a m e . e v e n t . g e t ( ) : i f e v e n t . t y p e = = p y g a m e . Q U I T : f i n i s h = T r u e p y g a m e . q u i t ( ) Thisalsosetsupaloopthatlistensforalleventsthathappen.Thesearethingslikekeys beingpressedorbuttonsbeingclicked.
Task1:
Followthestepsabovetocreateawindowthatcloseswhenyouclicktheclosex. Wemightalsowanttoaddtheabilitytoclosethewindowbypressingescape.Putthisjust aftertheother i f statementinthemainloopabove.Thespacingshouldlookthesameas theother i f statement. i f e v e n t . t y p e = = p y g a m e . K E Y D O W N a n d e v e n t . k e y = = p y g a m e . K _ E S C A P E : f i n i s h = T r u e
CHECKPOINT!CompletetheChallengequestionson w h i l e l o o p s !
HoldingoutforaHero!
Nowthatwevegotawindowupandrunning,weneedtoputourplayeronthescreen. First,beforeweenterthemainloopofourcode,weregoingtosetupourhero.Welldo thisbysettingupaspriteandsavingitinthevariable h e r o .Wecanthenaddpropertiesto itincludingwhichpicturetoload.Wellalsocalculatetherectangletheherotakesup.Well addthiscodeatthetopofthefile,beforethemainloop. Incomputergraphics,a spriteisatwodimensionalimageoranimationthatisintegrated intoalargerscene.(Wikipedia)
# S e t u p t h e h e r o h e r o = p y g a m e . s p r i t e . S p r i t e ( ) # A d d i m a g e a n d r e c t a n g l e p r o p e r t i e s t o t h e h e r o h e r o . i m a g e = p y g a m e . i m a g e . l o a d ( ' h e r o . g i f ' ) h e r o . r e c t = h e r o . i m a g e . g e t _ r e c t ( ) Wellalsocreateavariablecalled h e r o _ g r o u p tokeeptrackofourhero.Addthisbefore themainloop. h e r o _ g r o u p = p y g a m e . s p r i t e . G r o u p S i n g l e ( h e r o ) Great!Nowthatwevegottheherosetup,weneedtopaintittothescreen!Welladdthis partofthecodeinsideourmainloop.Theselinesshouldbethelastlinesofthemainloop thatis,thelastthingwewanttodoisdrawtheheroandupdatethescreen. # a d d t h e s e l i n e s a t t h e e n d o f t h e m a i n l o o p h e r o _ g r o u p . d r a w ( s c r e e n ) p y g a m e . d i s p l a y . u p d a t e ( ) Notethatweneedtoaddtheabovecodeinsidethewhileloop,sothattheherois continuallydrawntothescreen.
Task2:
Chooseyourhero!Puttheminyourgame.
MovingyourHero!
Wewanttobeabletodirectourheroaroundthescreen.Atthemoment,ourhero initialisesinthetopleftcornerofourscreensat(0,0). Aside:Graphicsonthecomputerarejustlikeagridwhichstartsat(0,0)atthetopleft cornerofthescreen.Eachsquareinthegridrepresentsapixel,andcanbereferenced by: ( < R O W N U M B E R > , < C O L U M N N U M B E R > )
Tomoveourheroaround,wellneedtoknowhowfartomovethemwitheachstep.We dontwantourherotoonlymoveonepixelleftandright,asitwouldtakehundredsofkey pressestomoveacrossthescreen.Instead,wellmoveourheroonetilespaneachkey press.Thatis,everytimewepressright,wewanttheherotomoveontothenextgrid square,basedonhowbigtheherois. Thinkofthecanvasasagridofsquaresthattheherocanmovethrough.Tocalculatehow bigthesquaresinthisgridare,wellneedtoknowhowmanytimestheherosimagecan fitonthecanvas.Wealreadyknowthe W I D T H and H E I G H T ofthedisplaywindow,aswe setitearlierinthecode.Setthe T I L E _ S I Z E tobeequalto h e r o . r e c t . w i d t h .Wecan thencalculatethenumberoftileswecanhaveinthegridbydividingthetotal W I D T H or H E I G H T bythe T I L E _ S I Z E .Thisshouldgointhefilebeforethemainloop,butafterthe linestartingwith h e r o . r e c t ,asyoullneedthisvaluetobeavailablefirst! T I L E _ S I Z E = h e r o . r e c t . w i d t h N U M _ T I L E S _ W I D T H = W I D T H / T I L E _ S I Z E N U M _ T I L E S _ H E I G H T = H E I G H T / T I L E _ S I Z E
Task4:
Makeyourheromove!
Whyismyheroleavingatrail?
Wait!Ourheroisleavingghostimagesofherselfbehindwhenshemoves!Wellneedto repaintthebackgroundblackwheneverwemoveher.
PaintingaBackground!
Weregoingtopaintaplainblackbackgroundforourcharacter.Wecandothisjustby fillingthescreenblackbeforeweredrawthehero.Wellneedtoaddthisinsidethemain loop,sothatthescreeniscontinuouslypaintedblack.Makesureyouaddthislineofcode beforethelineswhereyouaddtheheroandupdatethescreen.(Otherwise,youllfillthe screenblackoverthetopofthehero!) Aside:Whendrawingobjects(suchastheheroorthebackground)tothescreen,they aredrawninthesameorderthatthedrawcommandsappearinyourcode.Objectsthat aredrawnlateraredrawnontopofearlierobjects.Sotomaketheheroappearinfront ofthebackground,wedrawthebackgroundfirstandtheherosecond.
# P a i n t t h e b a c k g r o u n d b l a c k ( t h e t h r e e # v a l u e s r e p r e s e n t r e d , g r e e n a n d b l u e : # 0 f o r a l l o f t h e m m a k e s i t b l a c k ) s c r e e n . f i l l ( ( 0 , 0 , 0 ) ) Nowwedonthaveghostimagestrailingourhero.
DroptheCandy!
Great!Nowthatwehaveourherowalkingaround,weneedtoaddintheactualgame! Theaimofourgameisfortheherotopickuplolliesthathavebeendroppedalloverthe screen. Justlikewemadea h e r o _ g r o u p tokeeptrackofourhero,wellalsoaddina c a n d i e s variable.Allofthiscodeshouldbebeforethemainloop,butafterthelinewith T I L E _ S I Z E . Thiswillmakealisttostoreallthecandies. c a n d i e s = p y g a m e . s p r i t e . O r d e r e d U p d a t e s ( ) Firstwellgothroughaddingonecandy. Wellmakeanewspriteforit: c a n d y = p y g a m e . s p r i t e . S p r i t e ( ) Loaduptheimageofit: c a n d y . i m a g e = p y g a m e . i m a g e . l o a d ( ' c a n d y . p n g ' ) Makearectanglepropertyforit: c a n d y . r e c t = c a n d y . i m a g e . g e t _ r e c t ( ) PutitinalocationhereIlljustchoosetoputitthreetilestotherightandtwotilesdown: c a n d y . r e c t . l e f t = 3 * T I L E _ S I Z E c a n d y . r e c t . t o p = 2 * T I L E _ S I Z E Andaddittoourcandieslist: c a n d i e s . a d d ( c a n d y ) Wellalsoneedtodrawthecandytothescreen.Thiswillbe attheendofthemainloop, rightbeforethelineswherewedrawtheherotothescreen: h e r o _ g r o u p . d r a w ( s c r e e n ) andupdatethescreen: p y g a m e . d i s p l a y . u p d a t e ( ) c a n d i e s . d r a w ( s c r e e n ) Sonowthelastthreelinesofthecodeshouldbe: c a n d i e s . d r a w ( s c r e e n ) h e r o _ g r o u p . d r a w ( s c r e e n ) p y g a m e . d i s p l a y . u p d a t e ( )
Task5:
Putacandyonthescreen!
CHECKPOINT!CompletetheChallengequestionsonrandom numbers!
RandomisetheCandylocation!
Now,wecouldhardcodethelocationforallofthelolliesweredropping,butitwouldbe morefunifitchangedeverytime.Wecanusethe r a n d o m moduletogetrandomnumbers thatwecanuseascoordinates. Firstwellneedto i m p o r t r a n d o m . Putthisrightupthetopofthecode,justbelowtheline whereweimported p y g a m e . i m p o r t r a n d o m
Togeneraterandomnumbers,welluse r a n d o m . r a n d i n t ( ) ,whichtakestwoarguments: theminimumnumberandthemaximumnumber. Justaswecalculatedwhichtilesizedgridtoputthelollyinbefore,wedlikeittolineup nicelyinthegrid,soinsteadofchoosingarandomnumberbetween0and W I D T H forthex coordinate,wellchoosearandomnumberforthegridsquarebetween0and (N U M _ T I L E S _ W I D T H 1 ) or ( N U M _ T I L E S _ H E I G H T 1 ) .Wellthenneedtoconvertthe locationbackintopixels,bymultiplyingby T I L E _ S I Z E again.
Replacetheearlierlines: c a n d y . r e c t . l e f t = 3 * T I L E _ S I Z E c a n d y . r e c t . t o p = 2 * T I L E _ S I Z E with: c a n d y . r e c t . l e f t = r a n d o m . r a n d i n t ( 0 , N U M _ T I L E S _ W I D T H 1 ) * T I L E _ S I Z E c a n d y . r e c t . t o p = r a n d o m . r a n d i n t ( 0 , N U M _ T I L E S _ H E I G H T 1 ) * T I L E _ S I Z E
Task6:
Addinyourlollyatarandomlocationonthescreen!Rerunyourprogramafewtimesto seeitchangeposition.
CHECKPOINT!CompletetheChallengequestionsonranges!
MoreLolliestopickup
Great!Nowweregoingtoaddabunchmorelolliestopickup!Todothis,moveallthe codeweaddedintasks5and6intoaforloop(exceptthec a n d i e s = ...linethat shouldstaythethetop).WheneverwesayintoorinsideinPython,thatmeansuse spacestoindentsomelines(suchasthelinestocreatecandy)tomovetheminsidethe controlstatement.Here,thatsthe f o r statement. Usethe r a n g e ( ) functiontodeterminehowmanylolliestocreate.Thiscodeshouldstillbe beforethemainloop. f o r i i n r a n g e ( 1 0 ) : # a d d t h e c a n d y !
Task7:
Make10lolliesappearonthescreen!
Pickupthecandy!
Atthemoment,ifourherowalksoveralolly,nothinghappens.
Task8:
Makethecandydisappearifyourherowalksoverit.
Winningthegame!
Thewaywecanwinourgameisbypickingupallthelollies.Tofindoutwhetherornot youvewonthegame,welladdina w i n variablejustlikewesetupa q u i t variable. Initially,wellset w i n to F a l s e .Makesureyouputthisoutsideofthemainloop,nextto the q u i t = F a l s e line. w i n = F a l s e Now,whenwereintheloop(whileyourheroispickinguplollies)wellneedtocheckif yourherohaspickedupallthelollies.Wecancheckthisreallyeasilybyseeingwhatthe lengthofthelist c a n d i e s is. Ifthelistof c a n d i e s hasnoelementsinit(ie,haslengthof0)weshouldset w i n to T r u e ! Wewantthefollowingcodeinthemainloop,aswewanttokeepcheckingwhetherornot theplayerhaswon.Youcouldputthisafterthe g r o u p c o l l i d e function. i f l e n ( c a n d i e s ) = = 0 : w i n = T r u e Great!Nowthatweknowwhetherornottheplayerhaswon!Iftheyhave,wewantto displaysometexttothescreen.Putthefollowingcodeinsidethemainloop.Hint:ifyou cantseethetext,maybeyouredisplayingitbeforeyouclearthescreenitneedstogo afterwards! i f w i n : f o n t = p y g a m e . f o n t . F o n t ( N o n e , 3 6 ) t e x t _ i m a g e = f o n t . r e n d e r ( " Y o u W i n ! " , T r u e , ( 2 5 5 , 2 5 5 , 2 5 5 ) ) t e x t _ r e c t = t e x t _ i m a g e . g e t _ r e c t ( c e n t e r x = W I D T H / 2 , c e n t e r y = 1 0 0 ) s c r e e n . b l i t ( t e x t _ i m a g e , t e x t _ r e c t )
Task9:
Winthegame!
Congratulations!Younowhaveyourveryownworking game!:)
Ifyou'resuperfast,orwanttokeepworkingonthislater,herearesomeextrathingsto addtoyourgame!
Addingmorelolliesevery3seconds!
Wewanttomakeourgamemorefun,bymakingithardertopickupallthelollies!Todo this,welladdanextralollytothescreeneverythreeseconds! First,wellneedtochangethewayweaddlollies.Wellnowuseafunctiontoaddeach lollytothecandieslist.Outsidethemainloop,swapoutthecodewehadbeforethatadds lollies,andwritethisinstead.Itdefinesafunctionthatwearecalling a d d _ c a n d y ,and takesinthe c a n d i e s list. Wellkeeptheline f o r i i n r a n g e ( 1 0 ) : andnowmakeitcallthe a d d _ c a n d y functionfor eachiteration(i.e.,10times). d e f a d d _ c a n d y ( c a n d i e s ) : c a n d y = p y g a m e . s p r i t e . S p r i t e ( ) c a n d y . i m a g e = p y g a m e . i m a g e . l o a d ( ' c a n d y . p n g ' ) c a n d y . r e c t = c a n d y . i m a g e . g e t _ r e c t ( ) c a n d y . r e c t . l e f t = r a n d o m . r a n d i n t ( 0 , N U M _ T I L E S _ W I D T H 1 ) * T I L E _ S I Z E c a n d y . r e c t . t o p = r a n d o m . r a n d i n t ( 0 , N U M _ T I L E S _ H E I G H T 1 ) * T I L E _ S I Z E c a n d i e s . a d d ( c a n d y ) f o r i i n r a n g e ( 1 0 ) : a d d _ c a n d y ( c a n d i e s )
Nowwelladdatimerthatwilladdaneventtotheeventqueueeverycertainnumberof milliseconds.Herewellsetittoadda U S E R E V E N T every3seconds. Thisshouldgobeforethemainloopofthecode. p y g a m e . t i m e . s e t _ t i m e r ( p y g a m e . U S E R E V E N T , 3 0 0 0 ) Wellnowcatchthiseventaswehavebeencatchingkeypresses.Inthemainloop,below wherewearecheckingforup,down,leftandrightkeypresses,addthefollowingcode: i f e v e n t . t y p e = = p y g a m e . U S E R E V E N T : a d d _ c a n d y ( c a n d i e s ) Great!Werenearlythere!Nowwejustneedtomakesurethatiftheplayerhaswonthe game,wedontkeepaddinglolliesontothescreen!Todothis,wellcheckimmediately beforethe a d d _ c a n d y linewhetherornotwinisstillFalse.Ifitis,wecankeepadding candy.
Omnomnomnom!(addingsound)
Youshouldhaveafilealreadycallednom.wavwhichsoundslikeacookiemonstereatinga cookie.We'regoingtousethisfiletomakethesoundforwhenourheroeatsacandy. Atthebeginningofyourprogram(nearthetopsomewhere)weloadthesoundsothatit's fastertousewhenweneedit. m u n c h _ s o u n d = p y g a m e . m i x e r . S o u n d ( ' n o m . w a v ' ) Thenlaterwhenyouworkoutwhichcandiesarecurrentlybeingeaten,thegroupcollide functionreturnsthelistofcandiesthatwereeaten.Ifatleastonecandywaseaten,we playthesound! c o l l i d e s = p y g a m e . s p r i t e . g r o u p c o l l i d e ( h e r o _ g r o u p , c a n d i e s , F a l s e , T r u e ) i f l e n ( c o l l i d e s ) > 0 : m u n c h _ s o u n d . p l a y ( )