Gra Snake

Transkrypt

Gra Snake
Antoni Smoliński
nr indeksu: 236590
Projekt MARM
Gra Snake
W ramach projektu MARM zaimplementowana została gra snake do uruchomienia na
zestawie STM32F4 – Discovery. Gra polega na prowadzeniu po ekranie „węża” w kierunku losowo
generowanych punktów. Zderzenie z krawędzią okna, bądź z samym wężem powoduje zakończenie
gry. Zebranie punktu wydłuża węża i przyspiesza grę.
Implementacja gry składa się z trzech klas: main, view oraz snake.
W klasie main konfigurowany jest zegar, uruchomiany jest wyświetlacz oraz planista
FreeRTOS. Następnie startowany jest task Background_Task odświeżający ekran. W ramach tasku
Background_Task tworzony jest kolejny task: viewTask. Funkcje zadanie viewTask opisane są w
klasie view.
Klasa view tworzy dwa okna, poprzez funkcje z biblioteki WM. Jedno okno odpowiada za
„status bar” u góry ekranu. W tym okienku widoczny jest zegar. Drugie okno jest oknem gry i
opisane jest w klasie snake.
Klasa snake odpowiada za samą grę. Ma ona statyczne pola typu int: points, delay,
snakeHeadIndex, snakeRearIndex, snakeDirection (wykorzystywany z definiowanymi wartościami
DIRECTION_UP, DIRECTION_DOWN, DIRECTION_LEFT, DIRECTION_RIGHT) oraz
snakeLength. Dodatkowo jest też tu statyczna tablica struktur typu SnakeElement. SnakeElement to
struktura skłądająca się z trzech intów: x, y oraz nextPart. Są tu też zmienne pomocnicze do
rysowania węża na ekranie.
Definiowane są też zmienne NUM_CELL_X i NUM_CELL_Y, dzięki którym można
zmieniać ilość komórek, po których porusza się wąż.
W głównej pętli wywoływana jest funkcja move, odpowiedzialna za przeliczanie pozycji
węża, oraz wyświetlenie go na ekranie oraz delay. Długość opóźnienia wyliczana jest na podstawie
zdobytych punktów. Nie jest to zależność liniowa – ponieważ przy liniowej tempo gry rosło by zbyt
wolno. (Przy maksymalnej długości węża delay nie może spaść poniżej 0)
Wąż opisywany jest tablicą o długości NUM_CELL_X*NUM_CELL_Y (tak aby najdłuższy
wąż mógł zajmować cały ekran). Tablica ta zawiera struktury SnakeElement. Zmienna
snakeHeadIndex wskazuje na komórkę tablicy, w której jest element odpowiadający za pierwszy
element węża a zmienna snakeRearIndex wskazuje jego koniec. Zmienna snakeLength to długość
węża.
Przy wywołaniu funkcji move algorytm jest następujący:
Sprawdzany jest kierunek w którym przemieszcza się wąż. Następnie na podstawie
czołowego elementu tworzony jest nowy element (przesunięty odpowiednio o x lub y, w zależności
od kierunku). Sprawdzamy teraz czy element ten nie leży poza ekranem gry, lub czy nie istnieje już
taki element (to oznaczałoby że wpadliśmy na węża). Jeśli tak, to kończymy grę. Jeśli nie to
sprawdzamy czy w miejscu do którego ma się przemieścić czoło węża, jest do zdobycia punkt.
Jeśli nie ma punktu to nowy element zapisujemy w tablicy w miejscu wskazanym przez
zmienną snakeRearElement. W ten sposób nie powiększamy niepotrzebnie tablicy, nadpisujemy
ostatni element, nowym pierwszym i uzyskujemy przesunięcie węża. Należy jeszcze zaktualizować
zmienne wskazujące na pierwszy i ostatni element. Nowy ostatni element wyznaczamy przy
pomocy zmiennej nextPart w strukturze. Zmienna ta mówi w którym kierunku poruszał się wąż,
gdy ten element był tworzony.
Jeśli punkt jest, to nowy element wpisywany jest do tablicy pod indeksem o wartości
snakeLength a sama zmienna snakeLength jest inkrementowana. Wyliczany jest też nowa wartość
delay, przyspieszająca grę.
Po przeliczeniu modelu gry wykonywana jest funkcja draw odpowiedzialna za wyświetlenie
węża w oknie gry. Okno gry podzielone jest na prostokąty. Wielkość prostokątów zależna jest od
liczby pól gry (a więc od zmiennych NUM_CELL_X i NUM_CELL_Y). Następnie w podwójnej
pętli wyświetlane są na ekranie. Przy każdym wyświetlanym prostokącie sprawdzane jest czy w
odpowiadającej mu komórce jest wąż lub punkt. Jeśli wybierany jest kolor biały, jeśli jest punkt (i
nie ma węża) wybierany jest niebieski, a jeśli jest wąż to czarny.
Zmiana kierunku węża realizowana jest poprzez callback _onTouch. Jeśli wąż aktualnie
skierowany jest horyzontalnie to sprawdzamy czy dotknięcie było w górnej, czy w dolnej połowie
ekranu. Jeśli wąż skierowany jest wertykalnie, sprawdzamy czy dotknięcie było z lewej czy z
prawej strony. Dotknięcie ekranu zmienia tylko wartość zmiennej snakeDirection.
Po przegranej wyświetlane jest okienko z informacją o ilości zdobytych punktów oraz
przyciskiem „restart”, który sprowadza grę do inicjalnych wartości (czterosegmentowy wąż,
skierowany w prawo, pośrodku ekranu).

Podobne dokumenty