Hra na grafický displej - PACMAN

Vojtěch Melša, Jiří Šlesingr
xmelsa03@stud.feec.vutbr.cz, xslesi01@stud.feec.vutbr.cz

Obsah:

  1. Úvod
  2. Realizace
  3. Závěr
  4. Literatura

Úvod

Cílem projektu bylo vytvoření a naprogramování hry na grafický displej. Řešitelé projektu vyberou hru, která se bude realizovat instrukcemi a příkazy.

Realizace

Po uvážení všech možností bylo jako vhodná volba projektu hry na grafický displej zvolena všemi dobře známá hra Pacman (viz Obr.1).

Obr. 1: PACMAN

Účelem hry je pomocí definovaného emotikonu Pacmana (hlava s otevírajícími se ústy) sbírat body, které se načítají sběrem kuliček. Pacman  má pevně dané hrací pole,vymezující celý displej. V hracím poli jsou umístěny kuličky, které musí hráč sbírat. Vše je zobrazeno na grafickém displeji viz Obr.2.

displej.png

Obr. 2: Grafický displej

Po inicializaci hry se Pacman začne pohybovat. K ovládání hry slouží maticová klávesnice (Obr. 3, Obr. 4), kde pomocí čtyřech tlačítek se Pacman ovládá v horizontálním a vertikálním směru. Všechny řádkové vodiče jsou v klidu udržovány na úrovni H pomocí rezistorů R. Budicí obvod pak postupně připojuje na jednotlivé sloupcové vodiče úroveň L. Pokud je stisknuté některé tlačítek, které je připojeno na právě buzený vodič (tj. na úrovni L), je tato úroveň spínačem připojena na příslušný vodič (řádkový). Elektronika může ze zjištěných souřadnic odvodit kód příslušné klávesy.

Obr. 3: Zapojení maticové klávesnice.

 

Obr. 4: Signály maticového displeje

 

S využitím nekonečné smyčky se testují tlačítka maticové klávesnice, jejich stisk. Pokud uživatel zmáčkne jedno z tlačítek změny směru, pak se načte aktuální poloha, Pacman se vymaže, respektive se překreslí na bílo. Podle toho jaké bude zmáčknuté tlačítko - volba nového směru, se poloha Pacmana přednastaví do nového směru, dojde k vygenerování celého emotikonu v nové poloze.

Obr. 5: Připojení klávesnice k ATMega 16

Pohyb Pacmana zajišťuje obsluha přerušení časovače 1. Podle nastaveného směru se inkrementují nebo dekrementují souřadnice x a y o definovaný krok. Na původní poloze se emotikon smaže (překreslí se bílou) a vygeneruje se podle nových souřadnic.

Ukázky zdrojového kódu:

 

Nekonečná smyčka – testování tlačítek změny směru Pacmana

 

while( 1 )                                                             // nekonečná smyčka pro testování stisku tlačítek

                  {

 

            PORTB=0b01110000;                                    // výběř 1. řádku

            _delay_ms (30);

 

                  if (bit_is_clear(PINB,2))                      // testování stisku příslušného tlačítka (4)

                             {

 

                            

                             circle(x, y, 10, WHITE);                                   //

                             _delay_ms (5);

                             triangle(x, y, x-10, y+3, x-10, y-3, WHITE);   //

                             _delay_ms (5);

                             triangle(x, y, x+3, y+10, x-3, y+10, WHITE);   // překreslení (vymazání) pacmana pro všechny možné směry pohybu

                             _delay_ms (5);

                             triangle(x, y, x+3, y-10, x-3, y-10, WHITE);   //

                             _delay_ms (5);

                             triangle(x, y, x+10, y+3, x+10, y-3, WHITE);   //

 

                             _delay_ms (10);

                             circle(x, y, 10, BLACK);                                   //

                             triangle(x, y, x-10, y+3, x-10, y-3, BLACK);   // vykreslení pacmana pro danný směr (vlevo)

                            

                             smer=1;                                                                // nastavení směru (vlevo)

                             }

 

 

            PORTB=0b10110000;                                    // výběř 2. řádku

            _delay_ms (30);

 

                  if (bit_is_clear(PINB,2))                      // testování stisku příslušného tlačítka (5)

                             {

                            

                            

                             circle(x, y, 10, WHITE);                                   //

                             _delay_ms (5);

                             triangle(x, y, x-10, y+3, x-10, y-3, WHITE);   //

                             _delay_ms (5);

                             triangle(x, y, x+3, y+10, x-3, y+10, WHITE);   // překreslení (vymazání) pacmana pro všechny možné směry pohybu

                             _delay_ms (5);

                             triangle(x, y, x+3, y-10, x-3, y-10, WHITE);   //

                              _delay_ms (5);

                             triangle(x, y, x+10, y+3, x+10, y-3, WHITE);   //

 

                             _delay_ms (10);

                             circle(x, y, 10, BLACK);                                   //

                             triangle(x, y, x+3, y+10, x-3, y+10, BLACK);   // vykreslení pacmana pro danný směr (dolu)

                            

                             smer=2;                                                                // nastavení směru (dolů)

                             }

 

                  if (bit_is_clear(PINB,3))                      // testování stisku příslušného tlačítka (2)

                             {

                            

                            

                             circle(x, y, 10, WHITE);                                   //

                             _delay_ms (5);

                             triangle(x, y, x-10, y+3, x-10, y-3, WHITE);   //

                             _delay_ms (5);

                             triangle(x, y, x+3, y+10, x-3, y+10, WHITE);   // překreslení (vymazání) pacmana pro všechny možné směry pohybu

                             _delay_ms (5);

                             triangle(x, y, x+3, y-10, x-3, y-10, WHITE);   //

                             _delay_ms (5);

                             triangle(x, y, x+10, y+3, x+10, y-3, WHITE);   //

 

                             _delay_ms (10);

                             circle(x, y, 10, BLACK);                                   //

                             triangle(x, y, x+3, y-10, x-3, y-10, BLACK);   // vykreslení pacmana pro danný směr (nahoru)

                            

                             smer=3;                                                                // nastavení směru (nahoru)                   

                             }

 

 

                 

            PORTB=0b11010000;                                    // výběř 3. řádku

            _delay_ms (30);

 

                  if (bit_is_clear(PINB,2))                      // testování stisku příslušného tlačítka (6)

                             {

 

                            

                             circle(x, y, 10, WHITE);                                   //

                             _delay_ms (5);

                             triangle(x, y, x-10, y+3, x-10, y-3, WHITE);   //

                             _delay_ms (5);

                             triangle(x, y, x+3, y+10, x-3, y+10, WHITE);   // překreslení (vymazání) pacmana pro všechny možné směry pohybu

                             _delay_ms (5);

                             triangle(x, y, x+3, y-10, x-3, y-10, WHITE);   //

                             _delay_ms (5);

                             triangle(x, y, x+10, y+3, x+10, y-3, WHITE);   //

 

                             _delay_ms (10);

                             circle(x, y, 10, BLACK);                                   //

                             triangle(x, y, x+10, y+3, x+10, y-3, BLACK);   // vykreslení pacmana pro danný směr (vpravo)

                            

                             smer=0;                                                                // nastavení směru (vpravo) 

                             }

                  }

 

 

     

           

 

 

           

             

}

 

 

Obsluha přerušení časovače/čítače č. 1 – vymazání, generování, krok Pacmana podle zadaného směru

 

ISR( TIMER1_OVF_vect )                         // přerušení při přetečení časovače1/čítače1

{

     

     

 

                       

 

                  if (smer==1)                                                                             // testování směru pohybu

                             {

                             if (x>10)                                                                    // testování levého okraje obrazovky

                                   {

                                   x=x-krok;                                                              // dekrementace kroku ve směru x (phyb směrem vlevo)

 

 

                                  

                                   circle(x, y, 2, WHITE);                                          // překreslení (vymazání) sebraného bodu

 

                                   circle(x+krok, y, 10, WHITE);                                                //

                                   triangle(x+krok, y, x-10+krok, y+3, x-10+krok, y-3, WHITE);           // překreslení (vymazání) pacmana v daném směru pro předchozí krok

                                  

 

                                   circle(x, y, 10, BLACK);                                         //

                                   triangle(x, y, x-10, y+3, x-10, y-3, BLACK);         // vykreslení pacmana se změněným krokem v daném směru

                                   }    

                             }

 

     

                  if (smer==2)                                                                             // testování směru pohybu

                             {

                             if (y<50)                                                                    // testování spodního okraje obrazovky

                                   {

                                   y=y+krok;                                                              // inkrementace kroku ve směru y (pohym směrem dolu)

 

 

                                  

                                   circle(x, y, 2, WHITE);                                          // překreslení (vymazání) sebraného bodu

 

                                   circle(x, y-krok, 10, WHITE);                                                //

                                   triangle(x, y-krok, x+3, y+10-krok, x-3, y+10-krok, WHITE);           // překreslení (vymazání) pacmana v daném směru pro předchozí krok

                                  

 

                                   circle(x, y, 10, BLACK);                                         //

                                   triangle(x, y, x+3, y+10, x-3, y+10, BLACK);         // vykreslení pacmana se změněným krokem v daném směru

                                   }

                              }

 

 

     

                  if (smer==3)                                                                             // testování směru pohybu

                             {                      

                             if (y>10)                                                                    // testování horního okraje obrazovky

                                   {

                                   y=y-krok;                                                              // dekrementace kroku ve směru y (pohym směrem nahoru)

 

 

                                  

                                   circle(x, y, 2, WHITE);                                          // překreslení (vymazání) sebraného bodu

 

                                   circle(x, y+krok, 10, WHITE);                                                //

                                   triangle(x, y+krok, x+3, y-10+krok, x-3, y-10+krok, WHITE);           // překreslení (vymazání) pacmana v daném směru pro předchozí krok

                            

                                   circle(x, y, 10, BLACK);                                         //

                                   triangle(x, y, x+3, y-10, x-3, y-10, BLACK);         // vykreslení pacmana se změněným krokem v daném směru

                                   }

                             }

 

 

     

                  if (smer==0)                                                                             // testování směru pohybu

                             {

                             if (x<110)                                                                   // testování spodního okraje obrazovky

                                   {

                                   x=x+krok;                                                              // inkrementace kroku ve směru x (pohyb směrem vpravo)

 

 

                            

                                   circle(x, y, 2, WHITE);                                          // překreslení (vymazání) sebraného bodu

 

                                   circle(x-krok, y, 10, WHITE);                                                //

                                   triangle(x-krok, y, x+10-krok, y+3, x+10-krok, y-3, WHITE);           // překreslení (vymazání) pacmana v daném směru pro předchozí krok

 

                                   circle(x, y, 10, BLACK);                                         //

                                   triangle(x, y, x+10, y+3, x+10, y-3, BLACK);         // vykreslení pacmana se změněným krokem v daném směru

                                   }

                             }

                 

           

}

 
 
        #include<stdio.h>
        /*
        komentare...
        */
        

Závěr

Hra plně funguje, v případě, že Pacman dojde ke kraji displeje, tak se zastaví na aktuální pozici. Celá hra by se dala rozšířit o počítalo sebraných bodů  - skóre hry, případně doplnit hrací pole o pevné překážky, kterým by se hráč musel vyhnout, nebo doplnit hru o pasti, pokud by se jím hráč nevyhnul, došlo by například k resetu hry. Odkaz na stáhnutí zdrojového kódu projektu.

Literatura

[1] FRÝZA, Tomáš, FEDRA, Zbyněk, ŠEBESTA, Jirí. Mikroprocesorová technika : Laboratorní cvičení. [s.l.] : [s.n.]. 51 s. Dostupný z WWW: https://krel.feec.vutbr.cz/VYUKA/M_EST/MMIA/Texty/bmpt_laboratore.pdf.

[2] Atmel Corporation. Datasheet ATmega16. Atmel Corporation, 2006, www.atmel.com/literature. [online]. 2012 [cit. 2012-04-30]