{"id":921,"date":"2023-01-02T08:15:33","date_gmt":"2023-01-02T08:15:33","guid":{"rendered":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/?post_type=chapter&#038;p=921"},"modified":"2023-01-31T20:51:32","modified_gmt":"2023-01-31T20:51:32","slug":"pygamei-sundmused","status":"publish","type":"chapter","link":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/chapter\/pygamei-sundmused\/","title":{"raw":"PyGame'i s\u00fcndmused","rendered":"PyGame&#8217;i s\u00fcndmused"},"content":{"raw":"M\u00e4ngu m\u00e4ngimiseks peab saama kasutaja (m\u00e4ngija) anda korraldusi m\u00e4ngule. Sellised korraldused (n\u00e4iteks klaviatuuri v\u00f5i hiire klahvi vajutamised) on s\u00fcndmused (<em>events<\/em>). M\u00e4nguts\u00fcklis me tegelikult juba kasutasime s\u00fcndmuste kontrolli selleks, et akna sulgemisel l\u00f5petataks m\u00e4ng \u00e4ra.\r\n\r\nPyGame hoiab s\u00fcndmusi j\u00e4rjekorras (<em>queue<\/em>). S\u00fcndmused lisatakse j\u00e4rjekorda nende tekkimise j\u00e4rjekorras. S\u00fcndmusi saab lugeda selles j\u00e4rjekorras, nagu need on j\u00e4rjekorda lisatud. Ehk j\u00e4rjekorrast v\u00f5etakse j\u00e4rgmisena k\u00f5ige varasemana salvestatud s\u00fcndmus (<em>FIFO - first in first out<\/em>). S\u00fcndmuste j\u00e4rjekorral on limiit. Kui j\u00e4rjekord saab t\u00e4is, siis uusi s\u00fcndmusi sinna ei lisata (viga selle kohta ka ei anta). Seega m\u00f5istlik oleks, kui m\u00e4nguts\u00fckli igal sammul loetakse j\u00e4rjekorrast s\u00fcndmused. Vastasel juhul, kui s\u00fcndmused kuhjuvad, v\u00f5ib operatsioonis\u00fcsteem pidada rakendust (m\u00e4ngu) hangunuks ning programmi t\u00f6\u00f6 l\u00f5petatakse.\r\n\r\nSelleks, et k\u00f5iki s\u00fcndmusi lugeda, saab kasutada <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.event.get()<\/span><\/code> funktsiooniga. See tagastab j\u00e4rjendi <code class=\"docutils literal notranslate\"><span class=\"pre\">Event<\/span><\/code> t\u00fc\u00fcpi objektidest. <code class=\"docutils literal notranslate\"><span class=\"pre\">get()<\/span><\/code> funktsioonile saab ette anda ka s\u00fcndmuste t\u00fc\u00fcbi, milliseid s\u00fcndmusi soovime saada. <code class=\"docutils literal notranslate\"><span class=\"pre\">get()<\/span><\/code> meetod eemaldab k\u00f5ik tagastatud s\u00fcndmused s\u00fcndmuste j\u00e4rjekorrast. Soovitatav on igal ts\u00fckli sammul s\u00fcndmusi lugeda. Kui mingil p\u00f5hjusel otseselt s\u00fcndmusi pole vaja kasutada, siis on soovitatav kasutada funktsiooni <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.event.pump()<\/span><\/code>. See tagab k\u00f5ikide s\u00fcndmuste korrektse k\u00e4sitlemise ning s\u00fcndmuste j\u00e4rjekord tehakse t\u00fchjaks.\r\n\r\nIgal s\u00fcndmusel on t\u00fc\u00fcp. PyGame toetab v\u00e4ga palju erinevaid t\u00fc\u00fcpe. Aga vaatame siinkohal peamisi t\u00fc\u00fcpe, millega m\u00e4ngu juhtida. Need on klaviatuuri ja hiire s\u00fcndmused.\r\n\r\n<section id=\"klaviatuuri-sundmused\">\r\n<h2 id=\"klaviatuuri-sundmused\">Klaviatuuri s\u00fcndmused<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#klaviatuuri-sundmused\">\uf0c1<\/a><\/h2>\r\nKlaviatuurilt saab lugeda klahvivajutusi, t\u00e4psemalt klahvi allavajutamise (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYDOWN<\/span><\/code>) ja klahvi lahtilaskmise (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code>) s\u00fcndmusi. Seda t\u00fc\u00fcpi s\u00fcndmustel on kaasas ka info klahvi enda kohta (atribuut <code class=\"docutils literal notranslate\"><span class=\"pre\">key<\/span><\/code>).\r\n\r\nVaatame n\u00e4idet, kus ring liigub ekraanil ringi vastavalt noolte vajutustele:\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\nplayer_x = 100\r\nplayer_y = 100\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        if event.type == pygame.KEYDOWN:\r\n            if event.key == pygame.K_UP:\r\n                player_y -= 10\r\n            if event.key == pygame.K_DOWN:\r\n                player_y += 10\r\n            if event.key == pygame.K_LEFT:\r\n                player_x -= 10\r\n            if event.key == pygame.K_RIGHT:\r\n                player_x += 10\r\n\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # draw a blue circle at player's position (x, y) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (player_x, player_y), 50)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\r\nLoome alguses kaks muutujat, mis t\u00e4histavad m\u00e4ngija x ja y koordinaate (vastavalt <code class=\"docutils literal notranslate\"><span class=\"pre\">player_x<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">player_y<\/span><\/code> muutujad). Anname neile alguses v\u00e4\u00e4rtused 100 ja 100. Ja n\u00fc\u00fcd vastavalt klahvivajutustele hakkame m\u00e4ngijat liigutama. Hetkel selles n\u00e4ites on m\u00e4ngija lihtsalt \u00fcks ring. Aga see v\u00f5ib vabalt olla mingi pilt v\u00f5i ristk\u00fclik vms.\r\n\r\nTs\u00fckkel, kus k\u00e4iakse l\u00e4bi k\u00f5ik s\u00fcndmused, omab eraldi kontrolli selle kohta, kas s\u00fcndmuse t\u00fc\u00fcp on <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.KEYDOWN<\/span><\/code>. Kui on, siis teame, et loetud s\u00fcndmus <code class=\"docutils literal notranslate\"><span class=\"pre\">event<\/span><\/code> on klahvivajutus. Edasi kontrollime, mis on selle s\u00fcndmuse klahv (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.key<\/span><\/code>). V\u00f5rdluseks kasutame PyGame'is eeldefineeritud klahvide konstante, mille saame k\u00e4tte pygame moodulist ning mille nimi algab <code class=\"docutils literal notranslate\"><span class=\"pre\">K_<\/span><\/code>. N\u00e4iteks noolteklahvide konstandid on:\r\n<ul class=\"simple\">\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_UP<\/span><\/code> - \u00fclesnool<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_DOWN<\/span><\/code> - allanool<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_LEFT<\/span><\/code> - vasakule nool<\/li>\r\n \t<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_RIGHT<\/span><\/code> - paremale nool<\/li>\r\n<\/ul>\r\nVastavalt klahvivajutusele muudame m\u00e4ngija koordinaati. N\u00e4iteks kui vajutatakse \u00fclesklahvi, siis m\u00e4ngija y-koordinaat v\u00e4heneb 10 v\u00f5rra.\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\">Siin n\u00e4ites saab ekraanilt v\u00e4lja liikuda. V\u00f5id proovida koodi muuta nii, et kui koordinaadi v\u00e4\u00e4rtus l\u00e4heb liiga suureks v\u00f5i v\u00e4ikeseks, siis seda enam ei muudeta. Selliselt ei saa pall akna raamides v\u00e4lja liikuda.<\/div>\r\n<\/div>\r\n<div class=\"admonition-harjutus admonition\">\r\n\r\nAntud kood t\u00f6\u00f6tab ja saab m\u00e4ngijat liigutada. Aga kui paned t\u00e4hele, siis klahvi all hoides midagi ei toimu. Asi on selles, et <code class=\"docutils literal notranslate\"><span class=\"pre\">KEYDOWN<\/span><\/code> s\u00fcndmus registreeritakse vaid sellel hetkel, kui klahv alla vajutatakse. Kui seda all hoitakse, siis \u00fchtegi s\u00fcndmust ei registreerida. \u00dcks v\u00f5imalus selle \"lahendamiseks\" on see, et kui klahv vajutatakse alla, m\u00e4\u00e4ratakse m\u00e4ngijale liikumiskiirus. Kui klahv lastakse lahti (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code>), siis m\u00e4\u00e4ratakse kiiruseks 0 (ehk m\u00e4ngija j\u00e4\u00e4b seisma).\r\n\r\n<\/div>\r\nLisame praegu kiiruse vaid x-suunalisele liikumisele:\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\nplayer_x = 100\r\nplayer_y = 100\r\nspeed_x = 0\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        if event.type == pygame.KEYDOWN:\r\n            if event.key == pygame.K_LEFT:\r\n                speed_x = -1\r\n            if event.key == pygame.K_RIGHT:\r\n                speed_x = 1\r\n        if event.type == pygame.KEYUP:\r\n            speed_x = 0\r\n\r\n    if speed_x != 0:\r\n        player_x += speed_x\r\n\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # draw a blue circle at player's position (x, y) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (player_x, player_y), 50)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\r\nLisasime \u00fche t\u00e4iendava muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">speed_x<\/span><\/code>, mis algselt on 0. Kui toimub klahvivajutus (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYDOWN<\/span><\/code>), siis m\u00e4\u00e4ratakse <code class=\"docutils literal notranslate\"><span class=\"pre\">speed_x<\/span><\/code> v\u00e4\u00e4rtus. Kui klahv lastakse lahti (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code>), siis m\u00e4\u00e4ratakse <code class=\"docutils literal notranslate\"><span class=\"pre\">speed_x<\/span><\/code> v\u00e4\u00e4rtus nulliks.\r\n<div class=\"textbox textbox--exercises\"><header class=\"textbox__header\">\r\n<p class=\"textbox__title\">M\u00f5tle<\/p>\r\n\r\n<\/header>\r\n<div class=\"textbox__content\">Miks pole <code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code> tingimuse all vaja eraldi kontrollida, kas lahti lasti vasakule v\u00f5i paremale nool?<\/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\">Proovi eelnevat koodi muuta nii, et ka y-suunaliselt toimub sarnane liikumine (kuni klahvi hoitakse all, siis m\u00e4ngija liigub; kui klahv lastakse lahti, siis m\u00e4ngija j\u00e4\u00e4b seisma).<\/div>\r\n<\/div>\r\nKlahvivajutusi on v\u00f5imalik saada ka <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.key.get_pressed()<\/span><\/code> funktsiooniga. See tagastab s\u00f5nastiku, kus v\u00f5ti on klahvi kood (<code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_<\/span><\/code> konstantide seast) ja v\u00e4\u00e4rtus on t\u00f5ev\u00e4\u00e4rtus, kas seda klahvi on vajutatud.\r\n\r\nSeda kasutades saab \u00fcmber kirjutada m\u00e4ngija liikumise vastavalt klahvivajutusele j\u00e4rgnevalt:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">keys = pygame.key.get_pressed()\r\nif keys[pygame.K_UP]:\r\n    player_y -= 1\r\nif keys[pygame.K_DOWN]:\r\n    player_y += 1\r\nif keys[pygame.K_LEFT]:\r\n    player_x -= 1\r\nif keys[pygame.K_RIGHT]:\r\n    player_x += 1\r\n<\/pre>\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">keys<\/span><\/code> muutujasse pannakse s\u00f5nastik, kus klahvidele on vastavuses kas <code class=\"docutils literal notranslate\"><span class=\"pre\">True<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">False<\/span><\/code>. Kui klahv on hetkel all, siis vastava v\u00f5tme puhul v\u00e4\u00e4rtus on <code class=\"docutils literal notranslate\"><span class=\"pre\">True<\/span><\/code>.\r\n\r\nSiin n\u00e4ites on muudetud sammu pikkuseks 1 (algses n\u00e4ites oli see 10) piksel, kuna klahvivajutus kestab tavaliselt m\u00f5ne hetke ning kogu selle aja v\u00e4ltel on s\u00f5nastikus vastava klahvi v\u00e4\u00e4rtus t\u00f5ene ja seet\u00f5ttu toimub ka liikumine.\r\n\r\nKuigi selline kirjapilt on \u00fcldiselt l\u00fchem ja v\u00f5ib-olla ka loetavam, siis peab arvestama, et sellise lahenduse puhul ei ole s\u00fcndmuste j\u00e4rjekord teada. Kui n\u00e4iteks m\u00e4ngija peab midagi kirjutama, siis vajutuste j\u00e4rjekord ei pruugi siit selge olla (vajutab v\u00e4ga v\u00e4ikese vahega kaks klahvi alla, siis selle ts\u00fckli sammu sees v\u00f5ivad m\u00f5lemad olla s\u00f5nastikus t\u00f5ese v\u00e4\u00e4rtusega, aga kumb enne vajutati pole teada).\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 eelnevat koodi muuta nii, et kasutad taustapilti ning kujundi asemel omakorda pilti. See t\u00e4hendab, et <code class=\"docutils literal notranslate\"><span class=\"pre\">screen.fill()<\/span><\/code> asemel tuleks kasutada <code class=\"docutils literal notranslate\"><span class=\"pre\">blit()<\/span><\/code> funktsiooni. M\u00f5istlik oleks proovida asendada vaid see osa ekraanist, kus midagi on muutunud (kust tuleb \"kustutada\" vana objekti pilt).<\/div>\r\n<\/div>\r\n<\/section><section id=\"hiire-sundmused\">\r\n<h2>M\u00f5tle ja nuputa!<\/h2>\r\n[h5p id=\"45\"]\r\n<h2 id=\"hiire-sundmused\">Hiire s\u00fcndmused<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#hiire-sundmused\">\uf0c1<\/a><\/h2>\r\nHiirelt saab sarnaselt klaviatuurile lugeda hiire klahvivajutusi (<code class=\"docutils literal notranslate\"><span class=\"pre\">MOUSEBUTTONDOWN<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">MOUSEBUTTONUP<\/span><\/code>). Lisaks saab lugeda hiire liikumise s\u00fcndmust <code class=\"docutils literal notranslate\"><span class=\"pre\">MOUSEMOTION<\/span><\/code>. Klahvis\u00fcndmuste objektis on olemas positsioon (<code class=\"docutils literal notranslate\"><span class=\"pre\">pos<\/span><\/code>), kus hiir oli klahvivajutuse hetkel, ja klahv (<code class=\"docutils literal notranslate\"><span class=\"pre\">button<\/span><\/code>), mida vajutati.\r\n\r\nVaatame n\u00e4idet, kus ekraanil on pall (ring). Kui selle peal klikkida, liigub pall uuele positsioonile:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\nimport random\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((800, 600))\r\n\r\nrunning = True\r\nplayer_x = 100\r\nplayer_y = 100\r\nplayer_radius = 50\r\n\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        if event.type == pygame.MOUSEBUTTONDOWN and event.button == pygame.BUTTON_LEFT:\r\n            # let's use vector here\r\n            vector = pygame.Vector2(event.pos[0] - player_x, event.pos[1] - player_y)\r\n            if vector.length() &lt;= player_radius:\r\n                player_x = random.randint(0 + player_radius, screen.get_width() - player_radius)\r\n                player_y = random.randint(0 + player_radius, screen.get_height() - player_radius)\r\n\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # draw a blue circle at player's position (x, y) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (player_x, player_y), player_radius)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\r\nLisaks m\u00e4ngija asukohale (<code class=\"docutils literal notranslate\"><span class=\"pre\">player_x<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">player_y<\/span><\/code>) loome muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">player_radius<\/span><\/code>, mis t\u00e4histab ringi raadiust. Kuna kasutame seda raadiust mitmes kohas, siis on m\u00f5istlik see muutujaks m\u00e4\u00e4rata.\r\n\r\nS\u00fcndmuste ts\u00fcklis kontrollime, kas s\u00fcndmuse <code class=\"docutils literal notranslate\"><span class=\"pre\">event<\/span><\/code> t\u00fc\u00fcp on <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.MOUSEBUTTONDOWN<\/span><\/code> ja vajutatud klahv on hiire vasak klahv (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.button<\/span> <span class=\"pre\">==<\/span> <span class=\"pre\">pygame.BUTTON_LEFT<\/span><\/code>). N\u00fc\u00fcd on meil teada, et toimus hiire vasaku klahvi vajutus. Me peame kontrollima, kas klikk toimus ringi sees v\u00f5i mitte. Selleks arvutame hiire positsiooni kauguse ringi keskpunktist.\r\n\r\n[caption id=\"attachment_922\" align=\"alignnone\" width=\"732\"]<img class=\"size-full wp-image-922\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/mouse_position_distance_from_circle_center.png\" alt=\"Kursori kaugus ringi keskpunktist\" width=\"732\" height=\"656\" \/> Leiame kursori kauguse ringi keskpunktist ning v\u00f5rdleme, kas kaugus on v\u00e4iksem-v\u00f5rdne raadiusega (sellisel juhul toimus klikk ringi sees)[\/caption]\r\n\r\nPildil on kujutatud ring koos keskpunktiga (sinine t\u00e4pp). Punane t\u00e4pp on positsioon, kus toimus hiire klikk. Leiame x- ja y-teljel kahe punkti vahe (vastavalt <code class=\"docutils literal notranslate\"><span class=\"pre\">dx<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">dy<\/span><\/code>). Nendest kahes v\u00e4\u00e4rtusest saame luua vektori (joonisel roheline joon <code class=\"docutils literal notranslate\"><span class=\"pre\">v<\/span><\/code>). Kui selle vektori pikkus on v\u00e4iksem v\u00f5i v\u00f5rdne ringi raadiusega (joonisel <code class=\"docutils literal notranslate\"><span class=\"pre\">R<\/span><\/code>), siis j\u00e4relikult toimus klikk ringi sees. Kui kaugus on raadiusest suurem, siis toimus klikk ringist v\u00e4ljas.\r\n\r\n<code class=\"docutils literal notranslate\"><span class=\"pre\">dx<\/span><\/code> arvutamiseks leiame s\u00fcndmuse (hiirekliki) positsiooni x-koordinaadi (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.pos[0]<\/span><\/code>) v\u00e4\u00e4rtuse ja ringi keskpunkti x-koordinaadi (<code class=\"docutils literal notranslate\"><span class=\"pre\">player_x<\/span><\/code>) v\u00e4\u00e4rtuse vahe (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.pos[0]<\/span> <span class=\"pre\">-<\/span> <span class=\"pre\">player_x<\/span><\/code>). See vahe v\u00f5ib ka negatiivne olla. Aga vektori pikkuse jaoks ei ole vahet. Sarnaselt arvutama <code class=\"docutils literal notranslate\"><span class=\"pre\">dy<\/span><\/code> vahe. Me v\u00f5iks vektori asemel ka n\u00e4iteks Pythagorase teoreemi kasutada, et <code class=\"docutils literal notranslate\"><span class=\"pre\">v<\/span><\/code> pikkus arvutada (kuna <code class=\"docutils literal notranslate\"><span class=\"pre\">dx<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">dy<\/span><\/code> vaheline nurk on t\u00e4isnurk, <code class=\"docutils literal notranslate\"><span class=\"pre\">v<\/span><\/code> on h\u00fcpotenuus), aga vektoriga on seda mugavam teha.\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\">\r\n\r\nProovi koodi muuta nii, et kui arvutatakse uus ringi asukoht, siis see ei tohiks sattuda sellisesse asukohta, et ta juba j\u00e4\u00e4b hiire positsiooni alla.\r\n\r\nSiin v\u00f5ib m\u00f5elda nii, et uute koordinaatide arvutmine v\u00f5iks toimuda l\u00f5putus ts\u00fcklis. Seda ts\u00fcklit korratakse seni, kuni uued koordinaadid ei too ringi hiire alla. Selleks saab peale koordinaatide arvutamist leida nende kaugus hiire positsioonist (n\u00e4iteks kasutades vektorit). Kui kaugus on piisav, siis l\u00f5petatakse l\u00f5putu ts\u00fckkel \u00e4ra. Muul juhul korratakse tegevust uue ts\u00fckli sammu sees.\r\n\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<h2>M\u00f5tle ja nuputa!<\/h2>\r\n[h5p id=\"46\"]\r\n\r\n<hr class=\"docutils\" \/>\r\n\r\nT\u00e4psemat lugemist s\u00fcndmuste kohta: <a class=\"reference external\" href=\"https:\/\/www.pygame.org\/docs\/ref\/event.html\">https:\/\/www.pygame.org\/docs\/ref\/event.html<\/a>\r\n\r\n<\/section>","rendered":"<p>M\u00e4ngu m\u00e4ngimiseks peab saama kasutaja (m\u00e4ngija) anda korraldusi m\u00e4ngule. Sellised korraldused (n\u00e4iteks klaviatuuri v\u00f5i hiire klahvi vajutamised) on s\u00fcndmused (<em>events<\/em>). M\u00e4nguts\u00fcklis me tegelikult juba kasutasime s\u00fcndmuste kontrolli selleks, et akna sulgemisel l\u00f5petataks m\u00e4ng \u00e4ra.<\/p>\n<p>PyGame hoiab s\u00fcndmusi j\u00e4rjekorras (<em>queue<\/em>). S\u00fcndmused lisatakse j\u00e4rjekorda nende tekkimise j\u00e4rjekorras. S\u00fcndmusi saab lugeda selles j\u00e4rjekorras, nagu need on j\u00e4rjekorda lisatud. Ehk j\u00e4rjekorrast v\u00f5etakse j\u00e4rgmisena k\u00f5ige varasemana salvestatud s\u00fcndmus (<em>FIFO &#8211; first in first out<\/em>). S\u00fcndmuste j\u00e4rjekorral on limiit. Kui j\u00e4rjekord saab t\u00e4is, siis uusi s\u00fcndmusi sinna ei lisata (viga selle kohta ka ei anta). Seega m\u00f5istlik oleks, kui m\u00e4nguts\u00fckli igal sammul loetakse j\u00e4rjekorrast s\u00fcndmused. Vastasel juhul, kui s\u00fcndmused kuhjuvad, v\u00f5ib operatsioonis\u00fcsteem pidada rakendust (m\u00e4ngu) hangunuks ning programmi t\u00f6\u00f6 l\u00f5petatakse.<\/p>\n<p>Selleks, et k\u00f5iki s\u00fcndmusi lugeda, saab kasutada <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.event.get()<\/span><\/code> funktsiooniga. See tagastab j\u00e4rjendi <code class=\"docutils literal notranslate\"><span class=\"pre\">Event<\/span><\/code> t\u00fc\u00fcpi objektidest. <code class=\"docutils literal notranslate\"><span class=\"pre\">get()<\/span><\/code> funktsioonile saab ette anda ka s\u00fcndmuste t\u00fc\u00fcbi, milliseid s\u00fcndmusi soovime saada. <code class=\"docutils literal notranslate\"><span class=\"pre\">get()<\/span><\/code> meetod eemaldab k\u00f5ik tagastatud s\u00fcndmused s\u00fcndmuste j\u00e4rjekorrast. Soovitatav on igal ts\u00fckli sammul s\u00fcndmusi lugeda. Kui mingil p\u00f5hjusel otseselt s\u00fcndmusi pole vaja kasutada, siis on soovitatav kasutada funktsiooni <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.event.pump()<\/span><\/code>. See tagab k\u00f5ikide s\u00fcndmuste korrektse k\u00e4sitlemise ning s\u00fcndmuste j\u00e4rjekord tehakse t\u00fchjaks.<\/p>\n<p>Igal s\u00fcndmusel on t\u00fc\u00fcp. PyGame toetab v\u00e4ga palju erinevaid t\u00fc\u00fcpe. Aga vaatame siinkohal peamisi t\u00fc\u00fcpe, millega m\u00e4ngu juhtida. Need on klaviatuuri ja hiire s\u00fcndmused.<\/p>\n<section id=\"klaviatuuri-sundmused\">\n<h2 id=\"klaviatuuri-sundmused\">Klaviatuuri s\u00fcndmused<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#klaviatuuri-sundmused\">\uf0c1<\/a><\/h2>\n<p>Klaviatuurilt saab lugeda klahvivajutusi, t\u00e4psemalt klahvi allavajutamise (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYDOWN<\/span><\/code>) ja klahvi lahtilaskmise (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code>) s\u00fcndmusi. Seda t\u00fc\u00fcpi s\u00fcndmustel on kaasas ka info klahvi enda kohta (atribuut <code class=\"docutils literal notranslate\"><span class=\"pre\">key<\/span><\/code>).<\/p>\n<p>Vaatame n\u00e4idet, kus ring liigub ekraanil ringi vastavalt noolte vajutustele:<\/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\nplayer_x = 100\r\nplayer_y = 100\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        if event.type == pygame.KEYDOWN:\r\n            if event.key == pygame.K_UP:\r\n                player_y -= 10\r\n            if event.key == pygame.K_DOWN:\r\n                player_y += 10\r\n            if event.key == pygame.K_LEFT:\r\n                player_x -= 10\r\n            if event.key == pygame.K_RIGHT:\r\n                player_x += 10\r\n\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # draw a blue circle at player's position (x, y) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (player_x, player_y), 50)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\n<p>Loome alguses kaks muutujat, mis t\u00e4histavad m\u00e4ngija x ja y koordinaate (vastavalt <code class=\"docutils literal notranslate\"><span class=\"pre\">player_x<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">player_y<\/span><\/code> muutujad). Anname neile alguses v\u00e4\u00e4rtused 100 ja 100. Ja n\u00fc\u00fcd vastavalt klahvivajutustele hakkame m\u00e4ngijat liigutama. Hetkel selles n\u00e4ites on m\u00e4ngija lihtsalt \u00fcks ring. Aga see v\u00f5ib vabalt olla mingi pilt v\u00f5i ristk\u00fclik vms.<\/p>\n<p>Ts\u00fckkel, kus k\u00e4iakse l\u00e4bi k\u00f5ik s\u00fcndmused, omab eraldi kontrolli selle kohta, kas s\u00fcndmuse t\u00fc\u00fcp on <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.KEYDOWN<\/span><\/code>. Kui on, siis teame, et loetud s\u00fcndmus <code class=\"docutils literal notranslate\"><span class=\"pre\">event<\/span><\/code> on klahvivajutus. Edasi kontrollime, mis on selle s\u00fcndmuse klahv (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.key<\/span><\/code>). V\u00f5rdluseks kasutame PyGame&#8217;is eeldefineeritud klahvide konstante, mille saame k\u00e4tte pygame moodulist ning mille nimi algab <code class=\"docutils literal notranslate\"><span class=\"pre\">K_<\/span><\/code>. N\u00e4iteks noolteklahvide konstandid on:<\/p>\n<ul class=\"simple\">\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_UP<\/span><\/code> &#8211; \u00fclesnool<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_DOWN<\/span><\/code> &#8211; allanool<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_LEFT<\/span><\/code> &#8211; vasakule nool<\/li>\n<li><code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_RIGHT<\/span><\/code> &#8211; paremale nool<\/li>\n<\/ul>\n<p>Vastavalt klahvivajutusele muudame m\u00e4ngija koordinaati. N\u00e4iteks kui vajutatakse \u00fclesklahvi, siis m\u00e4ngija y-koordinaat v\u00e4heneb 10 v\u00f5rra.<\/p>\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\">Siin n\u00e4ites saab ekraanilt v\u00e4lja liikuda. V\u00f5id proovida koodi muuta nii, et kui koordinaadi v\u00e4\u00e4rtus l\u00e4heb liiga suureks v\u00f5i v\u00e4ikeseks, siis seda enam ei muudeta. Selliselt ei saa pall akna raamides v\u00e4lja liikuda.<\/div>\n<\/div>\n<div class=\"admonition-harjutus admonition\">\n<p>Antud kood t\u00f6\u00f6tab ja saab m\u00e4ngijat liigutada. Aga kui paned t\u00e4hele, siis klahvi all hoides midagi ei toimu. Asi on selles, et <code class=\"docutils literal notranslate\"><span class=\"pre\">KEYDOWN<\/span><\/code> s\u00fcndmus registreeritakse vaid sellel hetkel, kui klahv alla vajutatakse. Kui seda all hoitakse, siis \u00fchtegi s\u00fcndmust ei registreerida. \u00dcks v\u00f5imalus selle &#8220;lahendamiseks&#8221; on see, et kui klahv vajutatakse alla, m\u00e4\u00e4ratakse m\u00e4ngijale liikumiskiirus. Kui klahv lastakse lahti (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code>), siis m\u00e4\u00e4ratakse kiiruseks 0 (ehk m\u00e4ngija j\u00e4\u00e4b seisma).<\/p>\n<\/div>\n<p>Lisame praegu kiiruse vaid x-suunalisele liikumisele:<\/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\nplayer_x = 100\r\nplayer_y = 100\r\nspeed_x = 0\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        if event.type == pygame.KEYDOWN:\r\n            if event.key == pygame.K_LEFT:\r\n                speed_x = -1\r\n            if event.key == pygame.K_RIGHT:\r\n                speed_x = 1\r\n        if event.type == pygame.KEYUP:\r\n            speed_x = 0\r\n\r\n    if speed_x != 0:\r\n        player_x += speed_x\r\n\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # draw a blue circle at player's position (x, y) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (player_x, player_y), 50)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\n<p>Lisasime \u00fche t\u00e4iendava muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">speed_x<\/span><\/code>, mis algselt on 0. Kui toimub klahvivajutus (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYDOWN<\/span><\/code>), siis m\u00e4\u00e4ratakse <code class=\"docutils literal notranslate\"><span class=\"pre\">speed_x<\/span><\/code> v\u00e4\u00e4rtus. Kui klahv lastakse lahti (<code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code>), siis m\u00e4\u00e4ratakse <code class=\"docutils literal notranslate\"><span class=\"pre\">speed_x<\/span><\/code> v\u00e4\u00e4rtus nulliks.<\/p>\n<div class=\"textbox textbox--exercises\">\n<header class=\"textbox__header\">\n<p class=\"textbox__title\">M\u00f5tle<\/p>\n<\/header>\n<div class=\"textbox__content\">Miks pole <code class=\"docutils literal notranslate\"><span class=\"pre\">KEYUP<\/span><\/code> tingimuse all vaja eraldi kontrollida, kas lahti lasti vasakule v\u00f5i paremale nool?<\/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\">Proovi eelnevat koodi muuta nii, et ka y-suunaliselt toimub sarnane liikumine (kuni klahvi hoitakse all, siis m\u00e4ngija liigub; kui klahv lastakse lahti, siis m\u00e4ngija j\u00e4\u00e4b seisma).<\/div>\n<\/div>\n<p>Klahvivajutusi on v\u00f5imalik saada ka <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.key.get_pressed()<\/span><\/code> funktsiooniga. See tagastab s\u00f5nastiku, kus v\u00f5ti on klahvi kood (<code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.K_<\/span><\/code> konstantide seast) ja v\u00e4\u00e4rtus on t\u00f5ev\u00e4\u00e4rtus, kas seda klahvi on vajutatud.<\/p>\n<p>Seda kasutades saab \u00fcmber kirjutada m\u00e4ngija liikumise vastavalt klahvivajutusele j\u00e4rgnevalt:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">keys = pygame.key.get_pressed()\r\nif keys[pygame.K_UP]:\r\n    player_y -= 1\r\nif keys[pygame.K_DOWN]:\r\n    player_y += 1\r\nif keys[pygame.K_LEFT]:\r\n    player_x -= 1\r\nif keys[pygame.K_RIGHT]:\r\n    player_x += 1\r\n<\/pre>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">keys<\/span><\/code> muutujasse pannakse s\u00f5nastik, kus klahvidele on vastavuses kas <code class=\"docutils literal notranslate\"><span class=\"pre\">True<\/span><\/code> v\u00f5i <code class=\"docutils literal notranslate\"><span class=\"pre\">False<\/span><\/code>. Kui klahv on hetkel all, siis vastava v\u00f5tme puhul v\u00e4\u00e4rtus on <code class=\"docutils literal notranslate\"><span class=\"pre\">True<\/span><\/code>.<\/p>\n<p>Siin n\u00e4ites on muudetud sammu pikkuseks 1 (algses n\u00e4ites oli see 10) piksel, kuna klahvivajutus kestab tavaliselt m\u00f5ne hetke ning kogu selle aja v\u00e4ltel on s\u00f5nastikus vastava klahvi v\u00e4\u00e4rtus t\u00f5ene ja seet\u00f5ttu toimub ka liikumine.<\/p>\n<p>Kuigi selline kirjapilt on \u00fcldiselt l\u00fchem ja v\u00f5ib-olla ka loetavam, siis peab arvestama, et sellise lahenduse puhul ei ole s\u00fcndmuste j\u00e4rjekord teada. Kui n\u00e4iteks m\u00e4ngija peab midagi kirjutama, siis vajutuste j\u00e4rjekord ei pruugi siit selge olla (vajutab v\u00e4ga v\u00e4ikese vahega kaks klahvi alla, siis selle ts\u00fckli sammu sees v\u00f5ivad m\u00f5lemad olla s\u00f5nastikus t\u00f5ese v\u00e4\u00e4rtusega, aga kumb enne vajutati pole teada).<\/p>\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 eelnevat koodi muuta nii, et kasutad taustapilti ning kujundi asemel omakorda pilti. See t\u00e4hendab, et <code class=\"docutils literal notranslate\"><span class=\"pre\">screen.fill()<\/span><\/code> asemel tuleks kasutada <code class=\"docutils literal notranslate\"><span class=\"pre\">blit()<\/span><\/code> funktsiooni. M\u00f5istlik oleks proovida asendada vaid see osa ekraanist, kus midagi on muutunud (kust tuleb &#8220;kustutada&#8221; vana objekti pilt).<\/div>\n<\/div>\n<\/section>\n<section id=\"hiire-sundmused\">\n<h2>M\u00f5tle ja nuputa!<\/h2>\n<div id=\"h5p-45\">\n<div class=\"h5p-iframe-wrapper\"><iframe id=\"h5p-iframe-45\" class=\"h5p-iframe\" data-content-id=\"45\" style=\"height:1px\" src=\"about:blank\" frameBorder=\"0\" scrolling=\"no\" title=\"Pygame (klaviatuuri s\u00fcndmused)\"><\/iframe><\/div>\n<\/div>\n<h2 id=\"hiire-sundmused\">Hiire s\u00fcndmused<a class=\"headerlink\" title=\"Permalink to this heading\" href=\"#hiire-sundmused\">\uf0c1<\/a><\/h2>\n<p>Hiirelt saab sarnaselt klaviatuurile lugeda hiire klahvivajutusi (<code class=\"docutils literal notranslate\"><span class=\"pre\">MOUSEBUTTONDOWN<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">MOUSEBUTTONUP<\/span><\/code>). Lisaks saab lugeda hiire liikumise s\u00fcndmust <code class=\"docutils literal notranslate\"><span class=\"pre\">MOUSEMOTION<\/span><\/code>. Klahvis\u00fcndmuste objektis on olemas positsioon (<code class=\"docutils literal notranslate\"><span class=\"pre\">pos<\/span><\/code>), kus hiir oli klahvivajutuse hetkel, ja klahv (<code class=\"docutils literal notranslate\"><span class=\"pre\">button<\/span><\/code>), mida vajutati.<\/p>\n<p>Vaatame n\u00e4idet, kus ekraanil on pall (ring). Kui selle peal klikkida, liigub pall uuele positsioonile:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pygame\r\nimport random\r\n\r\npygame.init()\r\n# create a window\r\nscreen = pygame.display.set_mode((800, 600))\r\n\r\nrunning = True\r\nplayer_x = 100\r\nplayer_y = 100\r\nplayer_radius = 50\r\n\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        if event.type == pygame.MOUSEBUTTONDOWN and event.button == pygame.BUTTON_LEFT:\r\n            # let's use vector here\r\n            vector = pygame.Vector2(event.pos[0] - player_x, event.pos[1] - player_y)\r\n            if vector.length() &lt;= player_radius:\r\n                player_x = random.randint(0 + player_radius, screen.get_width() - player_radius)\r\n                player_y = random.randint(0 + player_radius, screen.get_height() - player_radius)\r\n\r\n    # fill screen with white color\r\n    screen.fill((255, 255, 255))\r\n\r\n    # draw a blue circle at player's position (x, y) with radius 50\r\n    pygame.draw.circle(screen, (0, 0, 255), (player_x, player_y), player_radius)\r\n\r\n    # everything drawn will be visible\r\n    pygame.display.flip()\r\n<\/pre>\n<p>Lisaks m\u00e4ngija asukohale (<code class=\"docutils literal notranslate\"><span class=\"pre\">player_x<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">player_y<\/span><\/code>) loome muutuja <code class=\"docutils literal notranslate\"><span class=\"pre\">player_radius<\/span><\/code>, mis t\u00e4histab ringi raadiust. Kuna kasutame seda raadiust mitmes kohas, siis on m\u00f5istlik see muutujaks m\u00e4\u00e4rata.<\/p>\n<p>S\u00fcndmuste ts\u00fcklis kontrollime, kas s\u00fcndmuse <code class=\"docutils literal notranslate\"><span class=\"pre\">event<\/span><\/code> t\u00fc\u00fcp on <code class=\"docutils literal notranslate\"><span class=\"pre\">pygame.MOUSEBUTTONDOWN<\/span><\/code> ja vajutatud klahv on hiire vasak klahv (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.button<\/span> <span class=\"pre\">==<\/span> <span class=\"pre\">pygame.BUTTON_LEFT<\/span><\/code>). N\u00fc\u00fcd on meil teada, et toimus hiire vasaku klahvi vajutus. Me peame kontrollima, kas klikk toimus ringi sees v\u00f5i mitte. Selleks arvutame hiire positsiooni kauguse ringi keskpunktist.<\/p>\n<figure id=\"attachment_922\" aria-describedby=\"caption-attachment-922\" style=\"width: 732px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-922\" src=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/mouse_position_distance_from_circle_center.png\" alt=\"Kursori kaugus ringi keskpunktist\" width=\"732\" height=\"656\" srcset=\"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/mouse_position_distance_from_circle_center.png 732w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/mouse_position_distance_from_circle_center-300x269.png 300w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/mouse_position_distance_from_circle_center-65x58.png 65w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/mouse_position_distance_from_circle_center-225x202.png 225w, https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-content\/uploads\/sites\/18\/2023\/01\/mouse_position_distance_from_circle_center-350x314.png 350w\" sizes=\"auto, (max-width: 732px) 100vw, 732px\" \/><figcaption id=\"caption-attachment-922\" class=\"wp-caption-text\">Leiame kursori kauguse ringi keskpunktist ning v\u00f5rdleme, kas kaugus on v\u00e4iksem-v\u00f5rdne raadiusega (sellisel juhul toimus klikk ringi sees)<\/figcaption><\/figure>\n<p>Pildil on kujutatud ring koos keskpunktiga (sinine t\u00e4pp). Punane t\u00e4pp on positsioon, kus toimus hiire klikk. Leiame x- ja y-teljel kahe punkti vahe (vastavalt <code class=\"docutils literal notranslate\"><span class=\"pre\">dx<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">dy<\/span><\/code>). Nendest kahes v\u00e4\u00e4rtusest saame luua vektori (joonisel roheline joon <code class=\"docutils literal notranslate\"><span class=\"pre\">v<\/span><\/code>). Kui selle vektori pikkus on v\u00e4iksem v\u00f5i v\u00f5rdne ringi raadiusega (joonisel <code class=\"docutils literal notranslate\"><span class=\"pre\">R<\/span><\/code>), siis j\u00e4relikult toimus klikk ringi sees. Kui kaugus on raadiusest suurem, siis toimus klikk ringist v\u00e4ljas.<\/p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">dx<\/span><\/code> arvutamiseks leiame s\u00fcndmuse (hiirekliki) positsiooni x-koordinaadi (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.pos[0]<\/span><\/code>) v\u00e4\u00e4rtuse ja ringi keskpunkti x-koordinaadi (<code class=\"docutils literal notranslate\"><span class=\"pre\">player_x<\/span><\/code>) v\u00e4\u00e4rtuse vahe (<code class=\"docutils literal notranslate\"><span class=\"pre\">event.pos[0]<\/span> <span class=\"pre\">-<\/span> <span class=\"pre\">player_x<\/span><\/code>). See vahe v\u00f5ib ka negatiivne olla. Aga vektori pikkuse jaoks ei ole vahet. Sarnaselt arvutama <code class=\"docutils literal notranslate\"><span class=\"pre\">dy<\/span><\/code> vahe. Me v\u00f5iks vektori asemel ka n\u00e4iteks Pythagorase teoreemi kasutada, et <code class=\"docutils literal notranslate\"><span class=\"pre\">v<\/span><\/code> pikkus arvutada (kuna <code class=\"docutils literal notranslate\"><span class=\"pre\">dx<\/span><\/code> ja <code class=\"docutils literal notranslate\"><span class=\"pre\">dy<\/span><\/code> vaheline nurk on t\u00e4isnurk, <code class=\"docutils literal notranslate\"><span class=\"pre\">v<\/span><\/code> on h\u00fcpotenuus), aga vektoriga on seda mugavam teha.<\/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\">\n<p>Proovi koodi muuta nii, et kui arvutatakse uus ringi asukoht, siis see ei tohiks sattuda sellisesse asukohta, et ta juba j\u00e4\u00e4b hiire positsiooni alla.<\/p>\n<p>Siin v\u00f5ib m\u00f5elda nii, et uute koordinaatide arvutmine v\u00f5iks toimuda l\u00f5putus ts\u00fcklis. Seda ts\u00fcklit korratakse seni, kuni uued koordinaadid ei too ringi hiire alla. Selleks saab peale koordinaatide arvutamist leida nende kaugus hiire positsioonist (n\u00e4iteks kasutades vektorit). Kui kaugus on piisav, siis l\u00f5petatakse l\u00f5putu ts\u00fckkel \u00e4ra. Muul juhul korratakse tegevust uue ts\u00fckli sammu sees.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<h2>M\u00f5tle ja nuputa!<\/h2>\n<div id=\"h5p-46\">\n<div class=\"h5p-iframe-wrapper\"><iframe id=\"h5p-iframe-46\" class=\"h5p-iframe\" data-content-id=\"46\" style=\"height:1px\" src=\"about:blank\" frameBorder=\"0\" scrolling=\"no\" title=\"Pygame (hiire s\u00fcndmused)\"><\/iframe><\/div>\n<\/div>\n<hr class=\"docutils\" \/>\n<p>T\u00e4psemat lugemist s\u00fcndmuste kohta: <a class=\"reference external\" href=\"https:\/\/www.pygame.org\/docs\/ref\/event.html\">https:\/\/www.pygame.org\/docs\/ref\/event.html<\/a><\/p>\n<\/section>\n","protected":false},"author":36,"menu_order":4,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-921","chapter","type-chapter","status-publish","hentry"],"part":780,"_links":{"self":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/921","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":4,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/921\/revisions"}],"predecessor-version":[{"id":974,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/921\/revisions\/974"}],"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\/921\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/media?parent=921"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapter-type?post=921"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/contributor?post=921"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/license?post=921"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}