Po kilku dniach niezbyt intensywnego zastanawiania się nad strukturą systemu GUI zdołałem wysmażyć coś, co można nazwać schematycznym modelem klas. Jest on wybitnie poglądowy i przedstawia się następująco:
Na pierwszy rzut oka może wydawać się nieco pokręcony, ale z odrobiną wysiłku można go odcyfrować :] To co jest w nim chyba najważniejsze, to dość wyraźny podział na część rysującą (lewa strona) i tę zawierającą kontrolki. Łączy je “most” złożony z głównej klasy systemu, nazwanej bardzo oryginalnie: System :) Taki podział zapewni między innymi prostsze rysowanie samych kontrolek, które będą renderowane przy pomocy takich poleceń jak: narysuj ramkę, narysuj wciśnięty przycisk, itp. To rozwiązanie zaczerpnąłem z Windows.Forms, gdzie jest zresztą ono posunięte o wiele dalej.
Lista kontrolek jest, jak widać, skromna i odpowiada tej, którą wcześniej ustaliłem jako minimalną. Oprócz abstrakcyjnej klasy dla wszystkich kontrolek wprowadziłem też osobną dla takich, które mogą zawierać i grupować inne kontrolki. Póki co jedynym obiektem tego rodzaju jest okno, ale GUI zna ich więcej: jak np. panel czy pole grupy (groupbox).
Oparcie strony o powszechnie znany system CMSowy jest wygodne, ale ma przynajmniej jedną wadę. Podobnie jak popularny system operacyjny (ciekawe, który dokładnie mam na myśli ;)) wymaga on pewności, że zawsze używa się najnowszej wersji. Inaczej można nietrudno paść ofiarą tego, co nazywamy eufemistycznie security issues.
Na szczęście w przypadku WordPress ciężko jest przegapić wydanie nowej wersji. Wiadomość o tym jest bowiem wtedy wyświetlana na głównej stronie panelu administracyjnego. Tak było i dzisiaj, kiedy pojawiła się wersja 2.2.2.
Uaktualnienie poszło gładko i sprawnie. Sądzę więc, że kolejne upgrade’y będą na tyle mało znaczącymi wydarzeniami, że nie będzie warto o nich pisać :)
Jako moderator forum Warsztatu dość często spotykam się z różnymi przejawami tak zwanego lamerstwa. Część z nich jest bardzo typowa, na czele z pokazywaniem kawałka kodu (zwykle obleśnego) i zadawaniem nieśmiertelnego pytania:
No i co tu jest źle?!
Nie trzeba się domyśleć, że reakcja na takie kwiatki jest zwykle dość gwałtowna :)
Innym przykładem lamerstwa są zbyt ogólne pytania – czyli takie, na których odpowiedzi (o ile w ogóle istnieją) kryją za sobą całe, nierzadko bardzo obszerne dziedziny. “Jak napisać grę podobną do …?” czy “Jak dodać do gry tryb multiplayer?” to całkiem reprezentatywne przykłady. Co można zrobić, kiedy napotka się tego rodzaju okaz?
Oczywiście można zareagować drastycznie i represyjnie. Twierdzę jednak, że każdego (no, prawie każdego ;)) lamera da się w końcu odlamić. Nie dysponujemy naturalnie nieograniczonym czasem, by w ten sposób załatwiać wszystkie przypadki. Z odrobiną dobrych chęci można chyba jednak coś zdziałać.
Otóż według mnie dobrą receptą na ogólne pytanie są… pytania bardziej szczegółowe. I to w dużych ilościach, zadawane w sposób logiczny i rzeczowy. Osoba zasypana gradem takich konkretnych pytań, poruszających szczegółowe kwestie z danej dziedziny, na pewno będzie przynajmniej uświadomiona o obszerności tematu, który tknęła. A jeśli posiada odpowiedni zasób umiejętności wyszukiwania – którym to powinien się wykazywać każdy programista i delikwent aspirujący do tego miana – wtedy użyje tych pytań jako wskazówek do poszukiwania informacji na własną rękę. Na forum powróci zaś wówczas, gdy pojawią się bardziej konkretne zapytania i problemy, które z pewnością będą mogły liczyć na przyjaźniejszy odzew.
Czy to zbyt optymistyczny scenariusz? Być może. Na szczęście dość szybko okazałoby się, czy taka okrojona marchewka działa. Jeśli nie, wtedy zawsze można sięgnąć po kij :)
Przedwczoraj Blizzard oficjalnie potwierdził to, co parę dni wcześniej wyciekło do Internetu. Szykuje się drugi dodatek do gry World of Warcraft. Chociaż nie przewiduję, bym w bliskiej przyszłości powrócić do tej gry, muszę przyznać, że informacja ta wybitnie mnie zainteresowała.
Co do samej zawartości dodatku, większość spekulacji okazała się słuszna. Zabiera on graczy do mroźnego kontynentu Northrend na północy Azeroth, nad którym obecnie niepodzielnie panuje władca nieumarłych, czyli Król Lisz (Lich King; to niezbyt zgrabne tłumaczenie jest z WarCrafta 3).
O stronie fabularnej ciężko powiedzieć coś więcej, bo od czasu rozpoczęcia się ery WoW Blizzard nieco zaniedbał tę stronę świata gry. Więcej wiadomo o nowych elementach gry, które mają być wprowadzone w dodatku, jak choćby:
Póki co nic jeszcze nie wiadomo o ewentualnych nowych rasach, jakie mogłyby się pojawić w dodatku.
Na początku trochę mnie zdziwiło, że kolejny dodatek ma się pojawić tak szybko – przecież od wydania poprzedniego minęło ledwie pół roku. Po chwili zastanowienia jest to jednak dość oczywiste: pierwszy dodatek przyniósł Blizzardowi krociowe zyski i rzesze nowych i powracających graczy. Nic dziwnego, że chcą szybko powtórzyć ten manewr.
Dla istniejących graczy problem z nowym dodatkiem i z podniesieniem maksymalnego poziomu postaci polega na tym, że w ten sposób dewaluuje się cały wysiłek włożony w zdobywanie potężnych przedmiotów. Po wyjściu dodatku zostaną one bowiem szybko zastąpione przez zwyczajne nagrody za questy wykonywane podczas podnoszenia poziomu postaci. Innymi słowy, za zabicie kilku potworków będzie można dostać coś, co jest lepsze od łupu wziętego ze zwłok bossa, do którego zabicia potrzebnych było 10 lub 25 osób. Czy to jest fair?
Z pewnością nie, ale Blizzard się tym nie przejmuje. Chodzi tu bowiem o jakieś 10% graczy, którzy mają możliwość brania udziału w tak wielkich i trudnych raidach. Wymaga to oczywiście czasu i poświęcenia, ale nagrody są tego warte. Dopóki, rzecz jasna, ktoś nie zdecyduje się, że trzeba znowu podnieść limit poziomów i wcześniej potężny ekwipunek staje się kupą śmieci.
To oczywiście nie dotyczy pozostałych graczy, których jest zdecydowana większość. A więcej graczy to więcej pieniędzy z abonamentów – bo w końcu głównie o to tutaj chodzi. Tyle że skutkiem ubocznym może być “zmęczenie materiału” graczy zmuszonych co roku do kupowania nowego dodatku, nabijania kolejnych 10 poziomów i zdobywania ekwipunku od nowa. Niewykluczone, że w ten sposób Blizzard zarżnie kurę znoszącą złote jajka.
Nie tak dawno temu w notce Trzy rozwiązania dla relacji zawierania zastanawiałem się nad tym, jak elegancko i odpornie (na błędy) zrealizować interfejs klasy-kontenera zawierającego różne elementy. Po jakimś czasie jednak zapomniałem o całej sprawie, gdyż zająłem się menedżerem fontów, gdzie kwestia ta nie była mi potrzebna.
W końcu przyszła pora na zastanowienie się nad systemem GUI i wtedy przypomniałem sobie o tym problemie. Rezultatem tego jest wątek na forum Warsztatu.
Wywiązała się w nim ciekawa dyskusja, ale ostatecznie tylko odrobinę przybliżyła mnie do dokonania jakichś decyzji. Bardziej interesujące są może nieco inne wnioski, które przy tej okazji wyciągnąłem… Tak, chciałbym sobie teraz trochę pofilozofować :)
Zaskoczyło mnie trochę to, że na proste i jednoznaczne pytanie (“Które rozwiązanie jest lepsze?”) w dziedzinie tak zdawałoby się ścisłej jak programowanie nie ma dobrze uzasadnionej i obiektywnej odpowiedzi. Właściwie wszystkie argumenty, jakie tam padały były wielce subiektywne, na zasadzie: “wydaje mi się”, “bardziej naturalne będzie”, “najbardziej logiczne jest”, itd.
Okazało się, że programowanie – a zwłaszcza faza projektowania – wcale nie musi być taką ścisłą dziedziną, a każdy jego wytwór może mieć indywidualny charakter. Oczywiście, spora część podejmowanych przy okazji decyzji ma inny charakter niż dylemat, czy ładniejszy jest kolor zielony czy czerwony. Zdarzają się jednak i takie, gdzie kryteria są niejasne, nieostre i subiektywne.
Prostota, przejrzystość, elegancja… estetyka… piękno? Czy to dowód, że programowanie można w pewnym stopniu uważać za dziedzinę sztuki?
Tworzenie oprogramowania to nie jest lekki kawałek chleba. Zwłaszcza wtedy, gdy zajmujemy się tym komercyjnie, w zespole i jeszcze musimy dostosować się do wymagań klienta. Co wtedy się dzieje, zgrabnie opisuje rysunek, który wczoraj wpadł mi w ręce:
Na pewno jest w tym sporo prawdy :) Szczególnie interesujący z mojego punktu widzenia jest oczywiście czwarty obrazek, ilustrujący wyniki pracy programisty. Nie ma w nim absolutnie nic dziwnego, bo – jak wiadomo: “gdyby murarze budowali domy tak, jak programiści piszą programy, to jeden dzięcioł zniszczyłby całą cywilizację” ;]
Skoro posiadam już w miarę sprawnie działający moduł odpowiedzialny za grafikę 2D, pora zająć się jednym z jego najważniejszych zastosowań. Bo oprócz menu czy ekranu powitalnego, najważniejszymi dwuwymiarowymi elementami w każdej grze są składowe jej interfejsu użytkownika.
Po co jednak pisać własny system GUI?… Cóż, oprócz uniwersalnej odpowiedzi (“bo tak”) można odrzec, że to po prostu fajne :) W bardziej rozwiniętej wersji uzasadnienie brzmi tak, iż struktura wewnętrzna dobrze napisanego systemu UI to jeden z najelegantszych przykładów zastosowania programowania obiektowego w praktyce. Jest w niej aż gęsto od przeróżnych wzorców projektowych i całość aż kipi od kipi od tego, co nazywam estetyką projektowania.
Tej estetyki niestety będzie mi prawdopodobnie brakować, kiedy później zajmę się już całkiem “trójwymiarowymi” aspektami silnika, jak modelami, organizacją sceny, materiałami, oświetleniem, itd. Zbalansowanie wydajności z przejrzystością interfejsu (i kodu) na pewno będzie wymagało wielu nieprzyjemnych wysiłków…
A zatem z pewną przesadą można powiedzieć, że system GUI będę pisał dla… relaksu :) Wobec takiego postawienia sprawy nie ma rzecz jasna potrzeby odpierania argumentów w stylu: “Przecież to nie jest potrzebne!”, “W D3DX jest już system GUI (screen powyżej)”, “Dublujesz kontrolki systemowe”, itd. Dla porządku dam aczkolwiek jedno logiczne uzasadnienie: te gatunki gier, które najbardziej lubię – a więc RPGi, strategie czy gry ekonomiczne – wykorzystują UI w dużych i różnorodnych ilościach. Więc jeśli kiedyś… no ale do tego chyba przejdziemy znacznie później :]
GUI jest jedną z tych rzeczy, które można rozbudowywać właściwie w nieskończoność. Dlatego przydałoby się od razu ustalić założenia, jakie chciałbym spełnić. Przede wszystkim nie chcę mnożyć kontrolek ponad potrzebę, gdyż sądzę, że w dużej części przypadków do szczęścia wystarczą poniższe cztery:
Faktycznie przydałaby się jeszcze jakaś kontrolka listowa, ale na razie dla prostoty chcę ją pominąć.
Oprócz samych kontrolek ważne jest też odpowiednie ich zachowanie się. Przede wszystkim chodzi tu o kwestię fokusu klawiatury czy capture myszki, a także funkcjonalności klawisza Tab. Krótko mówiąc, chciałbym żeby mój system przypominał UI, które na co dzień można spotkać w Windows.
Tyle że moje UI nie musi być wcale takie “piękne” jak Aero z Windows Vista ;P