{"id":837,"date":"2019-02-16T11:02:11","date_gmt":"2019-02-16T10:02:11","guid":{"rendered":"https:\/\/www.kompikownia.pl\/?p=837"},"modified":"2019-02-16T11:18:23","modified_gmt":"2019-02-16T10:18:23","slug":"symulator-pozaru-lasu-dodajemy-narzedzia","status":"publish","type":"post","link":"https:\/\/www.kompikownia.pl\/index.php\/2019\/02\/16\/symulator-pozaru-lasu-dodajemy-narzedzia\/","title":{"rendered":"Symulator po\u017caru lasu &#8211; dodajemy narz\u0119dzia"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Czas czytania:<\/span> <span class=\"rt-time\">7<\/span> <span class=\"rt-label rt-postfix\">minut<\/span><\/span>\n<p>Semestr si\u0119 ju\u017c zako\u0144czy\u0142 &#8230; Nie da\u0142em rady opisywa\u0107 na bie\u017c\u0105co rozwoju projektu symulatora po\u017caru lasu. Na szcz\u0119\u015bcie wszystko zaliczy\u0142em w pierwszym terminie i teraz mam troch\u0119 wolnego czasu. Dzi\u0119ki temu moge nadrobi\u0107 wymuszone przez wy\u017csze czynniki zaleg\u0142o\u015bci. Zapraszam do lektury \ud83d\ude42 <\/p>\n\n\n\n<p>Co b\u0119dziemy robili? Dzisiaj dodamy do programu podstawowe narz\u0119dzia, kt\u00f3re b\u0119d\u0105 pozwala\u0142y na stworzenie &#8222;\u015brodowiska symulacji&#8221;. Po wprowadzeniu dzisiejszych modyfikacji b\u0119dziemy mogli na r\u00f3\u017cne sposoby rysowa\u0107 drzewa, po\u017cary i spalone drzewa. Je\u015bli chcesz przypomnie\u0107 sobie, co ju\u017c&nbsp;osi\u0105gn\u0119li\u015bmy, zajrzyj do <a href=\"https:\/\/www.kompikownia.pl\/index.php\/2018\/11\/30\/symulator-pozaru-lasu-tworzymy-okienko\/\">poprzedniego wpisu tej serii<\/a>. No to co, zaczynamy?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Poprawki w dotychczasowym kodzie<\/h2>\n\n\n\n<p>Musimy wprowadzi\u0107 kilka poprawek w dotychczasowym kodzie. Jakich? Je\u015bli zajrzysz do <a href=\"https:\/\/www.kompikownia.pl\/index.php\/2018\/11\/16\/symulator-pozaru-lasu-zalozenia-i-pierwsze-kroki\/\">pierwszej<\/a> i <a href=\"https:\/\/www.kompikownia.pl\/index.php\/2018\/11\/30\/symulator-pozaru-lasu-tworzymy-okienko\/\">drugiej<\/a> cz\u0119\u015bci tej serii zauwa\u017cysz, \u017ce zapomnieli\u015bmy o kilku rzeczach. Przede wszystkim nie wzi\u0119li\u015bmy pod uwag\u0119 mo\u017cliwo\u015bci usuwania punkt\u00f3w. B\u0119dzie nam niezb\u0119dna w momencie gdy b\u0119dziemy chcieli zrobi\u0107 narz\u0119dzie s\u0142u\u017c\u0105ce do usuwania narysowanych drzew\/po\u017car\u00f3w. Mogliby\u015bmy pomin\u0105\u0107 tworzenie takiego narz\u0119dzia. Lecz czy nie powinni\u015bmy bra\u0107 pod uwag\u0119&nbsp;tego, \u017ce u\u017cytkownikowi mo\u017ce si\u0119 omskn\u0105\u0107 r\u0119ka i narysuje drzewo nie w tym miejscu co chcia\u0142? No w\u0142a\u015bnie&#8230;<\/p>\n\n\n\n<p>Pierwsza zmiana dotknie enum PType. Dodamy w nim kolejn\u0105&nbsp;pozycj\u0119: NONE. Enum po zmianach b\u0119dzie wygl\u0105da\u0142o tak: <\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw2\">enum<\/span> PType <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; EXIST,<br \/>\n&nbsp; &nbsp; FIRE,<br \/>\n&nbsp; &nbsp; BURN,<br \/>\n&nbsp; &nbsp; NONE<br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy4\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Szczeg\u00f3\u0142y u\u017cycia ostatniej opcji poznasz w dalszej cz\u0119\u015bci artyku\u0142u. <\/p>\n\n\n\n<p>Dodamy do ForestMapy mo\u017cliwo\u015b\u0107 usuwania punkt\u00f3w. B\u0119dzie to kolejna metoda klasy ForestMap. Wygl\u0105da ona nast\u0119puj\u0105co: <\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>89<br \/>90<br \/>91<br \/><\/div><\/td><td><div class=\"cpp codecolorer\">&nbsp; &nbsp; <span class=\"kw4\">void<\/span> del<span class=\"br0\">&#40;<\/span><span class=\"kw4\">int<\/span> x,<span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#40;<\/span><span class=\"sy2\">*<\/span>fullMap<span class=\"br0\">&#41;<\/span>.<span class=\"me1\">erase<\/span><span class=\"br0\">&#40;<\/span>Coordinates<span class=\"br0\">&#40;<\/span>x,y<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Naszymi argumentami s\u0105 wsp\u00f3\u0142rz\u0119dne punktu kt\u00f3ry chcemy usun\u0105\u0107. Jak realizujemy t\u0119 operacj\u0119? Po prostu usuwamy z mapy punkt o danych koordynatach. Nic skomplikowanego, prawda? <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Gar\u015b\u0107 teorii &#8211; hierarchia klas<\/h2>\n\n\n\n<p>Naszym celem na dzie\u0144 dzisiejszy jest zaimplementowanie systemu narz\u0119dzi. Wg za\u0142o\u017ce\u0144, powinni\u015bmy mie\u0107 do dyspozycji nast\u0119puj\u0105ce narz\u0119dzia: <\/p>\n\n\n\n<ul><li><strong>pojedynczy punkt <\/strong>(rysuje drzewo\/po\u017car\/spalone drzewo po klikni\u0119ciu lewego przycisku myszy (LPM)<\/li><li><strong>o\u0142\u00f3wek<\/strong> (zaczyna rysowa\u0107 po naci\u015bni\u0119ciu LPM. Ko\u0144czy rysowa\u0107 po puszczeniu LPM) <\/li><li><strong>spray<\/strong> (rysuje kilkana\u015bcie rozrzuconych punkt\u00f3w wewn\u0105trz okr\u0119gu o okre\u015blonym rozmiarze, analogicznie jak spray w Paincie) <\/li><\/ul>\n\n\n\n<p>Jak mo\u017cemy zaimplementowa\u0107&nbsp;powy\u017csze narz\u0119dzia? Zauwa\u017cy\u0142e\u015b w nich co\u015b ciekawego? Widzisz jakie\u015b wsp\u00f3lne elementy? Ot\u00f3\u017c, ka\u017cde narz\u0119dzie rysuje jeden z czterech rodzaj\u00f3w punktu. Typy tych punkt\u00f3w zadeklarowali\u015bmy ju\u017c wcze\u015bniej w enum PType. Zauwa\u017c, \u017ce ka\u017cde z narz\u0119dzi rysuje punkt w jednej z trzech chwil: naci\u015bni\u0119cie LPM, puszczenie LPM lub ruszanie kursorem po wci\u015bni\u0119ciu LPM. Przyuwa\u017cenie tych wsp\u00f3lnych cech pozwala nam napisa\u0107 klas\u0119 abstrakcyjn\u0105 ATool, kt\u00f3ra deklaruje podstawowe metody s\u0142u\u017c\u0105ce do u\u017cywania wybranego narz\u0119dzia. Konkretne narz\u0119dzia, takie jak o\u0142\u00f3wek czy spray, b\u0119d\u0105 dziedziczy\u0142y po ATool, nadpisuj\u0105c potrzebne im do poprawnego dzia\u0142ania metody.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deklaracja i implementacja narz\u0119dzi<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">ATool &#8211; klasa bazowa dla wszystkich narz\u0119dzi<\/h3>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw2\">class<\/span> ATool <span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw2\">public<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">virtual<\/span> <span class=\"kw4\">void<\/span> onMouseDown<span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">virtual<\/span> <span class=\"kw4\">void<\/span> onMouseUp<span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">virtual<\/span> <span class=\"kw4\">void<\/span> onMouseMotion<span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> changeType<span class=\"br0\">&#40;<\/span>PType __newType<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; PType getType<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"kw1\">return<\/span> type<span class=\"sy4\">;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">virtual<\/span> ~ATool<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"kw2\">protected<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; ATool<span class=\"br0\">&#40;<\/span>PType __type,ForestMap<span class=\"sy2\">*<\/span> __map<span class=\"br0\">&#41;<\/span> <span class=\"sy4\">:<\/span>map<span class=\"br0\">&#40;<\/span>__map<span class=\"br0\">&#41;<\/span>, type<span class=\"br0\">&#40;<\/span>__type<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; ForestMap<span class=\"sy2\">*<\/span> map <span class=\"sy1\">=<\/span> <span class=\"kw2\">nullptr<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"kw2\">private<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; PType type<span class=\"sy4\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy4\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Sp\u00f3jrz na powy\u017cszy kod. Stanowi on kwintesencj\u0119 tego, co powiedzieli\u015bmy w poprzednim rozdziale. <\/p>\n\n\n\n<p>Zacznijmy od prywatnych atrybut\u00f3w klasy. Zdefiniowali\u015bmy zmienn\u0105 type, kt\u00f3ra przechowuje rodzaj punkt\u00f3w aktualnie rysowanych przez narz\u0119dzie. Po co nam ForestMap i to jeszcze w formie staro\u015bwieckiego wska\u017anika? Potrzebujemy go poniewa\u017c o\u0142\u00f3wek czy spray musi mie\u0107 mo\u017cliwo\u015b\u0107 realizacji swojego zadania, czyli dodania jednego lub wi\u0119kszej ilo\u015bci punkt\u00f3w. Narz\u0119dzie nie zarz\u0105dza czasem \u017cycia ForestMapy, wi\u0119c nie musimy jej przekazywa\u0107 ca\u0142ego <a href=\"https:\/\/www.kompikownia.pl\/index.php\/2018\/09\/22\/inteligentne-wskazniki-unique_ptr\/\">unique_pointera<\/a>. Wystarczy, \u017ce przeka\u017cemy wska\u017anik na  obiekt.<\/p>\n\n\n\n<p>Lecz powstaje kolejne pytanie. Dlaczego ForestMap jest elementem &#8222;chronionym&#8221; a nie &#8222;prywatnym&#8221; klasy? Zrobili\u015bmy tak dlatego, gdy\u017c klasy potomne ATool musz\u0105 mie\u0107 mo\u017cliwo\u015b\u0107 dodawania lub usuwania punkt\u00f3w z ForestMapy. Gdyby\u015bmy ForestMap uczynili prywatnym atrybutem klasy, klasy potomne nie mia\u0142yby do niego dost\u0119pu.<\/p>\n\n\n\n<p>Hmmm. Konstruktor te\u017c jest chroniony. Jakie ma to uzasadnienie? ATool nie reprezentuje \u017cadnego &#8222;konkretnego&#8221; narz\u0119dzia. Nie chcemy aby by\u0142a mo\u017cliwo\u015b\u0107&nbsp;utworzenia obiektu tej klasy. Klasa ATool ma stanowi\u0107 jedynie &#8222;szablon&#8221; dla swoich potomk\u00f3w. Umieszczenie konstruktora w sekcji chronionej jest idealnym rozwi\u0105zaniem. Obiektu takiego tworu nie b\u0119dzie mo\u017cna utworzy\u0107. Jednocze\u015bnie klasy pochodne mog\u0105 korzysta\u0107 z konstruktora klasy ATool.<\/p>\n\n\n\n<p>Co mo\u017cemy powiedzie\u0107 o publicznych metodach? Przede wszystkim spogl\u0105damy na wiersze 6-8. Te metody b\u0119d\u0105 odwala\u0142y najwi\u0119cej brudnej roboty. B\u0119d\u0105 wywo\u0142ywane b\u0119d\u0105 odpowiednio gdy zostanie naci\u015bni\u0119ty\/puszczony lewy przycisk myszy. Ostatnia metoda b\u0119dzie wywo\u0142ywana wtedy, gdy kursor myszy wykona ruch. Powstaje pytanie, dlaczego s\u0105 one wirtualne? Chcemy skorzysta\u0107 z polimorfizmu. Operator virtual zapewnia nas, \u017ce zostanie wybrana odpowiednia wersja metody w zale\u017cno\u015bci od rodzaju utworzonego obiektu. <\/p>\n\n\n\n<p>Metoda changeType pozwala na zmian\u0119 rodzaju punktu rysowanego przez narz\u0119dzie. To tutaj b\u0119dziemy wybierali, czy chcemy rysowa\u0107 np.: drzewa czy po\u017car. Analogicznie getType pozwala wybra\u0107 typ aktualnie rysowanego punktu.<\/p>\n\n\n\n<p>Wiemy ju\u017c, jak og\u00f3lnie ma wygl\u0105da\u0107 narz\u0119dzie. Pora wzi\u0105\u0107 si\u0119 za implementacj\u0119 konkretnych rozwi\u0105za\u0144 \ud83d\ude42 <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pojedynczy punkt &#8211; najprostsze mo\u017cliwe narz\u0119dzie<\/h3>\n\n\n\n<p>Przypomnijmy, za co ma odpowiada\u0107 narz\u0119dzie pojedynczy punkt? Ot\u00f3\u017c powinno rysowa\u0107 drzewo\/po\u017car\/spalone drzewo\/czy\u015bci\u0107 w miejscu, kt\u00f3re klikniemy LPM. Wnioskujemy z tego, \u017ce musimy nadpisa\u0107 metod\u0119 onMouseDown. No to bierzmy si\u0119 do roboty!<\/p>\n\n\n\n<p>Definicja klasy w pliku nag\u0142\u00f3wkowym b\u0119dzie wygl\u0105da\u0142a nast\u0119puj\u0105co: <\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>19<br \/>20<br \/>21<br \/>22<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw2\">class<\/span> ToolSinglePoint <span class=\"sy4\">:<\/span> <span class=\"kw2\">public<\/span> ATool <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; ToolSinglePoint<span class=\"br0\">&#40;<\/span>PType __type,ForestMap<span class=\"sy2\">*<\/span> __map<span class=\"br0\">&#41;<\/span> <span class=\"sy4\">:<\/span> ATool<span class=\"br0\">&#40;<\/span>__type,__map<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> onMouseDown<span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"kw2\">override<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy4\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Nic niezwyk\u0142ego. ToolSinglePoint dziedziczy publicznie po ATool. Dlaczego publicznie? Poniewa\u017c chcemy, aby publiczne metody pozosta\u0142y publiczne, chronione &#8211; chronione a prywatne &#8211; prywatne. Tylko dziedziczenie publiczne pozwala nam na takie co\u015b. <\/p>\n\n\n\n<p>Nadpisali\u015bmy tylko metod\u0119 onMouseDown. W niej b\u0119dziemy dodawali punkt do ForestMapy. Jak b\u0119dzie wygl\u0105da\u0142a ta operacja? Zobaczmy:<\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw4\">void<\/span> ToolSinglePoint<span class=\"sy4\">::<\/span><span class=\"me2\">onMouseDown<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span>getType<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy3\">!<\/span><span class=\"sy1\">=<\/span>NONE<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; map<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>add<span class=\"br0\">&#40;<\/span>x,y, getType<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; map<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>del<span class=\"br0\">&#40;<\/span>x,y<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>W linijce 7 zauwa\u017camy zastosowanie nowej pozycji enum PType. Sprawdzamy, czy nie jest on r\u00f3wny NONE. W takim wypadku po prostu dodajemy punkt o okre\u015b\u0142onym typie znajduj\u0105cy si\u0119 w okre\u015blonym miejscu do ForestMapy. Je\u015bli typ rysowanego punktu to NONE, musimy usun\u0105\u0107&nbsp;wszystko co znajduje si\u0119 w tym miejscu.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">O\u0142\u00f3wek &#8211; rysowanie ci\u0105g\u0142e<\/h3>\n\n\n\n<p>Podnie\u015bmy poprzeczk\u0119 o jedno oczko wy\u017cej. Zaimplementujemy teraz o\u0142\u00f3wek. Jak on dzia\u0142a? Ma rysowa\u0107 punkty danego typu od momentu wci\u015bni\u0119cia LPM do momentu puszczenia.<\/p>\n\n\n\n<p>Zastan\u00f3wmy si\u0119&nbsp;chwilk\u0119, czym b\u0119dzie r\u00f3\u017cni\u0142 si\u0119 o\u0142\u00f3wek od ToolSinglePoint? W sumie r\u00f3\u017cnica b\u0119dzie bardzo niewielka. Obydwa narz\u0119dzia robi\u0105 to samo przy naci\u015bni\u0119ciu LPM. Wynika st\u0105d, \u017ce metoda onMouseDown b\u0119dzie identyczna. ToolSinglePoint rysuje punkty tak\u017ce podczas ruchu myszki. Wniosek jest taki, \u017ce powinni\u015bmy nadpisa\u0107 metod\u0119 onMouseMotion. Jak b\u0119dzie wygl\u0105da\u0142o dodawanie punkt\u00f3w podczas ruchu myszki? Dok\u0142adnie tak samo jak przy klikni\u0119ciu.<\/p>\n\n\n\n<p>Czy w takim wypadku o\u0142\u00f3wek rzeczywi\u015bcie musi dziedziczy\u0107 po ATool? Ot\u00f3\u017c, niekoniecznie. Bli\u017cszym przodkiem dla o\u0142\u00f3wka jest ToolSinglePoint. I w\u0142a\u015bnie tak stworzymy to narz\u0119dzie. <\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw2\">class<\/span> ToolPencil <span class=\"sy4\">:<\/span> <span class=\"kw2\">public<\/span> ToolSinglePoint <span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw2\">public<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; ToolPencil<span class=\"br0\">&#40;<\/span>PType __type,ForestMap<span class=\"sy2\">*<\/span> __map<span class=\"br0\">&#41;<\/span> <span class=\"sy4\">:<\/span> ToolSinglePoint<span class=\"br0\">&#40;<\/span>__type,__map<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> onMouseMotion<span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"kw2\">override<\/span> <span class=\"br0\">&#123;<\/span>this<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>onMouseDown<span class=\"br0\">&#40;<\/span>x,y<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy4\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Spray &#8211; losowe rozmieszczanie punkt\u00f3w<\/h3>\n\n\n\n<p>Spray b\u0119dzie bardziej skomplikowany od o\u0142\u00f3wka czy pojedynczego punktu. Wykonajmy najpierw deklaracj\u0119 klasy.<\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw2\">class<\/span> ToolSpray <span class=\"sy4\">:<\/span> <span class=\"kw2\">public<\/span> ATool <span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw2\">public<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; ToolSpray<span class=\"br0\">&#40;<\/span>PType __type,ForestMap<span class=\"sy2\">*<\/span> __map,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> size<span class=\"br0\">&#41;<\/span> <span class=\"sy4\">:<\/span> ATool<span class=\"br0\">&#40;<\/span>__type,__map<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> onMouseDown<span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"kw2\">override<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> onMouseMotion<span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"kw2\">override<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"kw2\">private<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; &nbsp;<span class=\"kw4\">const<\/span> <span class=\"kw4\">int<\/span> size <span class=\"sy1\">=<\/span> <span class=\"nu0\">5<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">const<\/span> <span class=\"kw4\">double<\/span> numberOfPointsMultiplier <span class=\"sy1\">=<\/span> <span class=\"nu16\">0.5<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy4\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Nic niezwyk\u0142ego. Tym razem nadpisujemy metody onMouseDown i onMouseMotion. W zmiennych prywatnych stworzyli\u015bmy sta\u0142\u0105 size. Po co? Poniewa\u017c spray musi rozprowadza\u0107 punkty w pewnej odleg\u0142o\u015bci od miejsca w kt\u00f3rym klikn\u0119li\u015bmy. Wprowadzenie takiej sta\u0142ej pozwoli nam \u0142atwo doda\u0107 mo\u017cliwo\u015b\u0107 zmiany rozmiaru spraya w przysz\u0142o\u015bci.<\/p>\n\n\n\n<p>Zmienna prywatna numberOfPointsMultiplier pozwala na zmian\u0119 ilo\u015bci punkt\u00f3w generowan\u0105 przy pojedynczym wywo\u0142aniu jednej z metod on*.<\/p>\n\n\n\n<p>Zobaczmy, jak mo\u017cemy zdefiniowa\u0107 metody onMouseDown i onMouseMotion tak, aby spray dzia\u0142a\u0142 prawid\u0142owo. <\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw4\">void<\/span> ToolSpray<span class=\"sy4\">::<\/span><span class=\"me2\">onMouseDown<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span>getType<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy3\">!<\/span><span class=\"sy1\">=<\/span>NONE<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> numberOfPoints <span class=\"sy1\">=<\/span> size<span class=\"sy2\">*<\/span><span class=\"nu16\">0.5<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; std<span class=\"sy4\">::<\/span><span class=\"me2\">default_random_engine<\/span> generator<span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; generator.<span class=\"me1\">seed<\/span><span class=\"br0\">&#40;<\/span>std<span class=\"sy4\">::<\/span><span class=\"me2\">chrono<\/span><span class=\"sy4\">::<\/span><span class=\"me2\">system_clock<\/span><span class=\"sy4\">::<\/span><span class=\"me2\">now<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">time_since_epoch<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">count<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; std<span class=\"sy4\">::<\/span><span class=\"me2\">uniform_real_distribution<\/span><span class=\"sy1\">&lt;<\/span><span class=\"kw4\">double<\/span><span class=\"sy1\">&gt;<\/span> distribution<span class=\"br0\">&#40;<\/span><span class=\"nu0\">0<\/span>,<span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">for<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> i <span class=\"sy1\">=<\/span> <span class=\"nu0\">0<\/span><span class=\"sy4\">;<\/span>i<span class=\"sy1\">&lt;<\/span>numberOfPoints<span class=\"sy4\">;<\/span>i<span class=\"sy2\">++<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw4\">double<\/span> r <span class=\"sy1\">=<\/span> size<span class=\"sy2\">*<\/span><span class=\"kw3\">sqrt<\/span><span class=\"br0\">&#40;<\/span>distribution<span class=\"br0\">&#40;<\/span>generator<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw4\">double<\/span> angle <span class=\"sy1\">=<\/span> distribution<span class=\"br0\">&#40;<\/span>generator<span class=\"br0\">&#41;<\/span><span class=\"sy2\">*<\/span><span class=\"nu0\">2<\/span><span class=\"sy2\">*<\/span>M_PI<span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw4\">int<\/span> pointx <span class=\"sy1\">=<\/span> x<span class=\"sy2\">+<\/span>r<span class=\"sy2\">*<\/span><span class=\"kw3\">cos<\/span><span class=\"br0\">&#40;<\/span>angle<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw4\">int<\/span> pointy <span class=\"sy1\">=<\/span> y<span class=\"sy2\">+<\/span>r<span class=\"sy2\">*<\/span><span class=\"kw3\">sin<\/span><span class=\"br0\">&#40;<\/span>angle<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; map<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>add<span class=\"br0\">&#40;<\/span>pointx,pointy,getType<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"kw4\">void<\/span> ToolSpray<span class=\"sy4\">::<\/span><span class=\"me2\">onMouseMotion<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> x,<span class=\"kw4\">unsigned<\/span> <span class=\"kw4\">int<\/span> y<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; this<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>onMouseDown<span class=\"br0\">&#40;<\/span>x,y<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>W linijce 17 obliczamy ilo\u015b\u0107 punkt\u00f3w, kt\u00f3re wygenerujemy przy pojedynczym wywo\u0142aniu metody. Linijka 18,19 i 20 to konfiguracja generatora o rozk\u0142adzie r\u00f3wnomiernym. Od linii nr 21 zaczynamy w\u0142a\u015bciwe generowanie punkt\u00f3w.<\/p>\n\n\n\n<p>Zak\u0142adamy, \u017ce punkt w kt\u00f3rym u\u017cytkownik klikn\u0105\u0142 to \u015brodek ko\u0142a. Najpierw obliczamy, w jakiej odleg\u0142o\u015bci od \u015brodka wygenerujemy nowy punkt. Kolejny krok to wyliczenie w kt\u00f3rej cz\u0119\u015bci ko\u0142a zostanie utworzona kropka. Gdy mamy ju\u017c te dwie zmienne, mo\u017cemy obliczy\u0107 w\u0142a\u015bciwe wsp\u00f3\u0142rz\u0119dne x i y generowanego punkciku. Na samym ko\u0144cu dodajemy punkt do mapy.<\/p>\n\n\n\n<p>Sk\u0105d wzi\u0119\u0142y si\u0119 takie a nie inne wzory? Nie jest to blog matematyczny. Artyku\u0142 te\u017c nie jest po\u015bwi\u0119cony zawi\u0142o\u015bciom kr\u00f3lowej nauk. Je\u015bli jeste\u015b zainteresowany szczeg\u00f3\u0142ami, mog\u0119 odes\u0142a\u0107 do <a rel=\"noreferrer noopener\" aria-label=\" (otwiera si\u0119 na nowej zak\u0142adce)\" href=\"https:\/\/www.gamedev.net\/forums\/topic\/332994-random-point-in-a-circle\/\" target=\"_blank\">ciekawej dyskusji na ten temat<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jak skorzysta\u0107 z narz\u0119dzi? Modyfikacja SDLMain<\/h2>\n\n\n\n<p>Utworzyli\u015bmy ju\u017c trzy podstawowe narz\u0119dzia, kt\u00f3rych b\u0119dziemy u\u017cywa\u0107. W przysz\u0142o\u015bci nieco je zmodyfikujemy tak, aby by\u0142a mo\u017cliwo\u015b\u0107&nbsp;zmiany rozmiaru spraya czy o\u0142\u00f3wka. Teraz spr\u00f3bujmy po\u0142\u0105czy\u0107 nowo utworzone zabawki z g\u0142\u00f3wnym programem. <\/p>\n\n\n\n<p>Na pierwszy ogie\u0144 p\u00f3jdzie plik nag\u0142\u00f3wkowy SDLMain.h. Co musimy zrobi\u0107, aby\u015bmy mogli u\u017cy\u0107 narz\u0119dzia? SDLMain musi przechowywa\u0107 wska\u017anik do ATool. Dlaczego do ATool a nie konkretnego typu narz\u0119dzia? Poniewa\u017c chcemy zapewni\u0107 sobie mo\u017cliwo\u015b\u0107 zmiany narz\u0119dzia podczas dzia\u0142ania programu. Dzi\u0119ki klasie, mo\u017cna powiedzie\u0107, abstrakcyjnej ATool mo\u017cemy w pe\u0142ni skorzysta\u0107 z tzw. polimorfizmu. <\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw2\">class<\/span> SDLMain <span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw2\">public<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> init<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> clear<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> drawPoint<span class=\"br0\">&#40;<\/span><span class=\"kw4\">int<\/span> x,<span class=\"kw4\">int<\/span> y,PType type<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> gameLoop<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> setResolution<span class=\"br0\">&#40;<\/span><span class=\"kw4\">int<\/span> width,<span class=\"kw4\">int<\/span> height<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"kw2\">private<\/span><span class=\"sy4\">:<\/span><br \/>\n&nbsp; &nbsp; unique_ptr<span class=\"sy1\">&lt;<\/span>ForestMap<span class=\"sy1\">&gt;<\/span> map<span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; unique_ptr<span class=\"sy1\">&lt;<\/span>ATool<span class=\"sy1\">&gt;<\/span> tool<span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; SDL_Window <span class=\"sy2\">*<\/span>win <span class=\"sy1\">=<\/span> <span class=\"kw2\">nullptr<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; SDL_Renderer<span class=\"sy2\">*<\/span> renderer <span class=\"sy1\">=<\/span> <span class=\"kw2\">nullptr<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; function<span class=\"sy1\">&lt;<\/span><span class=\"kw4\">void<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw4\">int<\/span>,<span class=\"kw4\">int<\/span>,PType<span class=\"br0\">&#41;<\/span><span class=\"sy1\">&gt;<\/span> func<span class=\"sy4\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy4\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Aby\u015bmy mogli przetestowa\u0107 dane narz\u0119dzie, musimy zmodyfikowa\u0107 metod\u0119 init.<\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw4\">void<\/span> SDLMain<span class=\"sy4\">::<\/span><span class=\"me2\">init<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; win <span class=\"sy1\">=<\/span> SDL_CreateWindow<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;Symulator po\u017caru lasu&quot;<\/span>,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,<span class=\"nu0\">700<\/span>,<span class=\"nu0\">700<\/span>,SDL_WINDOW_SHOWN<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; renderer <span class=\"sy1\">=<\/span> SDL_CreateRenderer<span class=\"br0\">&#40;<\/span>win,<span class=\"sy2\">-<\/span><span class=\"nu0\">1<\/span>,SDL_RENDERER_ACCELERATED<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; func <span class=\"sy1\">=<\/span> bind<span class=\"br0\">&#40;<\/span><span class=\"sy3\">&amp;<\/span>SDLMain<span class=\"sy4\">::<\/span><span class=\"me2\">drawPoint<\/span>,<span class=\"kw3\">this<\/span>,placeholders<span class=\"sy4\">::<\/span>_1,placeholders<span class=\"sy4\">::<\/span>_2,placeholders<span class=\"sy4\">::<\/span>_3<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; map <span class=\"sy1\">=<\/span> make_unique<span class=\"sy1\">&lt;<\/span>ForestMap<span class=\"sy1\">&gt;<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; map<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>add<span class=\"br0\">&#40;<\/span><span class=\"nu0\">50<\/span>,<span class=\"nu0\">50<\/span>,EXIST<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; setResolution<span class=\"br0\">&#40;<\/span><span class=\"nu0\">100<\/span>,<span class=\"nu0\">100<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; tool <span class=\"sy1\">=<\/span> make_unique<span class=\"sy1\">&lt;<\/span>ToolSpray<span class=\"sy1\">&gt;<\/span><span class=\"br0\">&#40;<\/span>EXIST,map.<span class=\"me1\">get<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>Nowe linijki to 16 i 17. W linijce 16 ustawiamy wirtualn\u0105 rozdzielczo\u015b\u0107 za pomoc\u0105 utworzonej w poprzedniej cz\u0119\u015bci metody. Robimy to aby punkty by\u0142y wi\u0119ksze. Gdyby\u015bmy nie u\u017cyli tej metody to pojedynczy punkt na ekranie o wysokiej rozdzielczo\u015bci by\u0142by praktycznie niewidoczny. <\/p>\n\n\n\n<p>Linijka 17 to utworzenie narz\u0119dzia (w tym wypadku Spray), kt\u00f3re b\u0119dzie rysowa\u0142o drzewa. Jako drugi argument przekazujemy wska\u017anik do ForestMapy, kt\u00f3ry uzyskujemy z <a href=\"https:\/\/www.kompikownia.pl\/index.php\/2018\/09\/22\/inteligentne-wskazniki-unique_ptr\/\">unique_ptr&#8217;a<\/a> za pomoc\u0105 metody get. Je\u015bli chcemy przetestowa\u0107 inne narz\u0119dzie, tworzymy obiekt typu ToolSinglePoint albo ToolPencil. <\/p>\n\n\n\n<p>Co jeszcze si\u0119 zmieni? Ka\u017cde z narz\u0119dzi posiada metody onMouseDown\/Up\/Motion. Musimy doda\u0107 obs\u0142ug\u0119 zdarze\u0144 i wywo\u0142ywa\u0107 te metody w odpowiedzi na nie. Sp\u00f3jrzmy wi\u0119c, jak b\u0119dzie wygl\u0105da\u0142a nowa wersja metody gameLoop.<\/p>\n\n\n<div class=\"codecolorer-container cpp default\" style=\"overflow:auto;white-space:nowrap;width:90%;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/>45<br \/>46<br \/>47<br \/>48<br \/>49<br \/>50<br \/>51<br \/>52<br \/>53<br \/>54<br \/>55<br \/>56<br \/>57<br \/>58<br \/>59<br \/>60<br \/>61<br \/>62<br \/><\/div><\/td><td><div class=\"cpp codecolorer\"><span class=\"kw4\">void<\/span> SDLMain<span class=\"sy4\">::<\/span><span class=\"me2\">gameLoop<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw4\">bool<\/span> is_running <span class=\"sy1\">=<\/span> <span class=\"kw2\">true<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">while<\/span><span class=\"br0\">&#40;<\/span>is_running<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; SDL_Event ev<span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; clear<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">while<\/span><span class=\"br0\">&#40;<\/span>SDL_PollEvent<span class=\"br0\">&#40;<\/span><span class=\"sy3\">&amp;<\/span>ev<span class=\"br0\">&#41;<\/span><span class=\"sy3\">!<\/span><span class=\"sy1\">=<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw4\">int<\/span> x,y<span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SDL_GetMouseState<span class=\"br0\">&#40;<\/span><span class=\"sy3\">&amp;<\/span>x,<span class=\"sy3\">&amp;<\/span>y<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span>ev.<span class=\"me1\">type<\/span><span class=\"sy1\">==<\/span>SDL_MOUSEBUTTONDOWN <span class=\"sy3\">&amp;&amp;<\/span> ev.<span class=\"me1\">button<\/span>.<span class=\"me1\">button<\/span><span class=\"sy1\">==<\/span>SDL_BUTTON_LEFT<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tool<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>onMouseDown<span class=\"br0\">&#40;<\/span>x<span class=\"sy2\">\/<\/span><span class=\"nu0\">7<\/span>,y<span class=\"sy2\">\/<\/span><span class=\"nu0\">7<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span>ev.<span class=\"me1\">type<\/span><span class=\"sy1\">==<\/span>SDL_MOUSEBUTTONUP <span class=\"sy3\">&amp;&amp;<\/span> ev.<span class=\"me1\">button<\/span>.<span class=\"me1\">button<\/span><span class=\"sy1\">==<\/span>SDL_BUTTON_LEFT<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tool<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>onMouseUp<span class=\"br0\">&#40;<\/span>x<span class=\"sy2\">\/<\/span><span class=\"nu0\">7<\/span>,y<span class=\"sy2\">\/<\/span><span class=\"nu0\">7<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span>ev.<span class=\"me1\">type<\/span><span class=\"sy1\">==<\/span>SDL_MOUSEMOTION <span class=\"sy3\">&amp;&amp;<\/span> ev.<span class=\"me1\">button<\/span>.<span class=\"me1\">button<\/span><span class=\"sy1\">==<\/span>SDL_BUTTON_LEFT<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tool<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>onMouseMotion<span class=\"br0\">&#40;<\/span>x<span class=\"sy2\">\/<\/span><span class=\"nu0\">7<\/span>,y<span class=\"sy2\">\/<\/span><span class=\"nu0\">7<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; map<span class=\"sy2\">-<\/span><span class=\"sy1\">&gt;<\/span>drawAll<span class=\"br0\">&#40;<\/span>func<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; SDL_RenderPresent<span class=\"br0\">&#40;<\/span>renderer<span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; SDL_Delay<span class=\"br0\">&#40;<\/span><span class=\"nu0\">1000<\/span><span class=\"sy2\">\/<\/span><span class=\"nu0\">60<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy4\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n\n\n<p>W linijce 45 tworzymy p\u0119tl\u0119, kt\u00f3ra b\u0119dzie obs\u0142ugiwa\u0142a zdarzenia. Warunek zak\u0142ada, \u017ce obs\u0142uga zdarze\u0144 b\u0119dzie wykonywana dop\u00f3ki, dop\u00f3ty s\u0105 jakie\u015b zdarzenia do obs\u0142u\u017cenia. <\/p>\n\n\n\n<p>Linijka 46 i 47 pozwalaj\u0105 nam na pobranie i przechowanie wsp\u00f3\u0142rz\u0119dnych na jakie obecnie wskazuje myszka u\u017cytkownika. Wykorzystujemy to nieco dalej. <\/p>\n\n\n\n<p>Wiersze 48-56 to obs\u0142uga zdarze\u0144 klikni\u0119cia\/puszczenia\/ruchu myszy. W ramach reakcji na zdarzenie wywo\u0142ujemy odpowiedni\u0105 metod\u0119 z wybranego narz\u0119dzia. Dzi\u0119ki odpowiednio zastosowanemu polimorfizmowi jeste\u015bmy pewni, \u017ce zostanie wybrana odpowiednia wersja metody i wybrane przez u\u017cytkownika narz\u0119dzie b\u0119dzie funkcjonowa\u0142o tak jak powinno.<\/p>\n\n\n\n<p>Na wyja\u015bnienie zas\u0142uguje dzielenie przez si\u00f3demk\u0119 ka\u017cdej ze wsp\u00f3\u0142rz\u0119dnych. Dlaczego to robimy? Jest to tymczasowe rozwi\u0105zanie. Okno, kt\u00f3re utworzyli\u015bmy, ma wymiary 700 na 700 pikseli. Wirtualna rozdzielczo\u015b\u0107 naszego okna to 100 na 100. Musimy przeprowadzi\u0107 konwersj\u0119 wsp\u00f3\u0142rz\u0119dnych &#8222;globalnych&#8221; na wsp\u00f3\u0142rz\u0119dne &#8222;lokalne&#8221;. Nasze wirtualne okno ma 7 razy mniejsz\u0105 rozdzielczo\u015b\u0107 od w\u0142a\u015bciwego okna. Dlatego dzielimy ka\u017cd\u0105 wsp\u00f3\u0142rz\u0119dn\u0105 z procedury obs\u0142ugi okna przez 7.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"702\" height=\"723\" src=\"https:\/\/www.kompikownia.pl\/wp-content\/uploads\/2019\/02\/Screenshot_20190216_111708.png\" alt=\"\" class=\"wp-image-902\"\/><figcaption>Tak prezentuje si\u0119 teraz nasza aplikacja<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Co dalej?<\/h2>\n\n\n\n<p>Idziemy powoli, ale do przodu. Nasza aplikacja pozwala ju\u017c na malowanie r\u00f3\u017cnokolorowych punkt\u00f3w. Mo\u017cna powiedzie\u0107, \u017ce stworzyli\u015bmy ubog\u0105 wersj\u0119 Painta. Aplikacja posiada ju\u017c jak\u0105\u015b funkcjonalno\u015b\u0107 ale musisz pami\u0119ta\u0107, \u017ce jeszcze dosy\u0107 du\u017co wody w Wi\u015ble musi up\u0142yn\u0105\u0107 zanim sko\u0144czymy prac\u0119. <\/p>\n\n\n\n<p>Obecna wersja programu posiada kilka wad. Przede wszystkim, zmiana narz\u0119dzia (a nawet jego parametr\u00f3w) wymaga zmiany kodu \u017ar\u00f3d\u0142owego i ponownej kompilacji programu. Drugim problemem jest to, \u017ce nie da si\u0119 zmieni\u0107 rozmiaru p\u0119dzli czy spraya. Je\u015bli pobawisz si\u0119 t\u0105 aplikacj\u0105 zauwa\u017cysz jeszcze jeden uszczerbek. Narz\u0119dzia nie generuj\u0105 obw\u00f3dki. W przypadku spraya musimy wi\u0119c domy\u015b\u0142i\u0107 si\u0119 w kt\u00f3rym miejscu mog\u0105 pojawi\u0107 si\u0119 punkty. <\/p>\n\n\n\n<p>Te i by\u0107 mo\u017ce inne problemy rozwi\u0105\u017cemy nast\u0119pnym razem. <\/p>\n\n\n\n<p>Standardowo,<a href=\"https:\/\/github.com\/karol221-10\/forest_fire\/tree\/article-3\"> aktualny kod \u017ar\u00f3d\u0142owy jest dost\u0119pny w repozytorium na Githubie<\/a>. Zapraszam do komentowania i dzielenia si\u0119 uwagami \ud83d\ude42 <\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Czas czytania:<\/span> <span class=\"rt-time\">7<\/span> <span class=\"rt-label rt-postfix\">minut<\/span><\/span> Semestr si\u0119 ju\u017c zako\u0144czy\u0142 &#8230; Nie da\u0142em rady opisywa\u0107 na bie\u017c\u0105co rozwoju projektu symulatora po\u017caru lasu. Na szcz\u0119\u015bcie wszystko zaliczy\u0142em w pierwszym terminie i teraz mam troch\u0119 wolnego czasu. Dzi\u0119ki &#8230;<\/p>\n","protected":false},"author":1,"featured_media":900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[31,34],"tags":[],"_links":{"self":[{"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/posts\/837"}],"collection":[{"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/comments?post=837"}],"version-history":[{"count":63,"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/posts\/837\/revisions"}],"predecessor-version":[{"id":903,"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/posts\/837\/revisions\/903"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/media\/900"}],"wp:attachment":[{"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/media?parent=837"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/categories?post=837"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kompikownia.pl\/index.php\/wp-json\/wp\/v2\/tags?post=837"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}