[CZĘŚĆ 2] STM32Butterfly2: Tetris na STM32 – interfejs użytkownika

 

 

 

 

W drugiej części artykułu przedstawiamy budowę interfejsu użytkownika znanej i popularnej od lat gry Tetris, którą autor zaimplementował w mikrokontrolerze STM32F107 z zestawu STM32Butterfly2.

 

 

Interfejs użytkownika składa się z dwóch głównych części:

  • obsługi joysticka,
  • obsługi wyświetlacza graficznego.

Dzięki wcześniej przygotowanej obsłudze przerwań z pinów podłączonych do styków joysticka, bardzo łatwo będzie oprogramować tę część interfejsu.
Na początku zajmijmy się poruszaniem klocka na boki. Będzie to bardzo proste, bo mamy już gotowe funkcje, które to robią. Przed ich wywołaniem musimy tylko sprawdzić czy w zmiennej stan_gry zapisana jest wartość GRA. Zapobiegnie to przesuwaniu klocka podczas pauzy lub po zakończeniu gry. W funkcji przerwania EXTI15_10_IRQHandle w obrębie warunku sprawdzającego czy joystick był naciśnięty w prawo, dodajemy:

Analogiczny wpis dodajemy dla ruchu w lewo i dół, nie zapominając o dodaniu deklaracji (z modyfikatorem extern) zmiennej stan_gry na początku funkcji.
Do funkcji EXTI9_5_IRQHandler dodamy natomiast wywołanie funkcji obracającej klocek, jeżeli joystick zostanie przesunięty w górę. Tu także dodajemy definicję zmiennej stan_gry. Natomiast na początek pliku z funkcjami przerwań kopiujemy deklaracje nazw wartości dla tej zmiennej (NITRO, GRA… itd.).
Do obsługi wyświetlacza można zaadoptować jedna z wielu dostępnych gotowych bibliotek. Ja napisałem swoją od podstaw tak, aby była jak najprostsza. Nie będę tu wnikał zbytnio w szczegóły, zainteresowani sami prześledzą funkcje wyświetlania grafiki. Jeżeli chcesz skorzystać z mojej biblioteki to dodaj pliki NokiaLCD.c i NokiaLCD.h do projektu, a na początku pliku main.c powinno się znaleźć:

W ten sposób kompilator uzyska informację o wszystkich funkcjach biblioteki. Przed korzystaniem z wyświetlacza należy jeszcze wywołać funkcje LcdInit. Przygotowuje ona sprzęt do pracy. Najlepiej zrobić to zaraz po konfiguracji peryferiów mikrokontrolera.
Skupmy się teraz na funkcji, która rysuje ekran z planszą gry. W swoim projekcie nazwałem ją RysujEkran. Na początek wywołujemy funkcję LcdClear z naszej biblioteki graficznej, w celu usunięcia poprzedniej zawartość ekranu. W kolejnym kroku rysujemy na ekranie wszystkie stałe elementy tła (rysunek 5).

 

Rys. 5. Wygląd bitmapy tła

Rys. 5. Wygląd bitmapy tła

 

 

W katalogu projektu stworzyłem nowy plik grafika.h i tak skopiowałem tablicę nazywając ją:

Tak przygotowaną grafikę wyświetla się na ekranie funkcją LcdLoadBMP. Teraz wystarczy narysować samą planszę, spadający klocek, klocek jaki będzie następny oraz wynik gracza. Jednak zanim napiszemy resztę funkcji proponuję zdefiniować współrzędne każdego z tych elementów. Przyda się to nam jak będziemy chcieli w przyszłości zmienić układ graficzny. Moje definicje wyglądają tak:

Najpierw narysujemy stałe segmenty klocków na planszy. Przy tak niewielkiej rozdzielczości wyświetlacza postanowiłem, że każdy segment klocka będzie składał się z czterech pikseli. Aby narysować całą planszę musimy sprawdzić każdą z komórek tablicy plansza, czyli zastosujemy dwie pętle i warunek. Jeżeli dana komórka będzie miała wartość 1 to należy zapalić odpowiadające jej cztery piksele na ekranie. Ten fragment kodu napisałem w ten sposób:

Do pobrania

O autorze