Programy a aplikace od našich čtenářů

Tisk článku Tisk článku

PacMan

[Zpět na blog]

Datum: 12. 5. 2008 22:56       Autor: Tomáš Herceg       Zobrazeno: 3507x

Kategorie: 2D, VB.NET


Hru PacMan nám zaslal čtenář Jan Dědek.

Dobrý den,

zasílám Vám námět do rubriky „Od našich čtenářů“.

Začínám se učit ve VB.net programovat grafiku a jako ukázka na které můžu dělat pokusy mi krásně posloužila vaše hra Hungry Snake.

Chvíli jsem dělal se zdrojákem pokusy a různé úpravy, až jsem se rozhodl, že zkusím co jsem se všechno naučil a jestli jsem základy této problematiky pochopil a rozhodl jsem se naprogramovat hru úplně od začátku. Vybral jsem si další velmi známou hru PAC MAN. Jak už jsem řekl z Vašeho článku o hře had jsem se poprvé setkal s programováním grafiky, takže v mé hře bude několik bloku kódu velmi podobných (protože zatím nevím jaké jiné možnosti řešení jsou).

Hra je velmi jednoduchá. V 1 levelu jsou 3 protihráč, v každém dalším kole je jeden protihráč navíc. Po sebrání všech mincí hráč postupuje do dalšího kola kterých je celkem 5. Pokud hráč narazí do protihráče hra končí.

Konstrukce hry je podobná jako u hada s tím rozdílem, že jsem přidal ještě jeden timer který se stará o pohyb protihráčů které řídí počítač. To že počítačem řízené postavy mají vlastní timer má tu výhodu, že si uživatel může nastavit obtížnost hry (zmenší se interval na timeru a tím se NPC pohybují rychleji).

Kvůli protihráčům jsem si musel také vytvořit více typů polí. Tam jsem narazil na úskalí jak zjistit po přejezdu NPC jestli pole bylo prázdné a nebo na něm byl bod který ještě hráč nesebral. Proto jsem si u protihráče vytvořil 2 typy pole (obsazeni.volno a obsazeni.bod). Podle toho poznám co na poli bylo před změnou souřadnic a po další změně tam vrátím původní hodnotu.

Vnitřní stěna se generuje náhodně a tam jsem narazil na jedno úskalí které se mi prozatím nepodařilo vyřešit a to jak zajistit, aby mi nezůstalo nějaké (buď osamocené nebo skupina několika polí s mincema) které jsou zazděné a nejde se k nim dostat.

Rozmístění protihráčů je také generováno automaticky s tím, že je pole pro jejich rozmisťování úmyslně zmenšeno, aby se hned na začátku nevygeneroval protihráč hned vedle hráče a nedošlo ke sražení a tím ukončení hry.

Nejtěžší bylo vymyslet umělou inteligenci NPC. Nakonec jsem to vyřešil tak, že NPC jdou jedním směrem dokud do něčeho nenarazí (do stěny nebo do jiného NPC). Po nárazu je volána procedura která vygeneruje náhodné číslo od 1 do 4. (každému číslu je přiřazen jeden směr) a ten se pak u příslušného NPC nastaví, takže pohyb je opravdu náhodný. Pro každý směr (u hráče i NPC) je samostatný obrázek, aby to vypadalo že se smajlík vždycky kouká směrem kterým jde.

Pokud se Vám zdá tento námět zajímavý, určitě budu rád pokud se objeví na stránkách VBnet. Třeba někdo přijde s nějakým zajímavým zlepšením (ať už zmíněnou nevyřešenou kontrolou dostupností všech políček s mincemi nebo čímkoliv jiným) a hlavně s kritikou, abych se dozvěděl co udělat jinak,lépe, protože chybami se člověk učíJ

S pozdravem

Jan Dědek

 


> Na začátek

 

Hodnocení:

Hlasů: 4
Zvolte své hodnocení

Tomáš Herceg

Jsem hlavním softwarovým architektem ve společnosti Riganti. Mám dlouholeté zkušenosti s technologiemi ASP.NET, Silverlight, WPF a XNA. Působím též jako lektor ve společnosti Gopas a již třetím rokem jsem držitelem ocenění Microsoft Most Valuable Professional.

Podpořte vznik dalších článků
RSS Feed RSS Feed

Diskuse

1 

PacMan

Datum: 13.5.2008 22:53
Autor: Václav Antošík
Hodnocení autora: 41
Příspěvků: 102
Veľmi pekná hra. Len by som mal jednu pripomienku a to :
Stalo sa mi, že pri náhodnom umiestňovaní stien sa steny usporiadali tak, že obkolesili guličku a ja som sa k nej PacManom nemohol dostať. Možno by to chcelo doplniť ešte nejakú podmienku, ktorá by to riešila.

Vašo
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: PacMan

Datum: 14.5.2008 7:10
Autor: neregistrovaný (194.228.18.137)
Hodnocení autora: není
Příspěvků: 0
Ano o tom vím, píšu to i v příspěvku. Prozatím se mi tento problém nepodařilo vyřešit. Až budu mít chvilku čas zkusím na to ještě sednout;)
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: PacMan

Datum: 14.5.2008 19:58
Autor: Jan Novák
Hodnocení autora: 235
Příspěvků: 783
Navrhoval bych řešení typu projít všechny kuličky a zjišťovat, co má za sousedy, pokud by ani jeden z nich nebyl kulička, jednoduše by se kulička nahradila zdí.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: PacMan

Datum: 14.5.2008 21:15
Autor: neregistrovaný (77.48.126.251)
Hodnocení autora: není
Příspěvků: 0
To jsem zkoušel ale jde o to že takto nemusí být zablokovaná jenom jedna kulička,může jich být klidně 5 nebo když to přeženu tak se zeď může rozestavět po celá šířce hracího pole čímž hráč bude úplně odříznutý od vrchní půlky hrací plochy.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: PacMan

Datum: 14.5.2008 22:19
Autor: Václav Antošík
Hodnocení autora: 41
Příspěvků: 102
hmm a čo skúsiť pridať test taký, ktorý by hovoril, že každé políčko steny vnútry hracej plochy musí mať aspoň jedného suseda guličku. A ak nemá, tak náhodne vytvorí jednu guličku v okolí.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: PacMan

Datum: 14.5.2008 20:09
Autor: Václav Antošík
Hodnocení autora: 41
Příspěvků: 102
Prepáčte, že som poukázal na to, čo ste už spomenuli v článku ako nedostatok. Bola už pokročilá večerná hodina....

Vašo
 
           [Odpovědět]
 
Hodnocení: 1 Čekejte, prosím...

Re: PacMan

Datum: 15.5.2008 0:36
Autor: Viktor Langer
Hodnocení autora: 300
Příspěvků: 641
Ono to není ani moc složité, jenom to chce trochu potrápit hlavičku:
Nám jde o to, aby se ke každému penízku Vaše potvora mohla prokousat. Což tedy ty penízky umisťovat stejně?

Udělám si hrací pole (obvodové a vnitřní zdi) tak, jak jste zvyklý umístím hráče a sám se postavím na stejné pole, jako je on. (modré potvory ještě nechám v klidu).
No a teď se podívám na políčko, které mám po levé ruce, a pokud je toto políčko volné, umístím na něj puntík, postavím na něj brášku a řeknu mu, ať dělá úplně totéž, co já.
Dále se o brášku nestarám a kouknu se na políčko přede mnou a opět - je-li tam pusto a prázdno, dám další puntík a pošlu na něj dalšího brášku se stejnými instrukcemi. Sám se stejným způsobem ještě zajímám o políčko vpravo ode mne a nakonec to za zády. Tím mám padla.
No a každý z mých brášků dělá na "svém" políčku totéž, co jsem před chvílí dělal já, a umístí další bodíky a další brášky....
A až všichni bráškové zkontrolují všechna 4 svá sousední políčka, je pohádky konec a máme vystaráno, protože na všech políčkách, na která je možno jakkoliv dojít z výchozí pozice máme ťumplíky, no a pokud se vám při stavění zdi stane ten malér, že nějakou část pole uzavřete, vůbec to nevadí - vnitřní políčka budou bez penízků (pouze nezapomeňte počítat s tím, že nyní nemáte plný počet bodíků v každém kole při vyhodnocování skóre).

No a v řeči VB tato "složitost" vypadá nesmírně jednoduše:

Sub vykreslitBody()
        ' vykreslíme body všude tam, kde není zeď a přitom je pole přístupné

        ' výchozí poloha bude na souřadnicích, na kterých je umístěn hráč [hrac.X,hrac.Y]
        prozkoumejOkoli(hrac.X, hrac.Y)

        ' po provedeném průzkumu body vykreslím

        For x As Integer = 1 To 15
            For y As Integer = 1 To 15
                If pole(x, y) = obsazeni.bod Then
                    g.DrawImage(ImageList1.Images(9), x * 35, y * 35)
                End If
            Next
        Next

    End Sub

    Private Sub prozkoumejOkoli(ByVal X As Integer, ByVal Y As Integer)
        ' rekurzivní funkce, která jako vstup obdrží bod hracího pole, jehož okolí má prozkoumat

        ' prozkoumáme nejprve políčko vlevo od stávající pozice
        ' pokud je pole vlevo od aktuální pozice prázdné,
        ' pak na ně umístím bod a zkusím opětovným voláním stejné funkce
        ' prozkoumat jeho okolí
        If pole(X - 1, Y) = obsazeni.volno Then pole(X - 1, Y) = obsazeni.bod : prozkoumejOkoli(X - 1, Y)
        ' totéž udělám pro políčko nad aktuální pozicí...
        If pole(X, Y - 1) = obsazeni.volno Then pole(X, Y - 1) = obsazeni.bod : prozkoumejOkoli(X, Y - 1)
        ' ...a vpravo od ní...
        If pole(X + 1, Y) = obsazeni.volno Then pole(X + 1, Y) = obsazeni.bod : prozkoumejOkoli(X + 1, Y)
        ' ... a ještě dole
        If pole(X, Y + 1) = obsazeni.volno Then pole(X, Y + 1) = obsazeni.bod : prozkoumejOkoli(X, Y + 1)


    End Sub
 

No a pokud se Vám, tak jako mně, po několika pokusech o "rozdání" puntíků na hrací pole stane, že Vám hra "zamrzne", je to tím, že nemáte ošetřenu ještě jednu drobnost a totiž stav, kdy si kolem hráče nastavíte natěsno zdi ze všech 4 stran, takže se chudák hned od začátku nemůže ani hnout.:o(
 
           [Odpovědět]
 
Hodnocení: 3 Čekejte, prosím...

Re: PacMan

Datum: 16.5.2008 15:56
Autor: Tomáš Herceg
Hodnocení autora: 1660
Příspěvků: 3533
Smekám klobouk, jak názorně se vám povedlo popsat a vysvětlit rekurzi, ten nápad s tím bráškou je naprosto skvělý.
 
           [Odpovědět]
 
Hodnocení: 1 Čekejte, prosím...

Pauza

Datum: 15.5.2008 20:21
Autor: Jan Novák
Hodnocení autora: 235
Příspěvků: 783
Zdravím,
Objevil jsem ve Vaší hře (btw je dobrá :)) malou chybku. Pokud se střetnete s protivníkem a tudíž nastane konec hry, je možno našeho hrdinu "resuscitovat" malým trikem, a sice stiskem volby Pauza v nabídce Hra. Ovšem efekt je pouze dočasný. Nevím čím to je (přiznám se, že zdroáky jsem moc nezkoumal, protože mi teď přerůstají přes hlavy ty moje).

Hodně zdaru při vývoji dalšího projektu
 
           [Odpovědět]
 
Hodnocení: 2 Čekejte, prosím...

Re: Pauza

Datum: 16.5.2008 12:06
Autor: neregistrovaný (194.228.18.137)
Hodnocení autora: není
Příspěvků: 0
Děkuji za pochvalu a upozornění na bug, opravím ho:)
 
           [Odpovědět]
 
Hodnocení: 1 Čekejte, prosím...

PacMan

Datum: 12.8.2011 9:53
Autor: Ondřej Šrytr
Hodnocení autora: 0
Příspěvků: 16
Pěkné!
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...
1 
 

VBNET.CZ | © 2007 Tomáš Herceg, Tomáš Jecha | Kopírování a přejímání jakéhokoliv obsahu z tohoto webu je bez písemného svolení autorů zakázáno.