Warsztat FAQ

From Wiki

Spis treści

Wstęp

Kto to jest lamer? Co to jest lamerstwo?

Lamer to ktoś niemile widziany. Lamerstwo to zachowanie kogoś takiego.

Mianem lamera (jest to określenie bardzo negatywne) określa się zazwyczaj początkujących, których zachowanie łamie powszechnie przyjęte zasady i jest źle odbierane, denerwuje i wzbudza sprzeciw. Oczywiście nie każdy początkujący jest lamerem (zresztą nie każdy lamer jest początkującym). Lepiej mówić o lamerskim zachowaniu, które komuś może się przydarzyć. Lamerskie może być na przykład pytanie albo wypowiedź na forum. Należy starać się unikać zachowań, które mogą być odebrane jako lamerskie.

Skoro czytasz to FAQ, to najprawdopodobniej nie jesteś lamerem i jesteś na dobrej drodze, żeby nie zachowywać się jak lamer. Lamerzy nie czytają FAQ, regulaminów, dokumentacji, nie używają wyszukiwania ani nie korzystają z Google i innych źródeł.

Jak nie lamić?

Przeczytaj: Jak nie lamić.

Kilka innych zaleceń, które mogą być pomocne:

  • Znać zasady zachowania się w Sieci, czyli netykietę. Wykazywać pokorę i zrozumienie dla tych zasad. Nie buntować się przeciwko tym zasadom.
  • Zrozumieć znaczenie korzystania z dokumentacji (MSDN, Linux man, dokumentacja do danej biblioteki) oraz wyszukiwania rozwiązań problemów na Google. Nauczyć się z nich korzystać. Nie bać się ich.
  • Wykazywać własną inicjatywę, aktywność, kreatywność i samodzielność w myśleniu i rozwiązywaniu problemów, pokonywaniu przeszkód, znajdowaniu informacji i rozwiązań.
  • Pisząc swoje wypowiedzi w Internecie dbać o poprawność ortograficzną, gramatyczną, a przede wszystkim o dobre sformułowanie pytania.

Zobacz też: http://www.gamedev.net/community/forums/showfaq.asp?forum_id=31#FAQ-getstarted

Dlaczego zaawansowani nie lubią początkujących?

To nieprawda - to nie jest takie proste i ma swoje przyczyny.

Po pierwsze, zaawansowani nie lubią lamerów, a nie wszystkich początkujących. Ktoś kto mało umie, ale chętnie sie uczy i zachowuje się jak należy jest mile widziany. Nawet więcej - komuś takiemu chętnie się pomaga, bo wiele osób ma w sobie "instynkt dydaktyczny".

Pewna dająca się zaobserwować niechęć do początkujących wynika z kilku rzeczy. Początkujących jest zawsze więcej niż zaawansowanych. Toteż na każdego zaawansowanego przypada wielu początkujących, którzy zadają mu liczne pytania, a te - jak na jego poziom - są często bardzo elementarne, a więc nieciekawe. Ciebie jako kogoś zaawansowanego w obsłudze komputera też pewnie nudzą albo denerwują liczne pytania znajomych, którzy nie radzą sobie z obsługą Worda albo instalacją Windowsa.

Poza tym moderatorzy i inni bywalcy forum starają się dbać o jego poziom, zarówno w formie jak i treści wypowiedzi, oraz o zgodność z tematyką i dlatego walczą z wypowiedziami, które mogłyby temu zagrozić.

Mam świetny pomysł na grę!

To super, my też, ale niestety musisz wstrzymać swój zapał.

Po pierwsze, napisanie nawet bardzo prostej gry to kupa roboty. Takie gry jakie można kupić w sklepach kosztują zespół kilkudziesięciu ludzi nawet kilka lat pracy. Dlatego niestety nie jesteś jeszcze w stanie napisać swojej wymarzonej gry. Ale nie zniechęcaj się - programowanie gier i tak jest fajne. Ucz się, a potem będziesz mógł napisać super-hiper-wypasioną grę typu Pong albo Snake :)

Po drugie, niestety nikogo nie interesuje twój pomysł. Można podyskutować o samym pomyśle na grę (choć zwykle kończy się to stwierdzeniem "taka gra już była"), ale pomysłów każdy z nas ma cała masę, toteż nie mają one żadnej wartości.

Po trzecie, doświadczenie pokazuje że większości projektów się nie kończy. To nic, i tak można się przy ich pisaniu świetnie bawić i dużo nauczyć. Z projektów zespołowych niestety jeszcze częściej nie wychodzi nic dobrego. Wspólne pisanie wymaga dobrej organizacji pracy i jest dużo trudniejsze, niż pisanie własnego projektu.

Czy muszę umieć angielski?

Niestety tak.

Na początku Twojej przygody z programowaniem obejdzie się bez znajomości angielskiego. Możesz uczyć się z książek oraz z materiałów, które znajdziesz w polskim Internecie.

Pamiętaj również, iż proszenie o linki do kursów "koniecznie po polsku" jest uznawane ze objaw lamerstwa (patrz: Jak nie lamic)

Niestety na dłuższą metę przekonasz się, że znajomość angielskiego w przynajmniej podstawowym zakresie jest niezbędna. Nikt nie tłumaczy interfejsu środowisk programistycznych ani też dokumentacji do różnych bibliotek, z których prędzej czy później musisz zacząć korzystać. Ponadto na właściwie każdy temat w języku angielskim znajdziesz w Sieci wielokrotnie więcej informacji, niż po polsku. Na wiele tematów zaawansowanych dostępne są teksty wyłącznie po angielsku.

Co można zrobić?

  • Nie zaniedbywać lekcji angielskiego w szkole.
  • Zainstalować komputerowy słownik angielsko-polski i polsko-angielski i mimo wszystko próbować czytać teksty i dokumentacje techniczne po angielsku.
  • Zapisać się na dodatkowy kurs angielskiego.

Od czego zacząć?

Najpopularniejsza ścieżka to nauka języka C++, a potem jakiejś biblioteki graficznej.

Jeżeli chcesz programować gry, to najpierw musisz oczywiście nauczyć się programowania. Decyzja co do szczegółów należy do ciebie. Może chcesz pisać gry na komórki lub inne platformy albo gry przez WWW? Wtedy technologia będzie inna. Jeśli jednak interesuje cię, jak większość z nas, pisanie zwykłych gier na peceta, najlepszym wyborem będzie opanowanie języka C++. Potem naucz się używać jakiejś biblioteki graficznej 2D lub 3D (np. Allegro, SDL, DirectX, OpenGL).

Zobacz też:

Programowanie

Jakiego języka programowania się uczyć?

To zależy co chcesz, pisać, ale najczęściej wybierany jest C++.

Dawniej ludzie na Warsztacie pisali swoje gry w różnych językach - Delphi, C++, Visual Basic itd. Obecnie króluje C++ - język niełatwy, ale najważniejszy i używany jako podstawowy przez profesjonalistów z tej branży. Również większość kursów i artykułów na sieci opisanych jest C++em. Historia, aczkolwiek, powoli zatacza koło i w zależności od tego co chcesz pisać lepszym wyborem mogą być inne języki.

  • Popularność zdobywa platforma .NET na czele z językiem C#. Choć kod takich programów działa wolniej, pisze się go dużo wygodniej. Zobacz też: Kod natywny vs .NET. Oparta na .NET platforma XNA pozwala pisać gry przenośne między Windows i Xbox 360.
  • Gry na komórki pisze się w języku Java.
  • Aby pisać gry przez WWW, można używać np. HTML, CSS, JavaScript, XML, AJAX, PHP, Java.
  • Jeśli chcesz pisać kod przenośny na Windows i Linux, najczęstszym wyborem jest C++.

Mimo tego najpopularniejszy pozostaje obecnie język C++ jako podstawowy do pisania normalnych gier na peceta dla Windows lub Linux. Ucząc się go nie zapomnij, po opanowaniu podstaw, zapoznać się także ze wskaźnikami, programowaniem obiektowym (klasy itd.) oraz z biblioteką standardową (kontenery STL itd.).

Jaki kompilator wybrać?

Do wyboru są różne. Najpopularniejszy jest Visual C++.

Jeśli używasz języka C++, do wyboru masz wiele kompilatorów i środowisk programistycznych (jedno może być związane z drugim, ale nie musi). Zdaniem wielu, w systemie Windows najlepszym wyborem jest w obecnej chwili Microsoft Visual C++ Express 2008 - jest darmowy, wygodny, posiada dobry kompilator, a jego licencja pozwala nawet na pisanie programów komercyjnych.

Jeżeli chodzi o alternatywy, popularnością cieszą się środowiska takie jak Eclipse (z wtyczką C++), Code::Blocks, Netbeans (z wtyczką C++), CodeLite. DevC++, dość popularny wśród początkujących, nie jest rozwijany od pięciu lat i nie powinien być używany, dodatkowo dostarczany jest z starą wersją kompilatora GCC, co robi problemy przy próbie kompilacji bardziej skomplikowanego programu.

Listę popularnych środowisk do C++ znajdziesz tutaj: CPP vs Pascal.

Co to jest projekt i opcje projektu?

Żeby cokolwiek skompilować w Visual C++, trzeba stworzyć projekt. Żeby zwalczyć wiele problemów z kompilacją, trzeba umieć zmieniać opcje projektu.

W środowisku Visual C++, inaczej niż np. kompilując program w Linuksie z konsoli poleceniem g++, nie można tak po prostu skompilować pliku CPP - trzeba stworzyć projekt. Tworzy się go poleceniem File > New > Project.

Podczas tworzenia projektu do wyboru są cztery rodzaje (można to później zmieniać w opcjach projektu):

  • Console Application - program EXE konsolowy. Powinien mieć funkcję main.
  • Windows Application - program EXE okienkowy. Nie będzie miał domyślnie konsoli. Powinien mieć funkcję WinMain.
  • Static Library - wynikiem nie będzie program EXE, ale biblioteka dołączana statycznie, czyli plik LIB
  • DLL - wynikiem nie będzie program EXE, ale biblioteka dołączana dynamicznie, czyli plik DLL

Opcje projektu to bardzo ważne miejsce w Visual C++, ponieważ tam ustawia się wiele parametrów i w ten sposób rozwiązuje się wiele problemów, które często nękają początkujących. Opcje projektu znajdziesz:

  • W menu Project > NAZWA Properties...
  • Klikając prawym klawiszem na projekcie w Solution Explorer i wybierając polecenie menu Properties
  • Wciskając Alt+F7

Niektóre opcje często przestawia się zaraz po utworzeniu projektu:

  • General > Character Set - rodzaj używanych znaków. Zmień na Not Set, jeśli nie używasz Unikodu.
  • C/C++ > Code Generation > Runtime Library - w konfiguracji Debug zmień z "Multi-threaded Debug DLL" na "Multi-threaded Debug", a w konfiguracji Release zmień z "Multi-threaded DLL" na "Multi-threaded", jeśli nie chcesz, aby skompilowany program wymagał dodatkowych bibliotek MSVCR80.DLL i MSVCP80.DLL (w konfiguracji Release - MSVCR80D.DLL i MSVCP80D.DLL), których użytkownicy zwykle nie mają w swoim systemie. Niestety wówczas wzrasta rozmiar tworzonego pliku EXE.

Niektóre inne ważniejsze opcje to:

  • General > Output Directory - katalog, do którego trafi skompilowany plik EXE i niektóre inne towarzyszące mu pliki.
  • General > Configuration Type oraz Linker > System > SubSystem - rodzaj projektu, czyli aplikacja konsolowa, okienkowa, biblioteka statyczna LIB lub biblioteka dynamiczna DLL.
  • C/C++ > Preprocessor > Preprocessor Definitions - makra preprocesora, które mają być zdefiniowane we wszystkich plikach projektu.
  • C/C++ > Precompiled Headers > Create/Use Precompiled Header - przestaw na "Not Using Precompiled Headers", jeśli podczas tworzenia projektu omyłkowo pozostawiłeś zaznaczone użycie mechanizmu Precompiled Headers, a nie chcesz go używać i otrzymujesz błąd na temat pliku StdAfx.h.
  • Linker > Input > Additional Dependencies - tutaj dopisz pliki LIB, z którymi chcesz zlinkować swój program. To zazwyczaj rozwiązuje problemy z błędem "Unresolved External Symbol".

Jeśli program nie kompiluje się w konfiguracji Release, a kompiluje się w Debug, winne są zapewne opcje projektu, które przestawiłeś tylko dla tej drugiej konfiguracji. W oknie opcji projektu po lewej stronie na górze masz wybór, dla której konfiguracji (albo dla obydwu) oglądasz i przestawiasz opcje - zawsze o tym pamiętaj.

Jak zainstalować Visual C++ Express 2005?

Potrzebujesz jeszcze ściągnąć, zainstalować i skonfigurować Platform SDK.

Więcej informacji na temat rozpoczynania przygody ze środowiskiem Visual C++ Express 2005 znajdziesz tu:

Błąd Unresolved External Symbol

To bardzo częsty i bardzo prosty błąd, najczęściej spowodowany brakiem odpowiednich bibliotek (nie dołączone .lib). Rozwiązanie dla Visual C++: Unresolved External Symbol.

Jeśli używasz kompilatora GCC z wiersza poleceń, linkowanie z bibliotekami polega na dopisaniu opcji takiej jak -lopengl32, -lglu32 itd., ogólnie -lNAZWA.

Błąd konwersji łańcucha znaków

Kolejny, również częsty błąd użytkowników środowiska Visual Studio to problem związany z konwersją łańcucha znaków const char* do LPCWSTR, który objawia się następującym komunikatem:

cannot convert parameter 1 from 'const char *' to 'LPCWSTR'

Pojawia się on głównie podczas korzystania z funkcji WinAPI lub DirectX, a to dlatego, że zawarte w nich funkcje przyjmujące łańcuch znaków zdefiniowane są podwójnie i na końcu nazwy mają literkę A lub W. Dla użytkownika jest to niewidoczne dzięki zdefiniowaniu odpowiednich aliasów na podstawie tego czy używany Character Set to Unicode czy Multi-Byte. Na temat łańcuchów znaków możesz poczytać tutaj: http://wiki.gamedev.pl/Łańcuchy_w_CPP.

Aby rozwiązać ten problem wystarczy w opcjach projektu w sekcji General > Character Set ustawić Multi-Byte zamiast Unicode. Drugim ale rozsądniejszym rozwiązaniem będzie używanie już zdefiniowanego makra TEXT, które doda przed każdym łańcuchem L wtedy, gdy korzystasz z rozszerzonego kodowania (Unicode).

Mój program wymaga jakiegoś pliku DLL, którego ludzie nie mają

Zobacz jaki to plik.

Jeśli D3DX9_##.DLL (zamiast ## jest jakiś numer), to wynika z używania rozszerzenia D3DX w Direct3D, a numer jest związany z wersją używanego DirectX SDK. Nic na to nie poradzisz - poinformuj swoich użytkowników o konieczności pobrania tego pliku. Zobacz też to: http://regedit.gamedev.pl/wymagania.php5#d3dx9_XX.dll .

Jeśli MSVCR80.DLL, MSVCP80.DLL lub coś podobnego, rozwiązaniem jest zmiana opcji projektu. Wejdź do opcji projektu i w C/C++ > Code Generation > Runtime Library: w konfiguracji Debug zmień z "Multi-threaded Debug DLL" na "Multi-threaded Debug", a w konfiguracji Release zmień z "Multi-threaded DLL" na "Multi-threaded".

Jeśli MSVCR80D.DLL, MSVCP80D.DLL, to znaczy że dajesz ludziom wersję swojego programu skompilowaną w konfiguracji Debug. Powinieneś przestawić na Release i taką wersję udostępniać innym (patrz Co to jest konfiguracja Debug i Release?).

Mój program nie działa u kolegi

Najprostszym rozwiązaniem jest zmiana trybu kompilacji z Multithreaded DLL na Multithreaded. Aby tego dokonać należy wejść w Opcje projektu -> C/C++ -> Code Generation -> Runtime library. Dla wersji Release należy ustawić Multi-threaded (/MT), a dla Debug Multi-threaded Debug (/MTd). Wówczas skompilowany program nie będzie wymagał do działania bibliotek typu MSVCP90.DLL.

Jeżeli jednak z jakiś przyczyn wymagana jest kompilacja w trybie Multithreaded DLL to program nie działa, gdyż prawdopodobnie kolega nie ma zainstalowanego pakietu redystrybucyjnego Microsoft Visual C++ 2005 Redistributable Package który jest wymagany do działania aplikacji na komputerach bez środowiska Visual C++ 2005 EE.

Więcej na ten temat znajduje się w artykule Dystrybucja aplikacji napisanych w Visual CPP 2005 EE.

Co to znaczy Precompiled Headers?

To mechanizm pozwalający na znaczne przyspieszenie kompilacji. Jeśli go nie używasz, musisz mieć go wyłączonego aby uniknąć błędów.

Jeśli nie chcesz używać Precompiled Headers, a pojawiają się błędy kompilacji z tym związane albo mówiące o pliku StdAfx.h, wejdź do opcji projektu i w C/C++ > Precompiled Headers opcję Create/Use Precompiled Header przestaw na "Not Using Precompiled Headers".

Jeśli chcesz zacząć używać Precompiled Headers, poczytać coś na ten temat, na przykład http://regedit.gamedev.pl/produkcje/artykuly/PrecompiledHeaders.php5 . Warto to opanować, bo jest proste i przyspiesza kompilację dużych projektów wielokrotnie.

Co to jest konfiguracja Debug i Release?

To sposób kompilacji w Visual C++. Powinieneś wiedzieć o tym i używać tego.

W środowisku Visual C++ możesz skompilować program w konfiguracji Debug lub Release. Aktualnie wybraną konfigurację możesz zmieniać przez pole wyboru, które znajdziesz na pasku narzędzi u góry. Inne związane z tym polecenia to Build > Batch Build i Build > Configuration Manager.

  • Debug
    • Kompilacja jest szybsza
    • Kompilator nie dokonuje zaawansowanych optymalizacji
    • Dodany zostaje specjalny kod sprawdzający np. do iteratorów STL
    • Zmienne są inicjalizowane specjalnymi wartościami np. 0xCDCDCDCD
    • Program wynikowy jest większy
    • Program wynikowy działa wolniej
    • Stosuj podczas pisania programu
  • Release
    • Kompilacja jest wolniejsza
    • Kompilator dokonuje optymalizacji
    • Program wynikowy jest mniejszy
    • Program wynikowy działa szybciej
    • Stosuj do ostatecznej kompilacji programu przed jego opublikowaniem

Wyniki kompilacji (pliki EXE) w wersji Debug i Release znajdziesz w osobnych podkatalogach projektu.

Programy w wersji Release wbrew pozorom też można debugować w Visual C++, choć ze względu na stosowane przez kompilator optymalizacje debugger zachowuje się wtedy czasami dziwnie.

Jeśli program nie kompiluje się w konfiguracji Release, a kompiluje się w Debug, winne są zapewne opcje projektu, które przestawiłeś tylko dla tej drugiej konfiguracji. W oknie opcji projektu po lewej stronie na górze masz wybór, dla której konfiguracji (albo dla obydwu) oglądasz i przestawiasz opcje - zawsze o tym pamiętaj.

Jeśli program skompilowany w Debug działa dobrze, a w wersji Release działa źle lub wysypuje się, winny jest zazwyczaj drobny błąd w kodzie taki jak niezainicjalizowana zmienna. Program w wersji Debug sam wypełnia tworzone zmienne wartościami pomagającymi w zidentyfikowaniu takich błędów, na przykład 0xCDCDCDCD. W wersji Release w takiej zmiennej znajdują się przypadkowe śmieci, czasami zera.

W czym pisać interfejs programów okienkowych

Do wyboru jest wiele różnych bibliotek, niektóre ściśle związane z używanym językiem programowania.

Jeśli piszesz grę, wystarczy stworzyć puste okno i zainicjalizować w nim DirectX czy OpenGL. To nie jest trudne. Jeśli jednak piszesz edytor albo inną aplikację okienkową, musisz użyć jednej z dostępnych bibliotek do GUI, pozwalającej wygodnie tworzyć okna, przyciski i inne kontrolki.

  • Windows API (inaczej WinAPI, Win32API) - natywne API systemowe. Jest bardzo niewygodne w użyciu. Obecnie większość osób twierdzi, że nie warto męczyć się pisząc GUI z jego użyciem.
  • MFC (Microsoft Foundation Class Library) - stara biblioteka dostępna dla posiadaczy środowiska Visual C++ w wersji Professional lub lepszej. Jest również przez wielu krytykowane za niewygodę.
  • wxWidgets - wieloplatformowa biblioteka do GUI dla C++.
  • Qt, GTK - biblioteki do GUI przeznaczone natywnie dla Linuksa, ale można z nich korzystać także w Windows.

Jeśli jesteś gotów zmienić język programowania i środowisko specjalnie w tym celu, możesz też zainteresować się:

  • Windows Forms - odpowiedzialna za GUI część platformy .NET (język C# i inne)
  • VCL - biblioteka komponentów wchodząca w skład środowiska Delphi i Borland C++ Builder
  • AWT i Swing - biblioteki do GUI wchodzące w skład platformy Java

Jak zrobić w C++ wskaźnik do metody w klasie?

W C++ niestety brakuje tego mechanizmu, ale są do tego biblioteki.

Wskaźniki do metod, a konkretnie wskaźniki do dowolnej metody o zgodnym nagłówku w konkretnym obiekcie dowolnej klasy, nazywane też funkcjami zwrotnymi (ang. callback) delegatami (ang. delegate), zdarzeniami (ang. event), sygnałami i slotami, to mechanizm bardzo przydatny m.in. podczas pisania kontrolek interfejsu użytkownika (do reagowania na zdarzenia takie jak wciśnięcie przycisku). Tymczasem w przeciwieństwie do Delphi, C# i innych nowoczesnych środowisk i języków w języku C++ brakuje tego mechanizmu. Dostępne w C++ wskaźniki do metod w niczym nie przypominają tych i nie są zbyt często przydatne.

Powstało kilka bibliotek służących do realizacji tego mechanizmu w C++, spośród których warto wymienić:

Poza tym implementacja takich wskaźników jest nieodłączną częścią bibliotek do GUI dla C++, jak wxWidgets, Qt, MFC. Jeśli czujesz się na siłach, możesz też bazując na powyższych oraz na własnych pomysłach spróbować napisać taką bibliotekę samemu. Trzeba jedynie pamiętać za każdym razem dwie rzeczy - wskaźnik na konkretny obiekt i offset do konkretnej metody - oraz zastosować odpowiednie rzutowania.

Jak używać łańcuchów znaków w C++?

Dostępne są dwie główne opcje - znane z C łańcuchy typu char* oraz nowe, wygodniejsze łańcuchy typu std::string z biblioteki standardowej C++.

Więcej o tym: Łańcuchy w C++.

Częstym problemem jest konwersja między łańcuchem znaków a liczbą. Konwersja taka, w przeciwieństwie do na przykład PHP i wielu innych języków skryptowych, nie dokonuje się automatycznie. Informacje o tym jak to zrobić: Konwersja między liczbą a łańcuchem.

Jak wczytywać i zapisywać pliki?

Musisz użyć odpowiednich funkcji.

Istnieje kilka zestawów funkcji do tego celu. Więcej o tym: Obsługa plików.

Częstym problemem jest potrzeba przechowywania w plikach danych zapisanych w postaci tekstowej. Aby obsługiwać takie pliki, możesz:

  • Jeśli to prosty format z następującymi kolejno po sobie liczbami i łańcuchami bez spacji, użyj strumieni std::ifstream i std::ofstream z biblioteki standardowej C++.
  • Jeśli chcesz użyć języka XML czy innego gotowego, znajdź i użyj biblioteki z parserem tego języka.
  • Jeśli chcesz wymyślić własną składnię języka opisu, sam musisz napisać program do wczytywania danych w tym języku, czyli tzw. parser (nie jest to łatwe).

Czy warto najpierw zaprojektować grę?

Tak.

Oczywiście bez przesady, bo poświęcając się tylko rozdmuchanemu projektowaniu twój projekt może upaść zanim jeszcze zaczniesz pisać kod. Żadne projektowanie nie pomoże, jeśli nie posiadasz wiedzy i doświadczenia potrzebnych do zrealizowania tego, co program ma robić. Jednak ogólnie zawsze warto przemyśleć i zaprojektować organizację swojego kodu, a wcześniej także stawiane wymagania, przyjęte założenia i oczekiwane funkcje.

Trzeba dwa razy pomyśleć, zanim zacznie się pisać, żeby nie trzeba było dwa razy pisać, zanim zacznie się myśleć.

Jeśli chcesz zgłębić ten temat, zainteresuj się rzeczami takimi jak:

  • Inżynieria oprogramowania - to dziedzina zajmująca się organizowaniem produkcji oprogramowania
  • Extreme Programming, Agile Development - to niektóre z metodologii tworzenia oprogramowania
  • UML - to jedna z notacji pozwalających na graficzne projektowanie struktury programu, np. klas i powiązań między nimi

Programowanie gier

Czy warto stosować gotowy silnik?

To zależy. Użycie gotowego silnika jest często dobrym sposobem na zapoznanie się z podstawami programowania, a zwłaszcza zagadnień grafiki 3D. Poza tym szybkie ujrzenie efektów pracy może być motywujące.

Po nabyciu doświadczeniu dość szybko możesz jednak stwierdzić, że możliwości gotowego engine'u są za małe, albo uważasz go za zbyt niewygodny w użyciu, albo sądzisz że zaprojektowałbyś go lepiej, albo po prostu masz ochotę samemu zrobić to wszystko. W takim wypadku możesz wziąć się za pisanie własnego silnika.

Jeśli więc marzysz o napisaniu własnego silnika, pisz własny silnik. Jeśli zaś chcesz napisać grę na gotowym silniku, użyj gotowego silnika. Zobacz też: Silnik gotowy czy własny.

Który silnik wybrać?

Istnieje wiele gotowych silników, a wybór, którego dokonasz zależy już tylko od twoich własnych preferencji i ambicji. Do najważniejszych i najczęściej używanych należą :

Irrlicht – jest szybki, darmowy i prosty w nauce, ale często niestabilny – nie nadaje się do większych projektów

OGRE(ang. Object-Oriented Graphics Rendering Engine) – bardziej zaawansowany od Irrlichta, ale i trudniejszy w nauce. Jest darmowy i wykorzystywany do profesjonalnych produkcji. Ważne jest to, że OGRE jest wyłącznie silnikiem graficznym

Jeśli preferujesz Javę to możesz skorzystać z Java Monkey Engine

Lista silników:

Czy uczyć się programowania grafiki 2D czy 3D?

Ludzie różnie mówią.

Jedni twierdzą, że warto zaczynać naukę programowania gier od grafiki 2D, bo jest prostsza, a gry 2D mają swój urok i nadal są popularne. Inni przekonują, że można zaczynać naukę od razu od grafiki 3D i że w bibliotekach do grafiki 3D (DirectX, OpenGL) również można programować grafikę 2D.

W czym pisać gry 2D?

Istnieje wiele bibliotek do grafiki 2D, w tym:

  • Allegro - wieloplatformową biblioteka do programowania gier 2D.
  • SDL (Simple DirectMedia Layer) - choć używana bywa jako szkielet aplikacji 3D pisanych w OpenGL, jest też pełnowartościową, wieloplatformową biblioteką do programowania gier 2D.
  • DirectDraw - dwuwymiarowa część starych wersji DirectX-a. Większość osób twierdzi, że nie warto się jej uczyć i że jest przestarzała. Jednakże nadaje się do wyświetlania grafiki 2D i w niej powstaje wiele komercyjnych gier typu Casual.
  • Windows GDI czy też część graficzna innego API, którego używasz do napisania okienka i GUI. Jest zbyt wolne, by realizować a nim animację, ale do prostych gier turowych, logicznych itp. może wystarczyć.
  • Direct3D lub OpenGL - to są biblioteki do grafiki 3D, ale z powodzeniem można w nich też pisać gry 2D.

W czym pisać gry 3D?

Do wyboru są dwie biblioteki graficzne - DirectX i OpenGL. Nie można stwierdzić która jest lepsza.

Jedna i druga biblioteka ma swoich zagorzałych zwolenników oraz całe mnóstwo argumentów przemawiających na jej korzyść, a dyskusja o tym która z nich jest lepsza to właściwie niekończąca się wojna. Aby podjąć tą ważną decyzję, poczytaj na przykład:

Potężne FAQ na temat tych bibliotek znajdziesz tu:

Nic nie widać

Przyczyn może być cała masa i nikt inny jak tylko ty sam możesz znaleźć błąd.

Co najwyżej trochę pomóc może ten tekst: Nic nie widać.

Jak rysować półprzezroczyste obiekty?

Użyj alfa-testingu lub alfa-blendingu.

Niezależnie czy w DirectX czy w OpenGL, rysowanie obiektów mających obszary przezroczyste lub półprzezroczyste wiąże się z uaktywnieniem funkcji Alpha-Testing lub Alpha-Blending oraz dokonaniem odpowiednich ustawień. Przykładowo, zwyczajny alfa-blending to ustawienia: BlendOp=ADD, SrcBlend=SRCALPHA, DestBlend=INVSRCALPHA, zaś alfa-blending addytywny to: BlendOp=ADD, SrcBlend=SRCALPHA, DestBlend=ONE.

Istotna jest przy stosowaniu półprzezroczystości również kolejność rysowanych obiektów. Konieczne może być ich sortowanie w kolejności od najdalszych do najbliższych względem kamery. Trzeba też dobrze zaprojektować ogólny proces renderowania, żeby obiekty półprzezroczyste rysować na końcu mając na względzie, jak w ich przypadku zadziała Z-bufor. Poczytaj o tym więcej w swoim ulubionym tutorialu albo książce do OpenGL czy DirectX.

Temat ten był też wielokrotnie wałkowany na forum:

Jakiego edytora i formatu pliku używać do modeli 3D?

Jeśli zaczynasz swoją przygodę z czystym DirectXem, możesz zapoznać się z prostym formatem x, którego wczytanie, dzięki bibliotece D3DX, jest proste, a jednocześnie format zapewnia elastyczność i jest wygodny. Wiele kursów można znaleźć w internecie.

W OpenGL jest trochę więcej problemów. Musisz samemu wczytać model z pliku. Jednym z najprostszych formatów jest obj, ewentualnie troszkę bardziej skomplikowany jednak dający więcej możliwości md2. Na stronie [1] można znaleźć loadery dla modeli w formacie ms3d i lwo..

Jeżeli używasz gotowego silnika, problemu nie ma. Większość z nich obsługuje bardzo wiele formatów (md2, md3, md5, x, obj, 3ds, mdl...).

Zaawansowani często tworzą własne formaty modeli odpowiadające ich konkretnym potrzebom, zawierające te funkcje które chcą zaimplementować (np. animacja szkieletowa) i piszą własne wtyczki do eksportowania plików w tym formacie prosto z edytorów 3D.

Istnieje wiele programów graficznych. Niektóre z nich są darmowe, inne komercyjne i bardzo drogie. Do zaawansowanej edycji grafiki 2D (np. tekstur) najpopularniejsze są:

  • Paint .NET (darmowy)
  • GIMP (darmowy)
  • Adobe Photoshop
  • Paint Shop Pro

Do edycji modeli natomiast:

  • Milkshape 3D
  • Blender (darmowy)
  • 3D Studio MAX
  • Maya

Zobacz też: 3D & 2D Software Information

Co muszę umieć z matematyki?

Jak najwięcej :)

Na początku przygody z programowaniem gier wystarczą podstawy wyniesione ze szkoły, ale na dłuższą metę, zwłaszcza w grafice 3D, potrzebna jest znajomość bardziej zaawansowanych tematów, jak wektory, macierze czy kwaterniony.

Z czego się uczyć? Wstęp do geometrii potrzebnej w grafice 3D zawiera praktycznie każda książka do nauki OpenGL czy DirectX. Rozwiązania konkretnych problemów (jak np. kolizja trójkąt-trójkąt) znajdziesz w Internecie (właściwie tylko po angielsku) lub w bardziej zaawansowanej literaturze (np. książka Game Programming Gems - Perełki programowania gier).

Zobacz też: FAQ - Math and Physics

Co zrobić, żeby gra działała w stałym tempie?

Mnożyć prędkość razy czas, tak jak uczyli w szkole: Droga = Prędkość * Czas.

Przede wszystkim musisz wiedzieć, że wszelkie próby zmuszenia gry do pracy ze stałą, sztucznie ograniczoną liczbą klatek na sekundę to nie jest dobre wyjście. Zamiast tego należy zrobić tak:

Najpierw musisz wyposażyć się w jakąś funkcję do dokładnego pomiaru czasu. W Windows na początek możesz spróbować GetTickCount, ale dokładniejszy jest mechanizm QPC, czyli funkcje QueryPerformanceFrequency i QueryPerformanceCounter. W Linuksie dokładny czas zwraca funkcja gettimeofday.

Następnie musisz dopisać do swojego szkieletu gry pomiar czasu na początku każdej klatki i wyliczanie czasu, jaki minął od poprzedniej klatki w sekundach czy w milisekundach (nazwijmy go DeltaTime).

Wreszcie, podczas wszelkich obliczeń takich jak poruszanie się obiektów musisz uwzględnić ten czas jaki minął od poprzedniej klatki zmieniając pozycję obiektu według wzoru (w którym "Prędkość" to prędkość poruszania się obiektu w używanych jednostkach przestrzeni na sekundę czy milisekundę):

Pozycja = Pozycja + Prędkość * DeltaCzas

Jak obsługiwać klawiaturę, myszkę, joystick?

Do obsługi wejścia istnieje kilka bibliotek, których możesz użyć.

  • Jeśli piszesz w Allegro, SDL czy innej kompleksowej bibliotece do programowania gier, zapewne znajdziesz tam też funkcje przeznaczone do tego.
  • Jeśli wystarczy ci podstawowa obsługa klawiatury i myszy, użyj po prostu komunikatów otrzymywanych od systemu (np. komunikaty do okna w Windows API)
  • Jeśli chcesz mieć pełną i wyłączną kontrolę nad klawiaturą i muszką oraz obsługiwać wszelkiego rodzaju manipulatory, jak pady, joysticki i kierownice, użyj DirectInput (to część biblioteki DirectX).

Jak programować dźwięk?

Do odtwarzania muzyki i dźwięku istnieje wiele bibliotek.

  • DirectAudio wchodzący w skład DirectX.
  • OpenAL - darmowa, wieloplatformowa (dodatkowa bibliteka: ALUT)
  • FMOD - darmowa do zastosowań niekomercyjnych, odtwarza wiele formatów plików, bardzo potężna, wygodna, wieloplatformowa.
  • BASS - darmowa do zastosowań niekomercyjnych, odtwarza wiele formatów, wygodna, przenośna na Windows i MacOS.
  • Audiere - bardzo prosta w użyciu, darmowa.

Jak programować komunikację sieciową?

Musisz nauczyć się gniazd (ang. socket).

Interfejs gniazd jest standardem programowania sieciowego. Jego funkcje są bardzo podobne zarówno w Linux, jak i w Windows (gdzie ta część API systemowego nazywa się WinSock). Do nauki programowania sieciowego najczęściej polecanym materiałem jest dostępny online tutorial Beej's Guide to Network Programming. Polskie tłumaczenie - http://klepisko.eu.org/~bartek/bgnet/ - niestety od dłuższego czasu nie działa. Mirror polskiego tłumaczenia: http://regedit.gamedev.pl/Mirror/Beej_s%20Guide%20to%20Network%20Programming%20PL/

Znając gniazda, musisz zaprojektować własny protokół, według którego użytkownicy będą się komunikowali przez sieć. Musisz też tak napisać swoją aplikację, aby na czas wysyłania czy odbierania danych przez sieć nie zawieszała się. Możesz to zrobić używając gniazd asynchronicznych lub pisząc swój program wielowątkowo (co samo w sobie jest niełatwą, ale wartą poznania dziedziną). Generalnie pisanie gier sieciowych jest przynajmniej o oczko trudniejsze niż tworzenie gier działających tylko w trybie singleplayer.

Zobacz też: FAQ - Multiplayer and Network Programming.

Jak napisać grę na konsolę

Jeśli zadajesz to pytanie, to można być prawie pewnym, że Ty nie możesz. Programowanie konsol wymaga statusu oficjalnego dewelopera dla danej konsoli. Oznacza to, że jeśli chcesz stworzyć grą na PlayStation 3 i Xboksa 360, musisz mieć biznesowe relacje z Microsoftem i Sony. Obie firmy muszą upewnić się, że jesteś w stanie stworzyć produkt na wysokim poziomie, który pasuje do koncepcji firmy na temat portfolio platformy. W praktyce oznacza to, że albo znajdujesz się pod parasolem dużego wydawcy (Activision, EA, Ubisoft,...), albo masz gotowy produkt (nie pomysł - produkt) którym zainteresowany jest właściciel platformy (Nintendo, Microsoft, Sony).

Uzyskanie statusu oficjalnego dewelopera oznacza możliwość kupienia Development Kit (devkit), który jest niezbędny do pisania na daną platformę oprogramowania. Ceny devkitów są różne zależnie od platformy, ale dla konsol obecnej generacji (360, PS3) wahają się w okolicach kilku tysięcy dolarów (kilkunastu tysięcy złotych).

Należy także pamiętać, że programowanie konsol jest często dużo bardziej wymagające od programowania PC. Wymagana jest bardziej dogłębna wiedza z dziedziny programowania i architektury sprzętu, a co za tym idzie dużo więcej praktycznego doświadczenia niż w wypadku programowania na PC.

Istnieją alternatywy dla tego procesu, część z nich legalna, część nie. W przypadku Xboksa 360 możliwe jest pisanie gier przy użyciu XNA Game Studio - IDE opartego o Visual Studio i zestawu bibliotek dostępnych z poziomu kodu zarządzanego (C#). Gry pisane przy użyciu XNAGS mają odmienną od kodu w C czy C++ charakterystykę wydajności i wymagają stosunkowo odmiennego podejścia do kodu. Z poziomu XNA niemożliwe jest też wykorzystanie rozszerzeń SIMD procesora (VMX). Aplikacje napisane w XNAGS można także uruchamiać na PC oraz, z pewnymi ograniczeniami, na urządzeniach Windows Phone 7 oraz na Zune.

Inną legalną możliwością są studia na uczelni wyposażonej w devkity konsolowe.

Mniej legalną alternatywą jest tzw. homebrew. Homebrew to aplikacje pisane przy użyciu nielicencjonowanych narzędzi (kompilatorów i bibliotek), które mogą być uruchamiane na konsoli pod warunkiem sprzecznej z licencją modyfikacji sprzętu. W niektórych wypadkach błędy w oprogramowaniu producenta lub modelu bezpieczeństwa konsoli pozwalają na bezinwazyjne uruchomienie kodu, nie jest to jednak regułą. Homebrew jest stosunkowo popularne na konsolach przenośnych (PSP i DS) oraz konsolach poprzedniej generacji.

Z wiekiem konsole domowe czasem stają się bardziej otwarte. W 2009 roku Sony udostępniło szerszej grupie deweloperów dostęp do devkitów PS2 i umożliwiło im tworzenie oprogramowania poza klasycznym kanałem dystrybucji. Podobnie w przypadku PSX w 1997 Sony udostępniło specjalną wersję konsoli Net Yaroze (de facto dostępny dla każdego devkit), pozwalającą na pisanie własnego oprogramowania na tę platformę. Efekty pracy hobbystów były wydawane m.in. na krążkach dołączanych do Oficjalnego PlayStation Magazynu. Takie posunięcie ze strony właściciela platformy nie ma jednak nic wspólnego z homebrew i jest przykładem na stosunkowo jeszcze rzadką liberalizację podejścia do zamkniętych platform wraz z ich starzeniem się.

Wersja 1.1, 19 marca 2008
Autor: Adam Sawicki + koledzy z Warsztatu