All blog entries, ordered from most recent. Entry count: 1198.
# Stawianie realnych celów
Tue
19
Feb 2008
Pasjonaci programowania gier często porywają się z motyką na słońce próbując napisać samemu kompletną grę - taką jak sobie wymarzyli, np. taką jak GTA albo WoW. Nawet jeśli mieliby potrzebną wiedzę i doświadczenie, oczywiste jest, że nie sposób tego dokończyć - to by wymagało wielu lat pracy. Szczególnie, jeśli nie ma motywacji w postaci pieniędzy ani szefa straszącego zwolnieniem, a na horyzoncie pojawią się często nowy, jeszcze lepszy pomysł.
Ja nie twierdzę, że to jest złe. W pewnym sensie to jest tak samo dobre, jak każde inne programowanie - robisz to co lubisz i zdobywasz doświadczenie. Jednak porzucanie coraz to nowego niedokończonego projektu może rodzić frustrację.
Dlatego może warto zacząć wyznaczać sobie realne cele. Zacząć od przyznania się przed samym sobą, że nie jesteś w stanie sam jeden napisać gry takiego kalibru, jak GTA czy WoW. Następnie pomyśleć, co mógłbyś napisać, żeby pozostając w kręgu swoich zainteresowań jednocześnie było możliwe dokończenie tego. To mogą być różne rzeczy. Jeśli chcesz zrobić dobry uczynek, napisz bibliotekę, którą inni programiści mogą wykorzystywać w swoim kodzie. Albo demo, które będzie się miło oglądało. Albo efekt wraz z kodem źródłowym i opisem, z którego inni będą się mogli czegoś nauczyć. Albo program narzędziowy, który przyda się innym programistom.
Oczywiście, punkt widzenia zależy od punktu siedzenia (a także od wieku i doświadczenia). Dlatego wcale nie twierdzę, że moje podejście jest jedynie słuszne. Myślę jednak, że ma pewną dużą zaletę - tworzy portfolio dla przyszłego pracodawcy. Pracodawcę interesuje podobno przede wszystkim "co umiesz", a zaraz potem "co możesz pakazać". Myślę, że w tym kontekście małe, ale ukończone i przydatne kawałki oprogramowania mają większą wartość, niż duże, ale tylko rozpoczęte gry.
Comments | #software engineering Share
# Game Developers Conference 2008
Sun
17
Feb 2008
Jutro w San Francisco rozpoczyna się konferencja GDC 2008. Myślę, że warto śledzić wieści na temat tej największej konferencji z branży. W planie jest ogromna ilość różnorodnych prezentacji - godzinnych wykładów lub całodniowych tutoriali - a także różne imprezy i inne wydarzenia (zobaczcie choćby opis "Destroy All Developers" :) Prezentacji ani nagrań ze wszystkich tych wydarzeń nie udostępnią pewnie za darmo w Internecie, ale trzeba wypatrywać publikacji wybranych materiałów. Jakieś na pewno się pojawią, jako że na Google można znaleźć niejeden PDF z poprzednich edycji GDC.
# Optymalizacja rulez
Fri
15
Feb 2008
Optymalizację można różnie rozumieć. Może znaczyć nietworzenie wielu obiektów tymczasowych, nieużywanie wielu alokacji pamięci i inne takie podstawowe rzeczy (o których każdy wiedzieć powinien). Może znaczyć używanie takich algorytmów i struktur danych, które zapewnią najlepszą złożoność obliczeniową (to już wymaga więcej myślenia, ale jest bardzo ważne). Może oznaczać przepisanie newralgicznych pętli do asemblera (jeśli ktoś zna ten język). Abstrahując od tego wszystkiego, do celów programowania gier można ułożyć takie zasady optymalizacji:
Poza tym często trzeba znaleźć kompromis typu czas-pamięć. W programowaniu gier jest to o tyle proste, że czasu zawsze jest za mało, a pamięci niekoniecznie - gra ma prawo zająć kilkadziesiąt czy nawet kilkaset MB.
Korzystając z tych zasad zwiększyłem właśnie dwukrotnie liczbę FPS-ów w swoim kodzie :D W stwierdzeniu który fragment wymaga optymalizacji pomógł mi profiler - AMD CodeAnalyst.
# Best Freeware Arcade Games 2007
Wed
06
Feb 2008
Zachęcam do przejrzenia Best Freeware Arcade Games 2007. To lista 20 małych, darmowych gier typu Indie. Wiele z nich jest 2D, stylizowane na stare dobre gry z czasów DOS-a (niska rozdzielczość, pikseloza i te sprawy), a niektóre są na podobnym poziomie jak przeciętne prace z naszego konkursu Compo.
Jednak niektóre są bardzo fajne. Polecam zwłaszcza dwie: Swarm Racer (nr 11), w którym gracz steruje całą chmarą latających owadów i szczególnie Empyreal Nocturne (nr 20), w którym gracz lata w pełnym trójwymiarze stadem ośmiościanów i atakuje przeguby jakieś dziwnej poruszającej się konstrukcji. Ta ostatnia gra jest naprawdę niezwykła, bardzo oryginalna i robi niesamowite wrażenie. Przypomina Darwinię. Opanowanie jej obsługi zajęło mi trochę czasu, ale warto było :)
# Wydajność wczytywania tekstur w Direct3D 9
Mon
04
Feb 2008
Wydajność wczytywania tekstur w Direct3D 9 - Eksperyment - to mój nowy artykuł. Zapraszam do przeglądania. Powstał w wyniku prostego eksperymentu, jaki przeprowadziłem, żeby zbadać wydajność wczytywania tekstur przez Direct3D 9 z różnych formatów graficznych.
To część większego tematu, którym ostatnio się zainteresowałem - problemu wydajności wczytywania gry. Temat ten jest powiązany także ze stosowaniem kompresji w VFS, odpowiednią metodą realizowania wejścia-wyjścia (zobacz np. [To]), przygotowaniem wszelkich danych od razu w formacie docelowym (aby nie trzeba było niczego konwertować ani parsować podczas ładowania), czy nawet bezpośrednią serializacją danych binarnych do pamięci, łącznie z siecią obiektów powiązanych wskaźnkami (zobacz np. [To] i [To] albo cokolwiek na temat serializacji).
Zadałem też pytanie na forum.gamedev.pl, a cennych odpowiedzi udzielili mi m.in. ludzie z firmy CD Projekt :D
Comments | #productions #directx #rendering Share
# Koszmar DrawIndexedPrimitive
Sat
02
Feb 2008
Dzisiaj postanowiłem zwrócić waszą uwagę na pewną sprawę w interfejsie DirectX, która dla zaawansowanych jest oczywista, a początkującym może sprawić nie lada problem. Mnie długo zajęło zrozumienie, co dokładnie oznaczają parametry liczbowe funkcji:
HRESULT SetStreamSource( UINT StreamNumber, IDirect3DVertexBuffer9 * pStreamData, UINT OffsetInBytes, UINT Stride ); HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount );
Warto zgłębić ten temat, by uniknąć potem wrednych błędów (na czele z klasycznym "Nic nie widać" :) Pisząc w największym skrócie:
Comments | #directx #rendering Share
# Zespół Aspergera
Thu
31
Jan 2008
Ktoś przyniósł ostatnio na kanał #warsztat link do hasła Wikipedii omawiającego Zespół Aspergera. To rodzaj autyzmu, który charakteryzują przede wszystkim:
Czyżby nauka odkryła i nazwała to, co komputerowcy mają na myśli mówiąc, że ktoś jest nerdem? Ten pomysł nie jest nowy. Mówi o tym choćby intrygujący artykuł na portalu Wired - The Geek Syndrome. W Sieci można też znaleźć wiele notek blogowych na ten temat. O cierpienie na ten zespół podejrzewa się m.in. Isaaca Newtona, Alberta Eisteina, a nawet... Richarda Stallmana i Billa Gatesa!
Nie ma chyba sensu diagnozować się w tym kierunku - w końcu to i tak jest nieuleczalne. Z resztą kto z nas chciałby wyleczyć się z programowania? Jeśli jednak, to można spróbować metod ludowych - jeden z nas stwierdził na kanale, że lekarstwem jest etanol :)
Comments | #humor #psychiatry Share
# Metoda szablonowa zamiast rzutowania
Tue
29
Jan 2008
Wpadłem ostatnio na pomysł, żeby się z wami podzielić drobnym rozwiązaniem, które wymyśliłem i które stosuję od dawna w swoim kodzie. Jako przykład weźmy manager zasobów. U mnie jest jeden ogólny, a każda klasa zasobu dziedziczy ze wspólnej klasy bazowej IResource. Są więc klasy pochodne takie jak D3dTexture czy FmodSound. Zasobów używam przez wskaźnik, ale ponieważ ich lista jest zapisana w pliku tekstowym, trzeba taki wskaźnik najpierw pobrać na podstawie nazwy. Trzeba przy tym zrzutować otrzymany zasób w dół na określony typ pochodny. Można to zrobić tak:
res::D3dTexture *Tex = (res::D3dTexture*)res::g_Manager->MustGetResource(L"Potwór01"); Tex->Cośtam();
lub bezpieczniej ze względu na typ:
res::D3dTexture *Tex = dynamic_cast<res::D3dTexture*>(res::g_Manager->GetResource(L"Potwór01")); if (Tex == NULL) throw Error(...); Tex->Cośtam();
Mój pomysł polega na napisaniu metody szablonowej, która ukryje rzutowanie:
template <typename T>
T * MustGetResourceExf(const wstring &Name)
{
return static_cast<T*>(MustGetResource(Name));
}
I jej wersji wolniejszej ale bezpieczniejszej:
template <typename T>
T * MustGetResourceEx(const wstring &Name)
{
IResource *R = MustGetResource(Name);
if (typeid(*R) != typeid(T)) throw Error(...);
return static_cast*lt;T*>(R);
}
Używa się ich tak:
res::D3dTexture *Tex = res::g_Manager->MustGetResourceEx<res::D3dTexture>(L"Potwór01"); Tex->Cośtam();
Prawda, że bardziej eleganckie? :) Gdyby ktoś pytał, przedrostek "Must" oznacza u mnie, że w przypadku nieznalezienia zasobu o podanej nazwie rzucony zostaje wyjątek, w przeciwieństwie do metod bez niego, które w takim przypadu zwracają NULL.