{"id":1028,"date":"2023-02-02T09:34:12","date_gmt":"2023-02-02T09:34:12","guid":{"rendered":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/?post_type=chapter&#038;p=1028"},"modified":"2023-02-02T09:34:31","modified_gmt":"2023-02-02T09:34:31","slug":"platvormi-mangu-naide","status":"publish","type":"chapter","link":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/chapter\/platvormi-mangu-naide\/","title":{"raw":"Platvormi m\u00e4ngu n\u00e4ide","rendered":"Platvormi m\u00e4ngu n\u00e4ide"},"content":{"raw":"<h1 id=\"pygame-platform-game--page-root\">Platvormi m\u00e4ng<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#pygame-platform-game--page-root\">\uf0c1<\/a><\/h1>\r\nLoome \u00fche natuke keerukama platvormi m\u00e4ngu ning kasutame siin objekt-orienteeritud programmeerimist. M\u00e4ngukomponentide jagamine objektideks hoiab koodi puhtamana ning arendajal on selgem \u00fclevaade, kus mingid asjad toimuvad.\r\n\r\nM\u00e4ngujuhis: liigu m\u00e4ngijaga l\u00f5pulipu juurde. Vasakule-paremale saab liikuda klahvidega <code class=\"docutils literal notranslate\"><span class=\"pre\">a<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">d<\/span><\/code>, h\u00fcpata saab t\u00fchikuga. Kollide vastu ei tohi minna. Samuti ei tohi kukkuda teravate ogade otsa. M\u00f5lemal kahel juhul m\u00e4ng l\u00f5ppeb.\r\n\r\n[video width=\"1280\" height=\"720\" mp4=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/02\/platformer_game_example.mp4\"][\/video]\r\n\r\nSelles m\u00e4ngus on kaks erinevat stseeni v\u00f5i vaadet: men\u00fc\u00fc ja m\u00e4ngu vaade. Vaate jaoks on loodud eraldi klass <code class=\"docutils literal notranslate\"><span class=\"pre\">Scene<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/scene.py\">siin<\/a>). Men\u00fc\u00fc vaates (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/main_menu.py\">siin<\/a>) kuvatakse kaks nuppu. \u00dcks alustab m\u00e4ngu (vahetab stseeni v\u00f5i vaate), teine l\u00f5petab programmi.\r\n\r\nNuppude jaoks on loodud eraldi abiklass <code class=\"docutils literal notranslate\"><span class=\"pre\">Button<\/span><\/code>, mis paikneb <code class=\"docutils literal notranslate\"><span class=\"pre\">ui<\/span><\/code> moodulis (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/ui.py\">siin<\/a>). See on hea n\u00e4ide sellest, kuidas korduvkasutatavat komponenti on m\u00f5istlik hoida eraldi klassis. Kui hiljem on soov lisada veel m\u00f5ni nupp - n\u00e4iteks m\u00e4ngujuhise jaoks -, saab seda teha kasutades juba loodud nupu klassi.\r\n\r\nM\u00e4ngu vaate (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/game_level.py\">siin<\/a>) jaoks on koostatud maailm tekstina. Iga s\u00fcmbol tekstis t\u00e4histab mingi kindla suurusega ala \"maailmas\". Vastavalt tekstile koostatakse maailm, milles m\u00e4ngija liigub. Sedasi on mugav hiljem teha erinevaid leveleid. Loomulikult saaks maailma luua ka graafiliselt erinevate t\u00f6\u00f6vahenditega, aga selline tekstip\u00f5hine l\u00e4henemine on lihtsa maailma loomiseks v\u00e4ga mugav.\r\n\r\nMaailm ise on palju suurem, kui korraga ekraanile \u00e4ra mahub. Koodis on loodud eraldi pind <code class=\"docutils literal notranslate\"><span class=\"pre\">self.game_camera<\/span><\/code>, mis n\u00e4itab v\u00e4lja vaid teatud suurusega ala m\u00e4ngija \u00fcmber. See pind v\u00f5i n-\u00f6 vaade liigub m\u00e4ngijaga kaasa. Meetodis <code class=\"docutils literal notranslate\"><span class=\"pre\">build_level_from_data<\/span><\/code> toimub maailma ehitamine vastavalt tekstilisele esitusele. <code class=\"docutils literal notranslate\"><span class=\"pre\">render<\/span><\/code> meetodis arvutatakse v\u00e4lja, millist osa maailmast on vaja n\u00e4idata s\u00f5ltuvalt m\u00e4ngija asukohast.\r\n\r\nM\u00e4ngukomponentide jaoks kasutatakse erinevaid objekte, mis on \u00e4ra kirjeldatud moodulis <code class=\"docutils literal notranslate\"><span class=\"pre\">level_geometry.py<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/level_geometry.py\">siin<\/a>). Erinevate komponentide puhul on kirjeldatud, mis juhtub, kui nende pihta minna. N\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">FinishFlag<\/span><\/code> t\u00e4histab m\u00e4ngu l\u00f5ppu. Antud juhul lihtsalt prinditakse v\u00e4lja, et m\u00e4ng on l\u00f5ppenud. Aga siin v\u00f5iks vabalt m\u00e4ng liikuda edasi j\u00e4rgmise taseme juurde.\r\n\r\nM\u00e4ngu tegelaste jaoks on loodud \u00fcks \u00fchine \u00fclemklass <code class=\"docutils literal notranslate\"><span class=\"pre\">Body<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/body.py\">siin<\/a>). See klass laiendab PyGame'i enda <code class=\"docutils literal notranslate\"><span class=\"pre\">Sprite<\/span><\/code> klassi. Siin lisatakse meie m\u00e4ngu jaoks vajalikud komponendid ja funktsionaalsus. Eraldi lahendatakse objektidevahelise kokkupuute olukordi. N\u00e4iteks h\u00fcppamisel ei tohi l\u00e4bi seina kukkuda, seinast l\u00e4bi ei saa joosta, seinast l\u00e4bi ei saa h\u00fcpata jne. Seda v\u00f5ib vaadata <code class=\"docutils literal notranslate\"><span class=\"pre\">handle_collisions<\/span><\/code> meetodist.\r\n\r\nM\u00e4ngus on kahte t\u00fc\u00fcpi tegelasi: <code class=\"docutils literal notranslate\"><span class=\"pre\">Player<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/player.py\">siin<\/a>) ja <code class=\"docutils literal notranslate\"><span class=\"pre\">Monster<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/monster.py\">siin<\/a>). M\u00e4ngija puhul tegeletakse eraldi h\u00fcppe ja gravitatsiooniga. Koletis korral on liikumine lihtsam - ta liigub vaid vasakule ja paremale. Alguses liigub \u00fches suunas. Kui sein tuleb ette, siis liigub tagasi teises suunas. y-suunalist liikumist ei toimu.\r\n\r\nL\u00e4htekood tervele m\u00e4ngule on <a href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\">GitHubis<\/a>. Sealt saab k\u00e4tte ka erinevad pildid, mida m\u00e4ngus kasutatakse.","rendered":"<h1 id=\"pygame-platform-game--page-root\">Platvormi m\u00e4ng<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#pygame-platform-game--page-root\">\uf0c1<\/a><\/h1>\n<p>Loome \u00fche natuke keerukama platvormi m\u00e4ngu ning kasutame siin objekt-orienteeritud programmeerimist. M\u00e4ngukomponentide jagamine objektideks hoiab koodi puhtamana ning arendajal on selgem \u00fclevaade, kus mingid asjad toimuvad.<\/p>\n<p>M\u00e4ngujuhis: liigu m\u00e4ngijaga l\u00f5pulipu juurde. Vasakule-paremale saab liikuda klahvidega <code class=\"docutils literal notranslate\"><span class=\"pre\">a<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">d<\/span><\/code>, h\u00fcpata saab t\u00fchikuga. Kollide vastu ei tohi minna. Samuti ei tohi kukkuda teravate ogade otsa. M\u00f5lemal kahel juhul m\u00e4ng l\u00f5ppeb.<\/p>\n<div style=\"width: 1280px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-1028-1\" width=\"1280\" height=\"720\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/02\/platformer_game_example.mp4?_=1\" \/><a href=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/02\/platformer_game_example.mp4\">https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/02\/platformer_game_example.mp4<\/a><\/video><\/div>\n<p>Selles m\u00e4ngus on kaks erinevat stseeni v\u00f5i vaadet: men\u00fc\u00fc ja m\u00e4ngu vaade. Vaate jaoks on loodud eraldi klass <code class=\"docutils literal notranslate\"><span class=\"pre\">Scene<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/scene.py\">siin<\/a>). Men\u00fc\u00fc vaates (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/main_menu.py\">siin<\/a>) kuvatakse kaks nuppu. \u00dcks alustab m\u00e4ngu (vahetab stseeni v\u00f5i vaate), teine l\u00f5petab programmi.<\/p>\n<p>Nuppude jaoks on loodud eraldi abiklass <code class=\"docutils literal notranslate\"><span class=\"pre\">Button<\/span><\/code>, mis paikneb <code class=\"docutils literal notranslate\"><span class=\"pre\">ui<\/span><\/code> moodulis (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/ui.py\">siin<\/a>). See on hea n\u00e4ide sellest, kuidas korduvkasutatavat komponenti on m\u00f5istlik hoida eraldi klassis. Kui hiljem on soov lisada veel m\u00f5ni nupp &#8211; n\u00e4iteks m\u00e4ngujuhise jaoks -, saab seda teha kasutades juba loodud nupu klassi.<\/p>\n<p>M\u00e4ngu vaate (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/game_level.py\">siin<\/a>) jaoks on koostatud maailm tekstina. Iga s\u00fcmbol tekstis t\u00e4histab mingi kindla suurusega ala &#8220;maailmas&#8221;. Vastavalt tekstile koostatakse maailm, milles m\u00e4ngija liigub. Sedasi on mugav hiljem teha erinevaid leveleid. Loomulikult saaks maailma luua ka graafiliselt erinevate t\u00f6\u00f6vahenditega, aga selline tekstip\u00f5hine l\u00e4henemine on lihtsa maailma loomiseks v\u00e4ga mugav.<\/p>\n<p>Maailm ise on palju suurem, kui korraga ekraanile \u00e4ra mahub. Koodis on loodud eraldi pind <code class=\"docutils literal notranslate\"><span class=\"pre\">self.game_camera<\/span><\/code>, mis n\u00e4itab v\u00e4lja vaid teatud suurusega ala m\u00e4ngija \u00fcmber. See pind v\u00f5i n-\u00f6 vaade liigub m\u00e4ngijaga kaasa. Meetodis <code class=\"docutils literal notranslate\"><span class=\"pre\">build_level_from_data<\/span><\/code> toimub maailma ehitamine vastavalt tekstilisele esitusele. <code class=\"docutils literal notranslate\"><span class=\"pre\">render<\/span><\/code> meetodis arvutatakse v\u00e4lja, millist osa maailmast on vaja n\u00e4idata s\u00f5ltuvalt m\u00e4ngija asukohast.<\/p>\n<p>M\u00e4ngukomponentide jaoks kasutatakse erinevaid objekte, mis on \u00e4ra kirjeldatud moodulis <code class=\"docutils literal notranslate\"><span class=\"pre\">level_geometry.py<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/level_geometry.py\">siin<\/a>). Erinevate komponentide puhul on kirjeldatud, mis juhtub, kui nende pihta minna. N\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">FinishFlag<\/span><\/code> t\u00e4histab m\u00e4ngu l\u00f5ppu. Antud juhul lihtsalt prinditakse v\u00e4lja, et m\u00e4ng on l\u00f5ppenud. Aga siin v\u00f5iks vabalt m\u00e4ng liikuda edasi j\u00e4rgmise taseme juurde.<\/p>\n<p>M\u00e4ngu tegelaste jaoks on loodud \u00fcks \u00fchine \u00fclemklass <code class=\"docutils literal notranslate\"><span class=\"pre\">Body<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/body.py\">siin<\/a>). See klass laiendab PyGame&#8217;i enda <code class=\"docutils literal notranslate\"><span class=\"pre\">Sprite<\/span><\/code> klassi. Siin lisatakse meie m\u00e4ngu jaoks vajalikud komponendid ja funktsionaalsus. Eraldi lahendatakse objektidevahelise kokkupuute olukordi. N\u00e4iteks h\u00fcppamisel ei tohi l\u00e4bi seina kukkuda, seinast l\u00e4bi ei saa joosta, seinast l\u00e4bi ei saa h\u00fcpata jne. Seda v\u00f5ib vaadata <code class=\"docutils literal notranslate\"><span class=\"pre\">handle_collisions<\/span><\/code> meetodist.<\/p>\n<p>M\u00e4ngus on kahte t\u00fc\u00fcpi tegelasi: <code class=\"docutils literal notranslate\"><span class=\"pre\">Player<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/player.py\">siin<\/a>) ja <code class=\"docutils literal notranslate\"><span class=\"pre\">Monster<\/span><\/code> (l\u00e4htekood <a class=\"reference external\" href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\/blob\/main\/lib\/monster.py\">siin<\/a>). M\u00e4ngija puhul tegeletakse eraldi h\u00fcppe ja gravitatsiooniga. Koletis korral on liikumine lihtsam &#8211; ta liigub vaid vasakule ja paremale. Alguses liigub \u00fches suunas. Kui sein tuleb ette, siis liigub tagasi teises suunas. y-suunalist liikumist ei toimu.<\/p>\n<p>L\u00e4htekood tervele m\u00e4ngule on <a href=\"https:\/\/github.com\/taltech-coding\/pygame-platformer\">GitHubis<\/a>. Sealt saab k\u00e4tte ka erinevad pildid, mida m\u00e4ngus kasutatakse.<\/p>\n","protected":false},"author":36,"menu_order":7,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-1028","chapter","type-chapter","status-publish","hentry"],"part":780,"_links":{"self":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/1028","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/users\/36"}],"version-history":[{"count":1,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/1028\/revisions"}],"predecessor-version":[{"id":1030,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/1028\/revisions\/1030"}],"part":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/parts\/780"}],"metadata":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/1028\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/media?parent=1028"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapter-type?post=1028"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/contributor?post=1028"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/license?post=1028"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}