článek

Udělej si vlastní hru – I. část

Udělej si vlastní hru – I. část

Vítám všechny zájemce u dalšího dílu našeho malého seriálu o tvorbě počítačové hry. Minule jsme si shrnuli základní vlastnosti, které bude náš finální výtvor mít, dnes se již pustíme do samotné implementace.

Okno hry



Naše hra, dejme ji název třeba BomberMario, poběží pod operačním systémem Windows. A jelikož poběží pod Windows, bude muset mít své vlastní okno - a to i když poběží v celoobrazovkovém režimu, protože operační systém bude s naší aplikací muset nějakým způsobem komunikovat. Způsob komunikace mezi aplikací a operačním systémem je samozřejmě nutné nějak standardizovat, a proto se zavádí tzv. událostmi řízené programování, které v minimální míře využijeme i my. V praxi celá věc probíhá asi tak, že po vytvoření okna aplikace jsou tomuto oknu operačním systémem zasílány zprávy obsahující informace např. o stisknutých klávesách, pohybech myši apod. Aplikace, která v daném okně běží pak zpravidla ve svém kódu obsahuje patřičné funkce, které se o zpracování těchto zpráv postarají (tedy např. pokud byla stisknuta klávesa Esc, tak se aplikace ukončí). V tomto dílu si tedy ukážeme základní způsob správy okna, vystačíme si s funkcemi pro samotné vytvoření okna a fukncí pro reagování na zprávy, které oknu přijdou. Těchto zpráv je poměrně velké množství a samozřejmě, že nemusíme psát ke každé z nich příslušnou akci, vybereme si jen ty zprávy, které jsou pro nás z nějakého důvodu důležité, ostatní necháme zpracovat defaultně (viz dále).



WinAPI



Jak jsem již uvedl minule, WinAPI je rozhraní poskytující mnoho užitečných funkcí pro práci s okny a jejich prvky v MS Windows. Celé WinAPI je poměrně dost rozsáhlé, není tedy v možnostech tohoto seriálu seznámit s ním čtenáře do hloubky. Řekneme si jen to minimum, které budeme pro Bomber Maria potřebovat. Pokud by Vás zajímalo WinAPI jako takové, je na internetu spousta článků a jiných tutorialů zaměřených pouze na tuto problematiku. Dost informací lze též získat přímo na stránkách Microsoftu pro vývojáře http://www.msdn.microsoft.com/
Pokud používáte C/C++, funkce WinAPI naleznete v hlavičkovém souboru windows.h, který je standardní součástí většiny IDE pro Windows.



Poznámka: Cesta, kterou volím v tomto případě je podle mně cestou nejmenšího zla, tedy takovou cestou, která nezdržuje zbytečným učením se něčeho, co s hrou jako takovou přímo nesouvisí, avšak je to zároveň nutné k jejímu zdárnému dokončení a funkčnosti. Pokud tedy již s WinAPI nějaké zkušenosti máte, příp. použijete k vytvoření a správě okna vlastní způsob (např MFC), pak tak klidně učiňte a tento díl můžete přeskočit, neboť se zde ještě nezmíním přímo o implementaci herních záležitostí.









Vytvoření okna



Prvním úkolem, který je před námi, je zajistit, aby vůbec aplikace měla jak běžet, tedy vytvořit její okno. K tomu využijeme funkce: RegistraceOkna a VytvoreniOkna, jejichž kód je následující:




void RegistraceOkna(HINSTANCE hInstance)

{

    WNDCLASSEX w;

    w.cbSize = sizeof(WNDCLASSEX);

    w.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

    w.lpfnWndProc = WinProc;

    w.cbClsExtra = 0;

    w.cbWndExtra = 0;

    w.hInstance = hInstance;

    w.hIcon = LoadIcon(NULL, IDI_APPLICATION);

    w.hCursor = (HCURSOR)LoadCursor(NULL, IDC_ARROW);

    w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

    w.lpszMenuName = NULL;

    w.lpszClassName = "Bomberman";

    w.hIconSm = NULL;

    RegisterClassEx(&w);

}





void VytvoreniOkna(HINSTANCE hInstance)

{

     hWindow = CreateWindowEx(

              NULL,

              "Bomberman",

              "Bomberman",

              WS_OVERLAPPEDWINDOW,

              150,

              150,

              800,

              600,

              GetDesktopWindow(),

              NULL,

              hInstance,

              NULL);

}



Obě funkce volají ve svém těle volají funkce další, které jsou součástí WinAPI. Tyto standartní funkce (konkrétně to jsou funkce RegisterClassEx a CreateWindowEx) přebírají poměrně dost paramterů, pojďme si k nim tedy něco říct. Funkce RegistraceOkna zaregistruje třídu našeho okna do Windows, přičemž pomocí struktury WNDCLASSEX se předávají některá nastavení okna jako barva pozadí (hbrBackground) apod. Zajímavá je proměnná (lpfnWndProc, která udává funkci, které budou zasílány výše zmíněné zprávy pro pracování. V našem případě jsme tuto funkci pojmenovali WinProc, musíme ji však ještě implementovat, např. takto:




LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

    switch(msg)

    {

         case WM_CREATE:

            return 0;



        case WM_DESTROY:

        {

            PostQuitMessage(0);

            return 0;

        }



        case WM_PAINT:

        {

            ValidateRect(hWindow,NULL);

            return 0;

        }



    }

  return DefWindowProc(hWnd, msg, wParam, lParam);

}




Funkce WinProc (mimo jiné) přebírá jako svůj parametr příchozí zprávu (msg) a pomocí příkazu switch se rozhoduje, jakou akci v závislosti na druhu zprávy provede (např. zpráva M_DESTROY znamená požadavek na zrušení okna, pak tedy aplikaci v daném okně ukončíme pomocí WinAPI funkce PostQuitMessage). V průběhu tvorby vznikne potřeba reagovat na další zprávy (stisknuté klávesy apod.) – to snadno učiníme rozšířením možností v příkazu switch.



Nyní se ještě podívejme na funkci VytvoreniOkna, která, věrná svému názvu, má na starosti skutečné stvoření našeho požadovaného okna - učiní tak na základě registrované třídy okna pomocí funkce RegistraceOkna. Uvnitř této funkce je důležitá proměnná hWindow (je globální, deklarovaná na začátku programu), tzv. manipulátor okna (datový typ HWND), který slouží operačnímu systému jako jakýsi ukazatel na dané okno, aby s ním mohl OS komunikovat. Vytvoření okna je zajištěno WinAPI funkcí CreateWindowEx, která jako své parametry přebírá další vlastnosti okna, jako jeho velikost, pozici levého horního rohu okna na obrazovce apod.



Nyní zbývá implementovat poslední potřebnou funkci, totiž funkci, která bude v nekonečném cyklu po celou dobu běhu aplikace zjišťovat, zda byla oknu poslána nějaká zpráva (pak ji nechá zpracovat). Pokud žádná zpráva zrovna nepřišla, pak budeme moci provádět naše vlastní akce, např. překreslení obrazovky, provedení příslušných herních propočtů apod. - to si ukážeme v dalších dílech. Funkci bychom mohli pojmenovat např. MsgCheck a vypadat může třeba takto:




WPARAM MsgCheck()

{

    MSG mes;

    while(1)

    {



        if(PeekMessage(&mes, NULL, 0, 0, PM_REMOVE))

        {



                if (mes.message == WM_QUIT) break;


                TranslateMessage(&mes);

                DispatchMessage(&mes);



        }

        else

        {

                //zde budeme kreslit, pocitat atd.

        }

    }

  return mes.wParam;

}




Jako úplně poslední krok dáme vše dohromady - napíšeme funkci WinMain, windowsovou obdobu klasické funkce main v DOSosvských programech. Ta bude vypadat následovně:





INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)

{

    RegistraceOkna(hInstance); //registrace tridy okna

    VytvoreniOkna(hInstance); //vytvoreni okna



    ShowWindow(hWindow, SW_SHOWDEFAULT); //zobrazeni okna

    UpdateWindow(hWindow);



    INT Result;

    Result = MsgCheck(); //smycka pro prijem zprav

    return Result;

}



Tak, to by bylo pro tento díl vše. Bohužel rozsah a hlavně téma tohoto seriálu mě donutilo zmínit se o WinAPI skutečně minimalisticky, tedy tak, aby čtenář pouze věděl "že to bude fungovat", avšak již jsme nemohl napsat "proč to bude fungovat". Na druhé straně je pravda, že k programování samotné hry tato znalost nezbytná není, pokud se však o WinAPI chcete dozvědět víc, než tento úplný základ, pak Vás odkazuji na mnoho jiných seriálů, které se tímto tématem zabývají podstatně hlouběji, pro popis konkrétních funkcí a datových struktur doporučuji dokumentaci, kterou lze nalézt na výše uvedené webové stránce Microsoftu. Doporučuji Vám podívat se na popis v tomto článku použitých funkcí a také na deklaraci struktury WNDCLASSEX.









Co bude příště?



Příště se pustíme do porgramování samotné hry - podíváme se na incializaci grafického rozhraní (opět jen tak letmo, neboť tento seriál si nečiní nárok být tutorialem pro DirectX) a načteme a vykreslíme herní mapu - bludiště (tomu se můžeme věnovat podrobněji, neboť to naopak cílem seriálu je :-)).



Úkoly pro vás? Podívejte se na dokumentaci k použitým funkcí z WinAPI, pokud se rozhodnete použít výše uvedený kód, pak si zkuste "pohrát" s nastavením okna - velikostí, barvou pozadí, přidejte reakce na nějaké další zprávy (viz dokumentaci), stylem zobrazení (opět najdete v dokumentaci)...



Budu se těšit na další pokračování!



Zdrojové kódy: 310_prvni_cast.zip






Související odkazy:









jan_kohout

autor
/ jan_kohout

Publikováno: 13.05.2007


další články této kategorie





diskuze

odeslat

Nejsi automat? Napiš výsledek 2 + 5 =

Filip | 02.06.09 v 17:46

Jsem začátečník a potřebaval bych trochu víc poradit jak vkládat zdrojové kódy.Takže mi prosím napište někdo na e-mail.
Děkuji moc za radu

hannah montana | 31.07.08 v 10:32

jak se vyrábí hra?

kkory | 31.05.08 v 12:24

nevite o neakem programu na tvoreni hry

artman | 31.05.07 v 21:50

hh :), no ona to je hláška zkušených programátorů z českých-her.cz, každopádně s ní souhlasím, protože někdy jak člověk maká na něčem větším, tak by neměl být zaskočen nějakým tím warningem (viz. můj nedávný projekt do školního předmětu operační sytémy - klient/server aplikace, build log jsem ale neměl čas pořádně prostudovat... :))

Esaras | 31.05.07 v 18:56

Osobně moc DEV-C++ nedoporučuju, je poněkud neinteligentní a přijde mi že programátorovi spíše práci přidělává než usnadňuje, proto doporučuju jak již autor článku psal Visual Studio Express Edition, v němž se pracuje pohodlně.
To Leonidas: to co si napsal nejsou chyby ale warningy (ja nevim jak ty, ja na warningy nehraju, me zajimaji jen errory) a na překlad nemají žádný vliv, pouze tě informují o jisté zkutečnosti že nekterá konstrukce nemusí být úplně vpořádku, ale to není ten důvod proč ti to nejde přeložit. Musí ti to hlásit ještě nejaký error, muz 3D engine mi taky hlásí asi 44 warningů a vpohodě jde spustit. Jinak oblíbená hláška artmana:"jestliže se snaží mít programátor čistý buildlog tak to zavání fetišismem" :D

Leonidas | 21.05.07 v 21:44

Používám Dev-C++ a ten mi při kompilaci zdrojového kódu hlásí chybu..
řádek 70
[Warning] passing NULL used for non-pointer argument passing 1 of `HWND__*

a

[Warning] argument to non-pointer type `long unsigned int' from NULL

Nějak tomu popisu nerozumím a ani programování v C++ nedělám dlouho...

Jan Kohout | 16.05.07 v 17:00

Ke všem dotazům ohledně WinAPI:
WinAPI jako takové se odnikud nestahuje, potřebné funkce naleznete v hlavičkovém souboru windows.h, který bývá standartní součástí snad všech IDE určených pro Windows, pokud takové vývojové prostředí nevlastníte, pak si jej stáhněte - existuje jich dost zdarma, třeba již zmíněné Visual Studio express nebo též doporučuji Dev-C++.

JAJA | 15.05.07 v 22:11

Odkial si mozem stiahnut WinAPI?pls

artman | 14.05.07 v 16:13

trochu jsme zaktualizovali článek..chcete-li stáhnout výše zmíněné zdrojové kódy, neměl by být problém..

Jinak jak už tu bylo řečeno, pro získání WinApi je nejjednodušší zakoupení nějakého pěkného IDE... Například již zmíněné Visual Studio či Builder C++ (lépe asi to první).. Microsoft navíc nabízí pro nekomerční použití jejich produktů Expres verze zdarma, takže myslím, že by to mělo být v pohodě...

ihornak | 14.05.07 v 15:59

Kup si Windows a nainstaluj si ho, potom si kup nejake IDE, napriklad Visual Studio a aj to si nainstaluj, potom budes mat WinAPI ... :)

Nekdo | 14.05.07 v 13:54

Zdravim, kde sa dá zohnat to winAPI ?

JJ | 13.05.07 v 21:47

Ahoj, serial mi prijde zajimavy, ale mel bych malou pripominku k tomuto dilu. Jak je mnohokrat uvedeno, serial si neklade za cil ucit winapi. Ok, to chapu (k winapi je pekny serial na builderu), ale pak mi prijde zbytecne prakticky cely dil zaplacnout zdrojaky, ktere zkusenejsi programator preskoci a novacek je stejne nepochopi. Mnohem snazsi by bylo nevenovat se implementaci, ale analyze a reseni jednotlivych uloh a nakonec priplacnout zdrojak ke stazeni (pripadne trochu komentovany).
Z nastinu pristiho dilu tipuju, ze dil o dx bude vypadat podobne a myslim, ze by to byla skoda.

? | 13.05.07 v 11:35

Kde se dá stáhnout ten winapi ????