{"id":915,"date":"2023-01-02T08:08:43","date_gmt":"2023-01-02T08:08:43","guid":{"rendered":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/?post_type=chapter&#038;p=915"},"modified":"2023-02-02T05:36:00","modified_gmt":"2023-02-02T05:36:00","slug":"pygamei-ekraan-ja-joonistamine","status":"publish","type":"chapter","link":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/chapter\/pygamei-ekraan-ja-joonistamine\/","title":{"raw":"PyGame'i ekraan ja joonistamine","rendered":"PyGame&#8217;i ekraan ja joonistamine"},"content":{"raw":"PyGame'is toimub visuaalse pildi joonistamine n-\u00f6 joonistamispinnale (<em>surface<\/em>). Pind on ristk\u00fcliku kujuline ala, millele saab joonistada ja pilte lisada. <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.set_mode()<\/span><\/code> funktsiooniga luuakse \u00fcks eriline pind, mis t\u00e4histab kogu m\u00e4ngu n\u00e4htavat osa. Seda loodud pinda kasutatakse, et sinna m\u00e4ngukomponente joonistada.\r\n\r\nPinna sisu luuakse valmis m\u00e4nguts\u00fckli jooksul ning tavaliselt ts\u00fckli l\u00f5pus n\u00e4idatakse see v\u00e4lja kasutajale <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.flip()<\/span><\/code> funktsiooniga. N\u00e4iteks m\u00e4ngija tegelane liigub ja vastane liigub. See sisuliselt t\u00e4hendab, et pinna peal muudetakse m\u00e4ngija pildi\/kujundi asukohta ja vastase pildi\/kujundi asukohta. Asukoha muutmine t\u00e4hendab seda, et vana pilt\/kujund tuleb \"kustutada\" ja uus tuleb uuele positsioonile \"joonistada\". Kui need sammud on tehtud, siis kutsutakse v\u00e4lja funktsioon, mis n\u00e4itab muudatused ekraanile. Kui iga muudatus j\u00f5uaks kohe ekraanile, toimub v\u00e4ga palju visuaali muutmist (korra kustutatakse tegelane \u00e4ra ja siis joonistatakse uuesti), mis on m\u00e4ngijale ebamugav. PyGame'i puhul aga teeme muudatuse olekutes \u00e4ra ning <code class=\"docutils literal notranslate\"><span class=\"pre\">flip()<\/span><\/code> funktsiooniga n\u00e4idatakse need korraga v\u00e4lja.\r\n\r\n[embed]https:\/\/www.youtube.com\/embed\/PUAzPUY4flA[\/embed]\r\n\r\n<section id=\"pindade-kasutamine\">\r\n<h2 id=\"pindade-kasutamine\">Pindade kasutamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#pindade-kasutamine\">\uf0c1<\/a><\/h2>\r\nKui eelnevalt r\u00e4\u00e4kisime peamisest pinnast, mida n\u00e4idatakse aknas kasutajale, siis PyGame'is saab luua t\u00e4iendavaid pindu. Selleks saab kasutada <code class=\"docutils literal notranslate\"><span class=\"pre\">Surface<\/span><\/code> klassi. See annab v\u00f5imaluse t\u00e4psemalt juhtida, millist osa ekraanist on vaja uuendada. N\u00e4iteks v\u00f5ib kogu aken olla jagatud mitmeks osaks. \u00dches osas on m\u00e4ng, teises on men\u00fc\u00fc, kolmandas on m\u00e4ngija parameetrid. Sellisel juhul men\u00fc\u00fcd ja m\u00e4ngija parameetreid ei pea pidevalt uuendama. Kui m\u00e4ng on eraldi pinnal, siis on seda mugavam hallata ja m\u00e4ng t\u00f6\u00f6tab ka kiiremini.\r\n\r\nLoodav pind tuleb alati lisada m\u00f5ne teise pinna peale. \u00dcldiselt lisatakse loodav pind peamise pinna peale (mida <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.set_mode()<\/span><\/code> funktsiooniga loome). Aga on v\u00f5imalik ka nii, et peamise pinna peal on pind (n\u00e4iteks m\u00e4ngupind) ja selle peal on omakorda m\u00f5ni pind (m\u00e4ngija tegelane v\u00f5i vastase tegelane). Seega pind tuleb lisada teise pinna peale. Lisatav pind j\u00e4\u00e4b ekraanil esiplaanile taustapinna suhtes. Ehk kui peamine pind on must, aga sinna lisatakse valge m\u00e4ngupind, siis valge m\u00e4ngupind katab terves m\u00e4ngupinna ulatuses musta pinna valgega.\r\n\r\nPinna lisamine teise pinna peale toimub funktsiooniga <code class=\"docutils literal notranslate\"><span class=\"pre\">parent_surface.blit(child_surface,<\/span> <span class=\"pre\">(left,<\/span> <span class=\"pre\">top))<\/span><\/code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">child_surface<\/span><\/code> pind lisatakse <code class=\"docutils literal notranslate\"><span class=\"pre\">parent_surface<\/span><\/code> pinna peale asukohale <code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> pikslit vasakult ja <code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code> pikslit \u00fclevalt \u00e4\u00e4rest. Need koordinaadid on arvestatud <code class=\"docutils literal notranslate\"><span class=\"pre\">parent_surface<\/span><\/code> pinna suhtes.\r\n\r\nSiin on \u00fcks koodin\u00e4ide:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((800, 600))\r\n\r\nrunning = True\r\nwhile running:\r\n    for event in pygame.event.get():\r\n        if event.type == pygame.QUIT:\r\n            # closing window finishes the game loop\r\n            running = False\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # game surface\r\n    game_surface = pygame.Surface((600, 500))\r\n    game_surface.fill((128, 0, 0))\r\n    screen.blit(game_surface, (0, 0))\r\n\r\n    # player info surface\r\n    player_info_surface = pygame.Surface((200, 500))\r\n    player_info_surface.fill((0, 0, 0))\r\n    # put it on the right side\r\n    screen.blit(player_info_surface, (600, 0))\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\r\nTulemus peaks olema j\u00e4rgmine:\r\n\r\n<img class=\"alignnone size-large wp-image-916\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-1024x808.png\" alt=\"Ekraanide n\u00e4ide\" width=\"1024\" height=\"808\" \/>\r\n\r\nKoodis luuakse <code class=\"docutils literal notranslate\"><span class=\"pre\">game_surface<\/span><\/code> pind, mis lisatakse ekraanile vasakusse \u00fclemisse \u00e4\u00e4rde <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code>. Seej\u00e4rel luuakse m\u00e4ngija andmete pind, mis lisatakse m\u00e4nguala k\u00f5rvale. Kuna m\u00e4nguala laius on 600 pikslit, siis paigutatakse m\u00e4ngija andmete pind 600 piksli kaugusele vasakust \u00e4\u00e4rest.\r\n\r\nN\u00fc\u00fcd kui m\u00e4ngus midagi muutub, ei pea me tervet akent \u00fcle v\u00e4rvima. Piisab vaid m\u00e4nguala \u00fcle v\u00e4rvimisest. Tegelikult saab asju veel optimaalsemalt teha - saab \u00fcle v\u00e4rvida vaid selle osa, mis on muutunud. See annab teatud olukorras arvestatava kiirusev\u00f5idu. Kuigi esialgu m\u00e4ngutegemise juures ei ole see nii oluline. Kui kohe algusest peale proovid asju optimeerida, v\u00f5ib m\u00e4ngutegemise l\u00f5bu \u00e4ra kaduda. Pigem tegele optimeerimisega siis, kui see probleem tekib.\r\n<h2>M\u00f5tle ja nuputa!<\/h2>\r\n[h5p id=\"43\"]\r\n\r\n<\/section><section id=\"pildi-kasutamine\">\r\n<h2 id=\"pildi-kasutamine\">Pildi kasutamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#pildi-kasutamine\">\uf0c1<\/a><\/h2>\r\nTavaliselt m\u00e4ngus me ei kasuta igavaid v\u00e4rvilisi kaste, vaid taustapilti. Samamoodi m\u00e4ngu tegelane on pilt. PyGame'is pilt on samamoodi pind (<em>surface<\/em>). Seega v\u00e4ga palju sellest, mida eelnevalt kirjeldasime, rakendub ka piltide kohta.\r\n\r\nKogu ekraanil paistev visuaal on tegelikult pilt. Vahet pole, kas me joonistame ringe, loome uue pinna v\u00f5i lisame pilte. L\u00f5puks PyGame joonistab pildi. Pilt ise on tegelikult pikslite kogum. Seega v\u00f5ib \u00f6elda, et m\u00e4ngu jooksul me peame muutma pikslite v\u00e4\u00e4rtust (v\u00e4rvi) ja seel\u00e4bi n\u00e4eb m\u00e4ngija asju liikumas ja muutumas.\r\n\r\nTeeme \u00fche lihtsa n\u00e4ite, kus meil m\u00e4ngus on taustapilt ja selle peal liigub tegelane. Kuna plaanime teha kosmoseteemalist m\u00e4ngu, siis kasutame j\u00e4rgmisi pilte. Tegelikult pole \u00fcldse vahet, mis pilte kasutada - v\u00f5id vabalt proovida m\u00f5ne oma pildiga.\r\n\r\nMeie taustapilt:\r\n\r\n[caption id=\"attachment_917\" align=\"alignnone\" width=\"640\"]<img class=\"size-full wp-image-917\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space.png\" alt=\"Pilt planeedi ja raketiga kosmoses\" width=\"640\" height=\"640\" \/> Allikas: https:\/\/pixabay.com\/[\/caption]\r\n\r\nMeie tegelase pilt:\r\n\r\n[caption id=\"attachment_918\" align=\"alignnone\" width=\"64\"]<img class=\"size-full wp-image-918\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/rocket_small.png\" alt=\"V\u00e4ike rakett\" width=\"64\" height=\"62\" \/> Pildi allikas: <a href=\"https:\/\/pixabay.com\/\">https:\/\/pixabay.com\/<\/a>[\/caption]\r\n\r\nTegelase pilt on l\u00e4bipaistva taustaga, et taustapilt paistaks ilusti tema \u00fcmbert v\u00e4lja. Muidu pildid ise on ristk\u00fcliku kujulised. Kui pildi taust ei oleks l\u00e4bipaistev, siis oleks tegelane ka alati ristk\u00fcliku kujuline.\r\n\r\nVaatame, kuidas pildi liikumine peaks v\u00e4lja n\u00e4gema:\r\n\r\n<img class=\"alignnone size-large wp-image-919\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-1024x756.png\" alt=\"Raketi liikumine\" width=\"1024\" height=\"756\" \/>\r\n\r\nPildil on n\u00e4ha akna raam. Akna sisu on pind, millel v\u00f5ib omakorda olla taustapilt (seda teeme hiljem koodis, selguse m\u00f5ttes siin on taust valge). Pildi \u00fcmber olev punktiirjoon t\u00e4histab selle piirjooni. Tegelikult pildil neid jooni n\u00e4ha ei ole.\r\n\r\nAlustame sellest, et lisame pildi positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">(left,<\/span> <span class=\"pre\">top)<\/span><\/code>. Need on ka joonisel nooltega t\u00e4histatud. Kui tahame raketti liigutada paremale, siis joonistame selle pildi teatud hulga pikslite v\u00f5rra paremale - n\u00e4iteks positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">(left<\/span> <span class=\"pre\">+<\/span> <span class=\"pre\">100,<\/span> <span class=\"pre\">top)<\/span><\/code>. Kui me seda teeme, siis on ekraanil kaks raketti - algne ja liigutatud rakett. Selleks, et kasutaja jaoks oleks n\u00e4ha vaid \u00fcks rakett, peame vana \"kustutama\". Nagu eelnevalt kirjeldasime, siis toimub pikslite v\u00e4\u00e4rtuste muutmine. Selleks, et vasakpoolne rakett \u00e4ra kaoks, peame selle \u00fcle v\u00e4rvima. Kuna hetkel on meil taust valge, siis piisab, kui v\u00e4rvime selle ala valgega. Kui taustal oleks pilt, peaksime selle ala t\u00e4itma t\u00e4pselt selle osaga taustapildist. Alguses v\u00f5ib lihtsam olla see, et v\u00e4rvime kogu tausta korraga \u00e4ra - see on aeglasem, aga ei pruugi esialgu meie m\u00e4ngu m\u00f5jutada. Siin paljudes n\u00e4idetes oleme lihtsuse m\u00f5ttes terve tausta korraga \u00fcle v\u00e4rvinud. Aga teeme siin \u00fche t\u00e4psema n\u00e4ite.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((640, 640))\r\n\r\nbg = pygame.image.load(\"background_space.png\")\r\nrocket = pygame.image.load(\"rocket_small.png\")\r\n# rocket rectangle &lt;rect(0, 0, 64, 62)&gt;\r\nrocket_rect = rocket.get_rect()\r\n# we will use this rectangle to position the rocket, therefore let's set y value\r\nrocket_rect.y = 150\r\n\r\n# game surface with background image\r\nscreen.blit(bg, (0, 0))\r\n\r\n# set up a clock in order to control the flow of time\r\nclock = pygame.time.Clock()\r\n\r\nrunning = True\r\nwhile running:\r\n    for event in pygame.event.get():\r\n        if event.type == pygame.QUIT:\r\n            # closing window finishes the game loop\r\n            running = False\r\n\r\n    # \"erase\" the current rocket\r\n    screen.blit(bg, rocket_rect, rocket_rect)\r\n    # change rocket position (x = x + 2)\r\n    rocket_rect = rocket_rect.move(2, 0)\r\n    # draw a rocket to a new position\r\n    screen.blit(rocket, rocket_rect)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n    \r\n    # keep the program running at 30 FPS\r\n    clock.tick(30)\r\n<\/pre>\r\n&nbsp;\r\n\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">blit<\/span><\/code> funktsiooni saab v\u00e4lja kutsuda kujul <code class=\"docutils literal notranslate\"><span class=\"pre\">destination.blit(source,<\/span> <span class=\"pre\">destination_position)<\/span><\/code>. See t\u00e4hendab, et <code class=\"docutils literal notranslate\"><span class=\"pre\">destination<\/span><\/code> pinnale lisatakse <code class=\"docutils literal notranslate\"><span class=\"pre\">source<\/span><\/code> pind (n\u00e4iteks pilt) positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">destination_position<\/span><\/code>. Positsioon t\u00e4histab \u00e4ra pikslite arvu vasakult ja \u00fclevalt sihtkoha pinna \u00fclevalt vasakult \u00e4\u00e4rest. Positsioon v\u00f5ib olla kujul <code class=\"docutils literal notranslate\"><span class=\"pre\">(left,<\/span> <span class=\"pre\">top)<\/span><\/code>, aga seal v\u00f5ib kasutada ka <code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objekti. <code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objektil on lisaks \u00fclemise vasakpoolse punkti koordinaadile (<code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code>) ka laius ja k\u00f5rgus. Ristk\u00fcliku kasutamise puhul v\u00f5etakse sealt vaid <code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code> v\u00e4\u00e4rtused. Meie n\u00e4ites teeme samamoodi, et kasutame ristk\u00fclikut raketi paigutamiseks.\r\n\r\nVaatame, mida eelnev kood t\u00e4psemalt teeb:\r\n<ul class=\"simple\">\r\n \t<li>Koodin\u00e4ite alguses loeme sisse kahe pildi andmed. Taustapildi salvestame <code class=\"docutils literal notranslate\"><span class=\"pre\">bg<\/span><\/code> muutujasse ja raketi pildi salvestame <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket<\/span><\/code> muutujasse.<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">rocket.get_rect()<\/span><\/code> - k\u00fcsime raketi pildi ristk\u00fcliku objekti. See tagastab ristk\u00fcliku, mille \u00fclemine vasakpoolne tipp on koordinaadil <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code> ning millel on pildi laius ja k\u00f5rgus. Seega saame konkreetselt sellise tulemuse: <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;rect(0,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">64,<\/span> <span class=\"pre\">62)&gt;<\/span><\/code>. Seega meie pildi laius on 64 pikslit ja k\u00f5rgus 62 pikslit.<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect.y<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">150<\/span><\/code> - kuna eelnevalt k\u00fcsitud ristk\u00fcliku koordinaat oli <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code>, siis muudame k\u00f5rguse \u00e4ra. Kasutame seda <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> muutujat selleks, et joonistada rakett ekraanile. Hetkel siis rakett ei alusta p\u00e4ris \u00fclevalt \u00e4\u00e4rest, vaid 150 pikslit altpoolt.<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">screen.blit(bg,<\/span> <span class=\"pre\">(0,<\/span> <span class=\"pre\">0))<\/span><\/code> - lisame taustapildi ekraanile positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code>. Akna m\u00f5\u00f5dud oleme valinud vastavalt taustapildile. Seega kogu m\u00e4nguala t\u00e4idetakse meie taustapildiga.<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">clock<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">pygame.time.Clock()<\/span><\/code> - loome <code class=\"docutils literal notranslate\"><span class=\"pre\">Clock<\/span><\/code> objekti selleks, et hiljem saaks m\u00e4ngu tempot m\u00e4\u00e4rata. See on vajalik selleks, et m\u00e4nguts\u00fckli t\u00e4itmine ei toimuks liiga kiiresti. Muidu meie rakett liiguks liiga kiiresti ekraanilt v\u00e4lja.<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">screen.blit(bg,<\/span> <span class=\"pre\">rocket_rect,<\/span> <span class=\"pre\">rocket_rect)<\/span><\/code> - \"kustutame\" vana raketi pildi. T\u00e4psemalt toimub see, et taustapildilt v\u00f5etakse <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> ristk\u00fclik (t\u00e4pselt see osa, kus rakett praegu on). See v\u00f5etud ristk\u00fclik paigutatakse ekraanile sellele positsioonile, mis on m\u00e4\u00e4ratud <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> ristk\u00fclikuga. Kuna meil taustapilt on paigutatud katma tervet ekraani, siis siin saab t\u00e4pselt sama ristk\u00fclikut kasutada. Teine argument <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> t\u00e4histab positsiooni (<code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objektist v\u00f5etakse vaid \u00fclemaise vasakpoolse punkti koordinaadid), kuhu paigutatakse pilt. Kolmas argument <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> t\u00e4histab ristk\u00fclikut (seekord koos alguspunkti ning k\u00f5rguse ja laiusega), mis \"l\u00f5igatakse\" v\u00e4lja <code class=\"docutils literal notranslate\"><span class=\"pre\">bg<\/span><\/code> pildilt. Seega t\u00e4pselt see osa, mis j\u00e4\u00e4b raketi alla, kopeeritakse taustapildilt ekraanile. Selle tulemusena joonistatakse rakett \u00fcle, ehk siis rakett \"kustutatakse\". Peale seda rida raketti enam ekraanil n\u00e4ha ei ole (tegelikult seda sammu me p\u00e4riselt ei n\u00e4e, kuna k\u00f5ik toimub n\u00e4idatakse v\u00e4lja <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.flip()<\/span><\/code> v\u00e4ljakutsega ts\u00fckli l\u00f5pus).<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">rocket_rect.move(2,<\/span> <span class=\"pre\">0)<\/span><\/code> - muudame raketi ristk\u00fcliku positsiooni nii, et ta liigub kaks piksli paremale. Ehk siis <code class=\"docutils literal notranslate\"><span class=\"pre\">x<\/span><\/code> koordinaati suurendame kahe v\u00f5rra. K\u00f5rgus j\u00e4\u00e4b paigale (muudetakse 0 piksli v\u00f5rra). <code class=\"docutils literal notranslate\"><span class=\"pre\">move<\/span><\/code> meetod ei muuda ristk\u00fclikut, vaid loob uue, seep\u00e4rast peame tulemuse salvestama <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> muutujasse (kirjutame selle \u00fcle).<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">screen.blit(rocket,<\/span> <span class=\"pre\">rocket_rect)<\/span><\/code> - joonistame raketi pildi uuele positsioonile (mis on eelmise positsiooniga v\u00f5rreldes 2 piksli v\u00f5rra paremal).<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.flip()<\/span><\/code> - k\u00f5ik tehtud muudatused n\u00e4idatakse kasutajale.<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">clock.tick(30)<\/span><\/code> - m\u00e4\u00e4rame FPS (<em>frames per second<\/em>) v\u00e4\u00e4rtuse. PyGame vajadusel ootab siin natuke selleks, et ts\u00fckli samm ei t\u00f6\u00f6taks liiga kiiresti. M\u00e4\u00e4ratud v\u00e4\u00e4rtus t\u00e4hendab, et PyGame ootab piisavalt, et kaadrite arv sekundis ei \u00fcletaks seda v\u00e4\u00e4rtust.<\/li>\r\n<\/ul>\r\n\r\nM\u00e4ngu tempo m\u00e4\u00e4ramisest l\u00fchike video:\r\n\r\n[embed]https:\/\/www.youtube.com\/embed\/HgXXHhPbi3s[\/embed]\r\n\r\n<div class=\"admonition-harjutus admonition\">\r\n<div class=\"textbox textbox--exercises\"><header class=\"textbox__header\">\r\n<p class=\"textbox__title\">Harjutus<\/p>\r\n\r\n<\/header>\r\n<div class=\"textbox__content\">Proovi koodi muuta nii, et muutub liikuva objekti alguspositsioon ning liikumiskiirus. N\u00e4iteks v\u00f5iks objekt liikuda ka diagonaalis.<\/div>\r\n<\/div>\r\n<div class=\"textbox textbox--exercises\"><header class=\"textbox__header\">\r\n<p class=\"textbox__title\">Harjutus<\/p>\r\n\r\n<\/header>\r\n<div class=\"textbox__content\">\r\n\r\nProovi koodi muuta nii, et eksisteerib ka teine liikuv objekt, mis liigub teises suunas teise kiirusega.\r\n\r\nSelleks tuleb lisada teine pilt. V\u00f5ib ka sama pilti kasutada, aga siis on vaja eraldi <code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objekti, n\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">enemy_rect<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">rocket.get_rect()<\/span><\/code>. Seej\u00e4rel saab <code class=\"docutils literal notranslate\"><span class=\"pre\">enemy_rect<\/span><\/code> objektil muuta n\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">x<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">y<\/span><\/code> v\u00e4\u00e4rtust ning kasutada seda pildi \"kustutamiseks\" ning joonistamiseks ekraanile.\r\n\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/section><section id=\"kujundite-joonistamine\">\r\n<h2 id=\"kujundite-joonistamine\">Kujundite joonistamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#kujundite-joonistamine\">\uf0c1<\/a><\/h2>\r\nJoonistamiseks kasutame moodulit <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.draw<\/span><\/code>. Selles moodulis on funktsioonid erinevate kujundite joonistamiseks:\r\n<ul class=\"simple\">\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rect<\/span><\/code> - ristk\u00fclik<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">polygon<\/span><\/code> - hulknurk<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">circle<\/span><\/code> - ring<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">ellipse<\/span><\/code> - ellips<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">arc<\/span><\/code> - kaar<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">line<\/span><\/code> - sirgjoon<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">lines<\/span><\/code> - mitu \u00fchendatud sirgjoont<\/li>\r\n<\/ul>\r\nNende kujundite joonistamisel antakse funktsioonile kaasa pind, millele kujund joonistada. \u00dchtlasi saab kaasa anda v\u00e4rvi ja tavaliselt ka joone j\u00e4meduse.\r\n\r\nTeeme \u00fche n\u00e4ite, kus joonistame ekraanile \u00fche sinise ringi ja rohelise ristk\u00fcliku.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((800, 600))\r\n\r\nrunning = True\r\nwhile running:\r\n    for event in pygame.event.get():\r\n        if event.type == pygame.QUIT:\r\n            # closing window finishes the game loop\r\n            running = False\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n    \r\n    # draw a blue circle at (100, 100) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (100, 100), 50)\r\n    \r\n    # draw a green rectangle at (200, 100) with width 300, height 100\r\n    pygame.draw.rect(screen, (0, 255, 0), (200, 100, 300, 100))\r\n    \r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\r\n&nbsp;\r\n\r\n<\/section><section id=\"ristkuliku-joonistamine\">\r\n<h2 id=\"ristkuliku-joonistamine\">Ristk\u00fcliku joonistamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#ristkuliku-joonistamine\">\uf0c1<\/a><\/h2>\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.draw.rect(surface,<\/span> <span class=\"pre\">color,<\/span> <span class=\"pre\">rect,<\/span> <span class=\"pre\">width=0)<\/span><\/code>\r\n\r\nParameetrid:\r\n<ul>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">surface<\/span><\/code> - pind, millele joonistada<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">color<\/span><\/code> - v\u00e4rv (vt <a class=\"reference internal\" href=\"#color\"><span class=\"std std-ref\">V\u00e4rvid<\/span><\/a>)<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rect<\/span><\/code> - ristk\u00fcliku asukoht ja parameetrid. Need v\u00f5ivad olla j\u00e4rgmisel kujul:\r\n<ul class=\"simple\">\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">(left,<\/span> <span class=\"pre\">top,<\/span> <span class=\"pre\">width,<\/span> <span class=\"pre\">height)<\/span><\/code> - ennik (<em>tuple<\/em>) nelja v\u00e4\u00e4rtusega;<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">((left,<\/span> <span class=\"pre\">top),<\/span> <span class=\"pre\">(width,<\/span> <span class=\"pre\">height))<\/span><\/code> - kaks ennikut: esimeses on alguspunkti koordinaadid, teises on ristk\u00fcliku laius ja k\u00f5rgus;<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objekt<\/li>\r\n<\/ul>\r\n<div class=\"line-block\">\r\n<div class=\"line\">eelnevalt kasutatud v\u00e4\u00e4rtused:<\/div>\r\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> - pikslite arv vasakult \u00e4\u00e4rest<\/div>\r\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code> - pikslite arv \u00fclemisest \u00e4\u00e4rest<\/div>\r\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">width<\/span><\/code> - ristk\u00fcliku laius pikslites<\/div>\r\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">height<\/span><\/code> - ristk\u00fcliku k\u00f5rgus pikslites<\/div>\r\n<\/div><\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">width<\/span><\/code> - piirjoone j\u00e4medus pikslites. Vaikimisi v\u00e4\u00e4rtus on 0. Kui v\u00e4\u00e4rtus on 0, siis v\u00e4rvitakse kujund \u00fcleni m\u00e4rgitud v\u00e4rviga \u00e4ra. Muul juhul on v\u00e4rvitud vaid piirjoon vastava j\u00e4medusega.<\/li>\r\n<\/ul>\r\n<\/section><section id=\"varvid\"><span id=\"color\"><\/span>\r\n<h2 id=\"varvid\">V\u00e4rvid<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#varvid\">\uf0c1<\/a><\/h2>\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">Color(r,<\/span> <span class=\"pre\">g,<\/span> <span class=\"pre\">b,<\/span> <span class=\"pre\">a=255)<\/span><\/code>\r\n\r\nV\u00e4rvide esitamiseks kasutakse RGBA koode. RGB t\u00e4histab kolme v\u00e4rvi: punane (<em>Red<\/em>), roheline (<em>Green<\/em>) ja sinine (<em>Blue<\/em>). L\u00fchend tuleneb v\u00e4rvide inglisekeelsete s\u00f5nade esit\u00e4htedest. Neljas t\u00e4ht A t\u00e4histab l\u00e4bipaistvust (<em>Alpha<\/em>). Vaikimisi <code class=\"docutils literal notranslate\"><span class=\"pre\">a<\/span><\/code> v\u00e4\u00e4rtus on <code class=\"docutils literal notranslate\"><span class=\"pre\">255<\/span><\/code>, mis t\u00e4hendab, et l\u00e4bipaistvust ei ole. Teine \u00e4\u00e4rmus on <code class=\"docutils literal notranslate\"><span class=\"pre\">0<\/span><\/code>, kus v\u00e4rv on 100% l\u00e4bipaistev. Vahepealsete v\u00e4\u00e4rtustega saab osaliselt l\u00e4bipaistvat v\u00e4rvi luua. RGB v\u00e4\u00e4rtused on samamoodi vahemikus <code class=\"docutils literal notranslate\"><span class=\"pre\">0<\/span> <span class=\"pre\">-<\/span> <span class=\"pre\">255<\/span><\/code> (kaasa arvatud). V\u00e4\u00e4rtus n\u00e4itab, millise intensiivsusega vastavat v\u00e4rvi kasutatakse. N\u00e4iteks (ere)punase v\u00e4rvi jaoks m\u00e4\u00e4rame <code class=\"docutils literal notranslate\"><span class=\"pre\">r<\/span><\/code> v\u00e4\u00e4rtuse maksimaalseks (255) ja teised minimaalseks (0).\r\n\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">Color(color_value)<\/span><\/code>\r\n\r\nV\u00e4rvi v\u00f5ib m\u00e4\u00e4rata ka s\u00f5nena. V\u00f5imalikud vormingud:\r\n<ul class=\"simple\">\r\n \t<li>v\u00e4rvi nimi, n\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">\"red\"<\/span><\/code>. V\u00f5imalikud v\u00e4rvid on v\u00e4lja toodud siin: <a class=\"reference external\" href=\"https:\/\/www.pygame.org\/docs\/ref\/color_list.html\">https:\/\/www.pygame.org\/docs\/ref\/color_list.html<\/a><\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">\"#rrggbbaa\"<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#rrggbb\"<\/span><\/code>, kus t\u00e4hed t\u00e4histavad analoogselt punase, rohelise, sinise ja l\u00e4bipaistvuse v\u00e4\u00e4rtusi. Siin kasutatakse kuuteistk\u00fcmnendnumbreid. N\u00e4iteks (ere)punase jaoks: <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#ff0000\"<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FF0000\"<\/span><\/code>.<\/li>\r\n<\/ul>\r\nM\u00f5ned n\u00e4ited:\r\n<ul>\r\n \t<li>Punane v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(255,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FF0000\"<\/span><\/code>\r\n<div style=\"width: 100px;height: 40px;background-color: #ff0000\"><\/div><\/li>\r\n \t<li>Roheline v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">255,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#00FF00\"<\/span><\/code>\r\n<div style=\"width: 100px;height: 40px;background-color: #00ff00\"><\/div><\/li>\r\n \t<li>Sinine v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">255)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#0000FF\"<\/span><\/code>\r\n<div style=\"width: 100px;height: 40px;background-color: #0000ff\"><\/div><\/li>\r\n \t<li>Kollane v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(255,<\/span> <span class=\"pre\">255,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FFFF00\"<\/span><\/code>\r\n<div style=\"width: 100px;height: 40px;background-color: #ffff00\"><\/div><\/li>\r\n \t<li>Must v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#000000\"<\/span><\/code>\r\n<div style=\"width: 100px;height: 40px;background-color: #000000\"><\/div><\/li>\r\n \t<li>Valge v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(255,<\/span> <span class=\"pre\">255,<\/span> <span class=\"pre\">255)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FFFFFF\"<\/span><\/code>\r\n<div style=\"width: 100px;height: 40px;background-color: #ffffff\"><\/div><\/li>\r\n \t<li>Hall v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(128,<\/span> <span class=\"pre\">128,<\/span> <span class=\"pre\">128)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#808080\"<\/span><\/code>\r\n<div style=\"width: 100px;height: 40px;background-color: #808080\"><\/div><\/li>\r\n<\/ul>\r\n<h2>M\u00f5tle ja nuputa!<\/h2>\r\n[h5p id=\"44\"]\r\n\r\n<\/section>","rendered":"<p>PyGame&#8217;is toimub visuaalse pildi joonistamine n-\u00f6 joonistamispinnale (<em>surface<\/em>). Pind on ristk\u00fcliku kujuline ala, millele saab joonistada ja pilte lisada. <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.set_mode()<\/span><\/code> funktsiooniga luuakse \u00fcks eriline pind, mis t\u00e4histab kogu m\u00e4ngu n\u00e4htavat osa. Seda loodud pinda kasutatakse, et sinna m\u00e4ngukomponente joonistada.<\/p>\n<p>Pinna sisu luuakse valmis m\u00e4nguts\u00fckli jooksul ning tavaliselt ts\u00fckli l\u00f5pus n\u00e4idatakse see v\u00e4lja kasutajale <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.flip()<\/span><\/code> funktsiooniga. N\u00e4iteks m\u00e4ngija tegelane liigub ja vastane liigub. See sisuliselt t\u00e4hendab, et pinna peal muudetakse m\u00e4ngija pildi\/kujundi asukohta ja vastase pildi\/kujundi asukohta. Asukoha muutmine t\u00e4hendab seda, et vana pilt\/kujund tuleb &#8220;kustutada&#8221; ja uus tuleb uuele positsioonile &#8220;joonistada&#8221;. Kui need sammud on tehtud, siis kutsutakse v\u00e4lja funktsioon, mis n\u00e4itab muudatused ekraanile. Kui iga muudatus j\u00f5uaks kohe ekraanile, toimub v\u00e4ga palju visuaali muutmist (korra kustutatakse tegelane \u00e4ra ja siis joonistatakse uuesti), mis on m\u00e4ngijale ebamugav. PyGame&#8217;i puhul aga teeme muudatuse olekutes \u00e4ra ning <code class=\"docutils literal notranslate\"><span class=\"pre\">flip()<\/span><\/code> funktsiooniga n\u00e4idatakse need korraga v\u00e4lja.<\/p>\n<p><iframe loading=\"lazy\" id=\"oembed-1\" title=\"PyGame: Joonistamine\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/PUAzPUY4flA?feature=oembed&#38;rel=0\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<section id=\"pindade-kasutamine\">\n<h2 id=\"pindade-kasutamine\">Pindade kasutamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#pindade-kasutamine\">\uf0c1<\/a><\/h2>\n<p>Kui eelnevalt r\u00e4\u00e4kisime peamisest pinnast, mida n\u00e4idatakse aknas kasutajale, siis PyGame&#8217;is saab luua t\u00e4iendavaid pindu. Selleks saab kasutada <code class=\"docutils literal notranslate\"><span class=\"pre\">Surface<\/span><\/code> klassi. See annab v\u00f5imaluse t\u00e4psemalt juhtida, millist osa ekraanist on vaja uuendada. N\u00e4iteks v\u00f5ib kogu aken olla jagatud mitmeks osaks. \u00dches osas on m\u00e4ng, teises on men\u00fc\u00fc, kolmandas on m\u00e4ngija parameetrid. Sellisel juhul men\u00fc\u00fcd ja m\u00e4ngija parameetreid ei pea pidevalt uuendama. Kui m\u00e4ng on eraldi pinnal, siis on seda mugavam hallata ja m\u00e4ng t\u00f6\u00f6tab ka kiiremini.<\/p>\n<p>Loodav pind tuleb alati lisada m\u00f5ne teise pinna peale. \u00dcldiselt lisatakse loodav pind peamise pinna peale (mida <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.set_mode()<\/span><\/code> funktsiooniga loome). Aga on v\u00f5imalik ka nii, et peamise pinna peal on pind (n\u00e4iteks m\u00e4ngupind) ja selle peal on omakorda m\u00f5ni pind (m\u00e4ngija tegelane v\u00f5i vastase tegelane). Seega pind tuleb lisada teise pinna peale. Lisatav pind j\u00e4\u00e4b ekraanil esiplaanile taustapinna suhtes. Ehk kui peamine pind on must, aga sinna lisatakse valge m\u00e4ngupind, siis valge m\u00e4ngupind katab terves m\u00e4ngupinna ulatuses musta pinna valgega.<\/p>\n<p>Pinna lisamine teise pinna peale toimub funktsiooniga <code class=\"docutils literal notranslate\"><span class=\"pre\">parent_surface.blit(child_surface,<\/span> <span class=\"pre\">(left,<\/span> <span class=\"pre\">top))<\/span><\/code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">child_surface<\/span><\/code> pind lisatakse <code class=\"docutils literal notranslate\"><span class=\"pre\">parent_surface<\/span><\/code> pinna peale asukohale <code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> pikslit vasakult ja <code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code> pikslit \u00fclevalt \u00e4\u00e4rest. Need koordinaadid on arvestatud <code class=\"docutils literal notranslate\"><span class=\"pre\">parent_surface<\/span><\/code> pinna suhtes.<\/p>\n<p>Siin on \u00fcks koodin\u00e4ide:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((800, 600))\r\n\r\nrunning = True\r\nwhile running:\r\n    for event in pygame.event.get():\r\n        if event.type == pygame.QUIT:\r\n            # closing window finishes the game loop\r\n            running = False\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # game surface\r\n    game_surface = pygame.Surface((600, 500))\r\n    game_surface.fill((128, 0, 0))\r\n    screen.blit(game_surface, (0, 0))\r\n\r\n    # player info surface\r\n    player_info_surface = pygame.Surface((200, 500))\r\n    player_info_surface.fill((0, 0, 0))\r\n    # put it on the right side\r\n    screen.blit(player_info_surface, (600, 0))\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\n<p>Tulemus peaks olema j\u00e4rgmine:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-916\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-1024x808.png\" alt=\"Ekraanide n\u00e4ide\" width=\"1024\" height=\"808\" srcset=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-1024x808.png 1024w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-300x237.png 300w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-768x606.png 768w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-65x51.png 65w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-225x177.png 225w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example-350x276.png 350w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/surface_example.png 1401w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>Koodis luuakse <code class=\"docutils literal notranslate\"><span class=\"pre\">game_surface<\/span><\/code> pind, mis lisatakse ekraanile vasakusse \u00fclemisse \u00e4\u00e4rde <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code>. Seej\u00e4rel luuakse m\u00e4ngija andmete pind, mis lisatakse m\u00e4nguala k\u00f5rvale. Kuna m\u00e4nguala laius on 600 pikslit, siis paigutatakse m\u00e4ngija andmete pind 600 piksli kaugusele vasakust \u00e4\u00e4rest.<\/p>\n<p>N\u00fc\u00fcd kui m\u00e4ngus midagi muutub, ei pea me tervet akent \u00fcle v\u00e4rvima. Piisab vaid m\u00e4nguala \u00fcle v\u00e4rvimisest. Tegelikult saab asju veel optimaalsemalt teha &#8211; saab \u00fcle v\u00e4rvida vaid selle osa, mis on muutunud. See annab teatud olukorras arvestatava kiirusev\u00f5idu. Kuigi esialgu m\u00e4ngutegemise juures ei ole see nii oluline. Kui kohe algusest peale proovid asju optimeerida, v\u00f5ib m\u00e4ngutegemise l\u00f5bu \u00e4ra kaduda. Pigem tegele optimeerimisega siis, kui see probleem tekib.<\/p>\n<h2>M\u00f5tle ja nuputa!<\/h2>\n<div id=\"h5p-43\">\n<div class=\"h5p-iframe-wrapper\"><iframe id=\"h5p-iframe-43\" class=\"h5p-iframe\" data-content-id=\"43\" style=\"height:1px\" src=\"about:blank\" frameBorder=\"0\" scrolling=\"no\" title=\"Pygame (pinna sisu kuvamine)\"><\/iframe><\/div>\n<\/div>\n<\/section>\n<section id=\"pildi-kasutamine\">\n<h2 id=\"pildi-kasutamine\">Pildi kasutamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#pildi-kasutamine\">\uf0c1<\/a><\/h2>\n<p>Tavaliselt m\u00e4ngus me ei kasuta igavaid v\u00e4rvilisi kaste, vaid taustapilti. Samamoodi m\u00e4ngu tegelane on pilt. PyGame&#8217;is pilt on samamoodi pind (<em>surface<\/em>). Seega v\u00e4ga palju sellest, mida eelnevalt kirjeldasime, rakendub ka piltide kohta.<\/p>\n<p>Kogu ekraanil paistev visuaal on tegelikult pilt. Vahet pole, kas me joonistame ringe, loome uue pinna v\u00f5i lisame pilte. L\u00f5puks PyGame joonistab pildi. Pilt ise on tegelikult pikslite kogum. Seega v\u00f5ib \u00f6elda, et m\u00e4ngu jooksul me peame muutma pikslite v\u00e4\u00e4rtust (v\u00e4rvi) ja seel\u00e4bi n\u00e4eb m\u00e4ngija asju liikumas ja muutumas.<\/p>\n<p>Teeme \u00fche lihtsa n\u00e4ite, kus meil m\u00e4ngus on taustapilt ja selle peal liigub tegelane. Kuna plaanime teha kosmoseteemalist m\u00e4ngu, siis kasutame j\u00e4rgmisi pilte. Tegelikult pole \u00fcldse vahet, mis pilte kasutada &#8211; v\u00f5id vabalt proovida m\u00f5ne oma pildiga.<\/p>\n<p>Meie taustapilt:<\/p>\n<figure id=\"attachment_917\" aria-describedby=\"caption-attachment-917\" style=\"width: 640px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-917\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space.png\" alt=\"Pilt planeedi ja raketiga kosmoses\" width=\"640\" height=\"640\" srcset=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space.png 640w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space-300x300.png 300w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space-150x150.png 150w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space-65x65.png 65w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space-225x225.png 225w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/background_space-350x350.png 350w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption id=\"caption-attachment-917\" class=\"wp-caption-text\">Allikas: https:\/\/pixabay.com\/<\/figcaption><\/figure>\n<p>Meie tegelase pilt:<\/p>\n<figure id=\"attachment_918\" aria-describedby=\"caption-attachment-918\" style=\"width: 64px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-918\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/rocket_small.png\" alt=\"V\u00e4ike rakett\" width=\"64\" height=\"62\" \/><figcaption id=\"caption-attachment-918\" class=\"wp-caption-text\">Pildi allikas: <a href=\"https:\/\/pixabay.com\/\">https:\/\/pixabay.com\/<\/a><\/figcaption><\/figure>\n<p>Tegelase pilt on l\u00e4bipaistva taustaga, et taustapilt paistaks ilusti tema \u00fcmbert v\u00e4lja. Muidu pildid ise on ristk\u00fcliku kujulised. Kui pildi taust ei oleks l\u00e4bipaistev, siis oleks tegelane ka alati ristk\u00fcliku kujuline.<\/p>\n<p>Vaatame, kuidas pildi liikumine peaks v\u00e4lja n\u00e4gema:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-919\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-1024x756.png\" alt=\"Raketi liikumine\" width=\"1024\" height=\"756\" srcset=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-1024x756.png 1024w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-300x222.png 300w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-768x567.png 768w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-65x48.png 65w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-225x166.png 225w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image-350x258.png 350w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/move_image.png 1086w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>Pildil on n\u00e4ha akna raam. Akna sisu on pind, millel v\u00f5ib omakorda olla taustapilt (seda teeme hiljem koodis, selguse m\u00f5ttes siin on taust valge). Pildi \u00fcmber olev punktiirjoon t\u00e4histab selle piirjooni. Tegelikult pildil neid jooni n\u00e4ha ei ole.<\/p>\n<p>Alustame sellest, et lisame pildi positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">(left,<\/span> <span class=\"pre\">top)<\/span><\/code>. Need on ka joonisel nooltega t\u00e4histatud. Kui tahame raketti liigutada paremale, siis joonistame selle pildi teatud hulga pikslite v\u00f5rra paremale &#8211; n\u00e4iteks positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">(left<\/span> <span class=\"pre\">+<\/span> <span class=\"pre\">100,<\/span> <span class=\"pre\">top)<\/span><\/code>. Kui me seda teeme, siis on ekraanil kaks raketti &#8211; algne ja liigutatud rakett. Selleks, et kasutaja jaoks oleks n\u00e4ha vaid \u00fcks rakett, peame vana &#8220;kustutama&#8221;. Nagu eelnevalt kirjeldasime, siis toimub pikslite v\u00e4\u00e4rtuste muutmine. Selleks, et vasakpoolne rakett \u00e4ra kaoks, peame selle \u00fcle v\u00e4rvima. Kuna hetkel on meil taust valge, siis piisab, kui v\u00e4rvime selle ala valgega. Kui taustal oleks pilt, peaksime selle ala t\u00e4itma t\u00e4pselt selle osaga taustapildist. Alguses v\u00f5ib lihtsam olla see, et v\u00e4rvime kogu tausta korraga \u00e4ra &#8211; see on aeglasem, aga ei pruugi esialgu meie m\u00e4ngu m\u00f5jutada. Siin paljudes n\u00e4idetes oleme lihtsuse m\u00f5ttes terve tausta korraga \u00fcle v\u00e4rvinud. Aga teeme siin \u00fche t\u00e4psema n\u00e4ite.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((640, 640))\r\n\r\nbg = pygame.image.load(\"background_space.png\")\r\nrocket = pygame.image.load(\"rocket_small.png\")\r\n# rocket rectangle &lt;rect(0, 0, 64, 62)&gt;\r\nrocket_rect = rocket.get_rect()\r\n# we will use this rectangle to position the rocket, therefore let's set y value\r\nrocket_rect.y = 150\r\n\r\n# game surface with background image\r\nscreen.blit(bg, (0, 0))\r\n\r\n# set up a clock in order to control the flow of time\r\nclock = pygame.time.Clock()\r\n\r\nrunning = True\r\nwhile running:\r\n    for event in pygame.event.get():\r\n        if event.type == pygame.QUIT:\r\n            # closing window finishes the game loop\r\n            running = False\r\n\r\n    # \"erase\" the current rocket\r\n    screen.blit(bg, rocket_rect, rocket_rect)\r\n    # change rocket position (x = x + 2)\r\n    rocket_rect = rocket_rect.move(2, 0)\r\n    # draw a rocket to a new position\r\n    screen.blit(rocket, rocket_rect)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n    \r\n    # keep the program running at 30 FPS\r\n    clock.tick(30)\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">blit<\/span><\/code> funktsiooni saab v\u00e4lja kutsuda kujul <code class=\"docutils literal notranslate\"><span class=\"pre\">destination.blit(source,<\/span> <span class=\"pre\">destination_position)<\/span><\/code>. See t\u00e4hendab, et <code class=\"docutils literal notranslate\"><span class=\"pre\">destination<\/span><\/code> pinnale lisatakse <code class=\"docutils literal notranslate\"><span class=\"pre\">source<\/span><\/code> pind (n\u00e4iteks pilt) positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">destination_position<\/span><\/code>. Positsioon t\u00e4histab \u00e4ra pikslite arvu vasakult ja \u00fclevalt sihtkoha pinna \u00fclevalt vasakult \u00e4\u00e4rest. Positsioon v\u00f5ib olla kujul <code class=\"docutils literal notranslate\"><span class=\"pre\">(left,<\/span> <span class=\"pre\">top)<\/span><\/code>, aga seal v\u00f5ib kasutada ka <code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objekti. <code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objektil on lisaks \u00fclemise vasakpoolse punkti koordinaadile (<code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code>) ka laius ja k\u00f5rgus. Ristk\u00fcliku kasutamise puhul v\u00f5etakse sealt vaid <code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code> v\u00e4\u00e4rtused. Meie n\u00e4ites teeme samamoodi, et kasutame ristk\u00fclikut raketi paigutamiseks.<\/p>\n<p>Vaatame, mida eelnev kood t\u00e4psemalt teeb:<\/p>\n<ul class=\"simple\">\n<li>Koodin\u00e4ite alguses loeme sisse kahe pildi andmed. Taustapildi salvestame <code class=\"docutils literal notranslate\"><span class=\"pre\">bg<\/span><\/code> muutujasse ja raketi pildi salvestame <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket<\/span><\/code> muutujasse.<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">rocket.get_rect()<\/span><\/code> &#8211; k\u00fcsime raketi pildi ristk\u00fcliku objekti. See tagastab ristk\u00fcliku, mille \u00fclemine vasakpoolne tipp on koordinaadil <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code> ning millel on pildi laius ja k\u00f5rgus. Seega saame konkreetselt sellise tulemuse: <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;rect(0,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">64,<\/span> <span class=\"pre\">62)&gt;<\/span><\/code>. Seega meie pildi laius on 64 pikslit ja k\u00f5rgus 62 pikslit.<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect.y<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">150<\/span><\/code> &#8211; kuna eelnevalt k\u00fcsitud ristk\u00fcliku koordinaat oli <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code>, siis muudame k\u00f5rguse \u00e4ra. Kasutame seda <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> muutujat selleks, et joonistada rakett ekraanile. Hetkel siis rakett ei alusta p\u00e4ris \u00fclevalt \u00e4\u00e4rest, vaid 150 pikslit altpoolt.<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">screen.blit(bg,<\/span> <span class=\"pre\">(0,<\/span> <span class=\"pre\">0))<\/span><\/code> &#8211; lisame taustapildi ekraanile positsioonile <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0)<\/span><\/code>. Akna m\u00f5\u00f5dud oleme valinud vastavalt taustapildile. Seega kogu m\u00e4nguala t\u00e4idetakse meie taustapildiga.<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">clock<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">pygame.time.Clock()<\/span><\/code> &#8211; loome <code class=\"docutils literal notranslate\"><span class=\"pre\">Clock<\/span><\/code> objekti selleks, et hiljem saaks m\u00e4ngu tempot m\u00e4\u00e4rata. See on vajalik selleks, et m\u00e4nguts\u00fckli t\u00e4itmine ei toimuks liiga kiiresti. Muidu meie rakett liiguks liiga kiiresti ekraanilt v\u00e4lja.<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">screen.blit(bg,<\/span> <span class=\"pre\">rocket_rect,<\/span> <span class=\"pre\">rocket_rect)<\/span><\/code> &#8211; &#8220;kustutame&#8221; vana raketi pildi. T\u00e4psemalt toimub see, et taustapildilt v\u00f5etakse <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> ristk\u00fclik (t\u00e4pselt see osa, kus rakett praegu on). See v\u00f5etud ristk\u00fclik paigutatakse ekraanile sellele positsioonile, mis on m\u00e4\u00e4ratud <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> ristk\u00fclikuga. Kuna meil taustapilt on paigutatud katma tervet ekraani, siis siin saab t\u00e4pselt sama ristk\u00fclikut kasutada. Teine argument <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> t\u00e4histab positsiooni (<code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objektist v\u00f5etakse vaid \u00fclemaise vasakpoolse punkti koordinaadid), kuhu paigutatakse pilt. Kolmas argument <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> t\u00e4histab ristk\u00fclikut (seekord koos alguspunkti ning k\u00f5rguse ja laiusega), mis &#8220;l\u00f5igatakse&#8221; v\u00e4lja <code class=\"docutils literal notranslate\"><span class=\"pre\">bg<\/span><\/code> pildilt. Seega t\u00e4pselt see osa, mis j\u00e4\u00e4b raketi alla, kopeeritakse taustapildilt ekraanile. Selle tulemusena joonistatakse rakett \u00fcle, ehk siis rakett &#8220;kustutatakse&#8221;. Peale seda rida raketti enam ekraanil n\u00e4ha ei ole (tegelikult seda sammu me p\u00e4riselt ei n\u00e4e, kuna k\u00f5ik toimub n\u00e4idatakse v\u00e4lja <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.flip()<\/span><\/code> v\u00e4ljakutsega ts\u00fckli l\u00f5pus).<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">rocket_rect.move(2,<\/span> <span class=\"pre\">0)<\/span><\/code> &#8211; muudame raketi ristk\u00fcliku positsiooni nii, et ta liigub kaks piksli paremale. Ehk siis <code class=\"docutils literal notranslate\"><span class=\"pre\">x<\/span><\/code> koordinaati suurendame kahe v\u00f5rra. K\u00f5rgus j\u00e4\u00e4b paigale (muudetakse 0 piksli v\u00f5rra). <code class=\"docutils literal notranslate\"><span class=\"pre\">move<\/span><\/code> meetod ei muuda ristk\u00fclikut, vaid loob uue, seep\u00e4rast peame tulemuse salvestama <code class=\"docutils literal notranslate\"><span class=\"pre\">rocket_rect<\/span><\/code> muutujasse (kirjutame selle \u00fcle).<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">screen.blit(rocket,<\/span> <span class=\"pre\">rocket_rect)<\/span><\/code> &#8211; joonistame raketi pildi uuele positsioonile (mis on eelmise positsiooniga v\u00f5rreldes 2 piksli v\u00f5rra paremal).<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.display.flip()<\/span><\/code> &#8211; k\u00f5ik tehtud muudatused n\u00e4idatakse kasutajale.<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">clock.tick(30)<\/span><\/code> &#8211; m\u00e4\u00e4rame FPS (<em>frames per second<\/em>) v\u00e4\u00e4rtuse. PyGame vajadusel ootab siin natuke selleks, et ts\u00fckli samm ei t\u00f6\u00f6taks liiga kiiresti. M\u00e4\u00e4ratud v\u00e4\u00e4rtus t\u00e4hendab, et PyGame ootab piisavalt, et kaadrite arv sekundis ei \u00fcletaks seda v\u00e4\u00e4rtust.<\/li>\n<\/ul>\n<p>M\u00e4ngu tempo m\u00e4\u00e4ramisest l\u00fchike video:<\/p>\n<p><iframe loading=\"lazy\" id=\"oembed-2\" title=\"PyGame: m\u00e4ngu aeg (Clock)\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/HgXXHhPbi3s?feature=oembed&#38;rel=0\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<div class=\"admonition-harjutus admonition\">\n<div class=\"textbox textbox--exercises\">\n<header class=\"textbox__header\">\n<p class=\"textbox__title\">Harjutus<\/p>\n<\/header>\n<div class=\"textbox__content\">Proovi koodi muuta nii, et muutub liikuva objekti alguspositsioon ning liikumiskiirus. N\u00e4iteks v\u00f5iks objekt liikuda ka diagonaalis.<\/div>\n<\/div>\n<div class=\"textbox textbox--exercises\">\n<header class=\"textbox__header\">\n<p class=\"textbox__title\">Harjutus<\/p>\n<\/header>\n<div class=\"textbox__content\">\n<p>Proovi koodi muuta nii, et eksisteerib ka teine liikuv objekt, mis liigub teises suunas teise kiirusega.<\/p>\n<p>Selleks tuleb lisada teine pilt. V\u00f5ib ka sama pilti kasutada, aga siis on vaja eraldi <code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objekti, n\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">enemy_rect<\/span> <span class=\"pre\">=<\/span> <span class=\"pre\">rocket.get_rect()<\/span><\/code>. Seej\u00e4rel saab <code class=\"docutils literal notranslate\"><span class=\"pre\">enemy_rect<\/span><\/code> objektil muuta n\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">x<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">y<\/span><\/code> v\u00e4\u00e4rtust ning kasutada seda pildi &#8220;kustutamiseks&#8221; ning joonistamiseks ekraanile.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n<section id=\"kujundite-joonistamine\">\n<h2 id=\"kujundite-joonistamine\">Kujundite joonistamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#kujundite-joonistamine\">\uf0c1<\/a><\/h2>\n<p>Joonistamiseks kasutame moodulit <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.draw<\/span><\/code>. Selles moodulis on funktsioonid erinevate kujundite joonistamiseks:<\/p>\n<ul class=\"simple\">\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rect<\/span><\/code> &#8211; ristk\u00fclik<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">polygon<\/span><\/code> &#8211; hulknurk<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">circle<\/span><\/code> &#8211; ring<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">ellipse<\/span><\/code> &#8211; ellips<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">arc<\/span><\/code> &#8211; kaar<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">line<\/span><\/code> &#8211; sirgjoon<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">lines<\/span><\/code> &#8211; mitu \u00fchendatud sirgjoont<\/li>\n<\/ul>\n<p>Nende kujundite joonistamisel antakse funktsioonile kaasa pind, millele kujund joonistada. \u00dchtlasi saab kaasa anda v\u00e4rvi ja tavaliselt ka joone j\u00e4meduse.<\/p>\n<p>Teeme \u00fche n\u00e4ite, kus joonistame ekraanile \u00fche sinise ringi ja rohelise ristk\u00fcliku.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((800, 600))\r\n\r\nrunning = True\r\nwhile running:\r\n    for event in pygame.event.get():\r\n        if event.type == pygame.QUIT:\r\n            # closing window finishes the game loop\r\n            running = False\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n    \r\n    # draw a blue circle at (100, 100) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (100, 100), 50)\r\n    \r\n    # draw a green rectangle at (200, 100) with width 300, height 100\r\n    pygame.draw.rect(screen, (0, 255, 0), (200, 100, 300, 100))\r\n    \r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\n<p>&nbsp;<\/p>\n<\/section>\n<section id=\"ristkuliku-joonistamine\">\n<h2 id=\"ristkuliku-joonistamine\">Ristk\u00fcliku joonistamine<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#ristkuliku-joonistamine\">\uf0c1<\/a><\/h2>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.draw.rect(surface,<\/span> <span class=\"pre\">color,<\/span> <span class=\"pre\">rect,<\/span> <span class=\"pre\">width=0)<\/span><\/code><\/p>\n<p>Parameetrid:<\/p>\n<ul>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">surface<\/span><\/code> &#8211; pind, millele joonistada<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">color<\/span><\/code> &#8211; v\u00e4rv (vt <a class=\"reference internal\" href=\"#color\"><span class=\"std std-ref\">V\u00e4rvid<\/span><\/a>)<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">rect<\/span><\/code> &#8211; ristk\u00fcliku asukoht ja parameetrid. Need v\u00f5ivad olla j\u00e4rgmisel kujul:\n<ul class=\"simple\">\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">(left,<\/span> <span class=\"pre\">top,<\/span> <span class=\"pre\">width,<\/span> <span class=\"pre\">height)<\/span><\/code> &#8211; ennik (<em>tuple<\/em>) nelja v\u00e4\u00e4rtusega;<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">((left,<\/span> <span class=\"pre\">top),<\/span> <span class=\"pre\">(width,<\/span> <span class=\"pre\">height))<\/span><\/code> &#8211; kaks ennikut: esimeses on alguspunkti koordinaadid, teises on ristk\u00fcliku laius ja k\u00f5rgus;<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">Rect<\/span><\/code> objekt<\/li>\n<\/ul>\n<div class=\"line-block\">\n<div class=\"line\">eelnevalt kasutatud v\u00e4\u00e4rtused:<\/div>\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">left<\/span><\/code> &#8211; pikslite arv vasakult \u00e4\u00e4rest<\/div>\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">top<\/span><\/code> &#8211; pikslite arv \u00fclemisest \u00e4\u00e4rest<\/div>\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">width<\/span><\/code> &#8211; ristk\u00fcliku laius pikslites<\/div>\n<div class=\"line\"><code class=\"docutils literal notranslate\"><span class=\"pre\">height<\/span><\/code> &#8211; ristk\u00fcliku k\u00f5rgus pikslites<\/div>\n<\/div>\n<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">width<\/span><\/code> &#8211; piirjoone j\u00e4medus pikslites. Vaikimisi v\u00e4\u00e4rtus on 0. Kui v\u00e4\u00e4rtus on 0, siis v\u00e4rvitakse kujund \u00fcleni m\u00e4rgitud v\u00e4rviga \u00e4ra. Muul juhul on v\u00e4rvitud vaid piirjoon vastava j\u00e4medusega.<\/li>\n<\/ul>\n<\/section>\n<section id=\"varvid\"><span id=\"color\"><\/span><\/p>\n<h2 id=\"varvid\">V\u00e4rvid<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#varvid\">\uf0c1<\/a><\/h2>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Color(r,<\/span> <span class=\"pre\">g,<\/span> <span class=\"pre\">b,<\/span> <span class=\"pre\">a=255)<\/span><\/code><\/p>\n<p>V\u00e4rvide esitamiseks kasutakse RGBA koode. RGB t\u00e4histab kolme v\u00e4rvi: punane (<em>Red<\/em>), roheline (<em>Green<\/em>) ja sinine (<em>Blue<\/em>). L\u00fchend tuleneb v\u00e4rvide inglisekeelsete s\u00f5nade esit\u00e4htedest. Neljas t\u00e4ht A t\u00e4histab l\u00e4bipaistvust (<em>Alpha<\/em>). Vaikimisi <code class=\"docutils literal notranslate\"><span class=\"pre\">a<\/span><\/code> v\u00e4\u00e4rtus on <code class=\"docutils literal notranslate\"><span class=\"pre\">255<\/span><\/code>, mis t\u00e4hendab, et l\u00e4bipaistvust ei ole. Teine \u00e4\u00e4rmus on <code class=\"docutils literal notranslate\"><span class=\"pre\">0<\/span><\/code>, kus v\u00e4rv on 100% l\u00e4bipaistev. Vahepealsete v\u00e4\u00e4rtustega saab osaliselt l\u00e4bipaistvat v\u00e4rvi luua. RGB v\u00e4\u00e4rtused on samamoodi vahemikus <code class=\"docutils literal notranslate\"><span class=\"pre\">0<\/span> <span class=\"pre\">-<\/span> <span class=\"pre\">255<\/span><\/code> (kaasa arvatud). V\u00e4\u00e4rtus n\u00e4itab, millise intensiivsusega vastavat v\u00e4rvi kasutatakse. N\u00e4iteks (ere)punase v\u00e4rvi jaoks m\u00e4\u00e4rame <code class=\"docutils literal notranslate\"><span class=\"pre\">r<\/span><\/code> v\u00e4\u00e4rtuse maksimaalseks (255) ja teised minimaalseks (0).<\/p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Color(color_value)<\/span><\/code><\/p>\n<p>V\u00e4rvi v\u00f5ib m\u00e4\u00e4rata ka s\u00f5nena. V\u00f5imalikud vormingud:<\/p>\n<ul class=\"simple\">\n<li>v\u00e4rvi nimi, n\u00e4iteks <code class=\"docutils literal notranslate\"><span class=\"pre\">\"red\"<\/span><\/code>. V\u00f5imalikud v\u00e4rvid on v\u00e4lja toodud siin: <a class=\"reference external\" href=\"https:\/\/www.pygame.org\/docs\/ref\/color_list.html\">https:\/\/www.pygame.org\/docs\/ref\/color_list.html<\/a><\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">\"#rrggbbaa\"<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#rrggbb\"<\/span><\/code>, kus t\u00e4hed t\u00e4histavad analoogselt punase, rohelise, sinise ja l\u00e4bipaistvuse v\u00e4\u00e4rtusi. Siin kasutatakse kuuteistk\u00fcmnendnumbreid. N\u00e4iteks (ere)punase jaoks: <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#ff0000\"<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FF0000\"<\/span><\/code>.<\/li>\n<\/ul>\n<p>M\u00f5ned n\u00e4ited:<\/p>\n<ul>\n<li>Punane v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(255,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FF0000\"<\/span><\/code>\n<div style=\"width: 100px;height: 40px;background-color: #ff0000\"><\/div>\n<\/li>\n<li>Roheline v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">255,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#00FF00\"<\/span><\/code>\n<div style=\"width: 100px;height: 40px;background-color: #00ff00\"><\/div>\n<\/li>\n<li>Sinine v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">255)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#0000FF\"<\/span><\/code>\n<div style=\"width: 100px;height: 40px;background-color: #0000ff\"><\/div>\n<\/li>\n<li>Kollane v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(255,<\/span> <span class=\"pre\">255,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FFFF00\"<\/span><\/code>\n<div style=\"width: 100px;height: 40px;background-color: #ffff00\"><\/div>\n<\/li>\n<li>Must v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(0,<\/span> <span class=\"pre\">0,<\/span> <span class=\"pre\">0)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#000000\"<\/span><\/code>\n<div style=\"width: 100px;height: 40px;background-color: #000000\"><\/div>\n<\/li>\n<li>Valge v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(255,<\/span> <span class=\"pre\">255,<\/span> <span class=\"pre\">255)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#FFFFFF\"<\/span><\/code>\n<div style=\"width: 100px;height: 40px;background-color: #ffffff\"><\/div>\n<\/li>\n<li>Hall v\u00e4rv: <code class=\"docutils literal notranslate\"><span class=\"pre\">(128,<\/span> <span class=\"pre\">128,<\/span> <span class=\"pre\">128)<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">\"#808080\"<\/span><\/code>\n<div style=\"width: 100px;height: 40px;background-color: #808080\"><\/div>\n<\/li>\n<\/ul>\n<h2>M\u00f5tle ja nuputa!<\/h2>\n<div id=\"h5p-44\">\n<div class=\"h5p-iframe-wrapper\"><iframe id=\"h5p-iframe-44\" class=\"h5p-iframe\" data-content-id=\"44\" style=\"height:1px\" src=\"about:blank\" frameBorder=\"0\" scrolling=\"no\" title=\"Pygame (millne kujund)\"><\/iframe><\/div>\n<\/div>\n<\/section>\n","protected":false},"author":36,"menu_order":3,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-915","chapter","type-chapter","status-publish","hentry"],"part":780,"_links":{"self":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/915","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":7,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/915\/revisions"}],"predecessor-version":[{"id":939,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/915\/revisions\/939"}],"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\/915\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/media?parent=915"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapter-type?post=915"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/contributor?post=915"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/license?post=915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}