- Plan gry:
- Schemat obwodu:
- Wymagania wstępne:
- Programowanie Arduino do gry Space Race:
- Działanie gry Arduino Space Racer:
Programowanie zawsze było zabawne, a dzięki platformom programistycznym, takim jak Arduino, stało się o wiele lepsze. Prawie każdy programista próbowałby stworzyć jakąś grę, używając języka, którego się uczy / ćwiczy. Pomaga im to doskonalić umiejętności programowania w zabawny, ale produktywny sposób. Jestem wielkim fanem Arduino odkąd go poznałem i zawsze chciałem spróbować czegoś fajnego, kiedy dowiedziałem się, jak fajnie może być dzięki graficznemu wyświetlaczowi LCD, jak Nokia 5110, wraz z Arduino.Mój pomysł na stworzenie gry włączył się. To był ciekawy sposób na doskonalenie kilku umiejętności programistycznych i jednoczesną zabawę, więc chociaż wy też możecie być zainteresowani rozwojem swojej gry. Dlatego w tym samouczku nauczymy się, jak stworzyć przyzwoitą grę za pomocą Arduino i graficznego wyświetlacza LCD.
Zbudowaliśmy już staroświecką grę Snake za pomocą Arduino, więc tym razem próbujemy czegoś nowego i nazwaliśmy tę grę Space Race Game, w której musisz chronić swój statek przed statkami wroga za pomocą joysticka.
Plan gry:
Zanim zaczniemy, bardzo ważne jest, aby zaplanować, jak gra będzie działać. Wybrałem graficzny wyświetlacz LCD i joystick Nokia5110 przy wyborze sprzętu. Zakładam w tym samouczku, że wybrałeś również to samo. Ponieważ Nokia 5110 nie ma dużo miejsca, zaplanowaliśmy całą naszą grę w rozdzielczości 84 * 48 pikseli naszego wyświetlacza. Stworzyliśmy już samouczki dotyczące interfejsu Nokia 5110 LCD z Arduino i Joystick z Arduino.
W tej przestrzeni musimy ściśle dopasować się do obszaru gry i obszaru tablicy wyników, na którym będą wyświetlane takie rzeczy, jak wynik i inne rzeczy. Bardzo ważne jest, aby znać lokalizację piksela, w którym umieszczasz rzeczy, aby śledzić lokalizacje pikseli i aktualizować je na ekranie.
Po ustaleniu wyglądu ekranu gry musimy zdecydować o postaciach w naszej grze. W mojej grze mamy tylko dwie, postać gracza, która jest statkiem kosmicznym i postać wroga, która powinna wyglądać jak statek kosmiczny obcych. Wyświetlacz LCD Nokii może wyświetlać obrazy bitmapowe, więc zdecydowałem się użyć tej opcji, aby wyświetlić mój statek kosmiczny i wrogów.
Będziemy więc mieć statek kosmiczny, który ściga się przez statki kosmiczne obcych, ten statek kosmiczny będzie miał trzy tory do zmian, aby uniknąć uderzenia w kosmitów. Przez cały czas obcy mogą zajmować tylko dwa tory, a gracz powinien mieć możliwość przejeżdżania przez wolny tor. Gdy te pomysły zostaną zakończone, możemy przejść do sprzętu, a następnie do programowania.
Schemat obwodu:
Obwód tej gry Arduino jest bardzo prosty; musimy tylko połączyć moduł LCD Nokia 5110 i joystick z Arduino. Pełny schemat obwodu pokazano poniżej
Nokia 5110 LCD współpracuje z 3,3 V, a moduł Joystick działa z napięciem 5 V, więc upewnij się, że podłączyłeś LCD tylko do 3,3 V, ponieważ 5 V może go trwale uszkodzić. Wyświetlacz LCD komunikuje się z Arduino przez protokół SPI, a joystick odczytuje tylko ADC, aby odczytać zmianę napięcia. Konfiguracja połączenia będzie wyglądać mniej więcej tak poniżej
Wymagania wstępne:
Zanim przejdziemy do części programistycznej, ważne jest, abyście byli wygodni z modułem wyświetlacza i joystickiem, więc możesz skorzystać z poniższych samouczków, aby dowiedzieć się o nich więcej, a następnie wrócić tutaj, aby upewnić się, że wszystko działa tak, jak my. potrzebuję tego!
- Interfejs Nokia 5110 LCD z Arduino
- Moduł joysticka współpracujący z Arduino
Programowanie Arduino do gry Space Race:
Kompletny program do gry można znaleźć na końcu tej strony; możesz go używać bezpośrednio na swoim Arduino IDE i przesłać go na swoją tablicę. Ale jeśli chcesz wiedzieć, co tak naprawdę dzieje się w kodzie, przeczytaj dalej.
Jak zawsze zaczynamy nasz program od dodania naszych plików nagłówkowych bibliotek, potrzebujemy trzech bibliotek dla tego projektu, z których biblioteka SPI jest domyślnie dodawana do twojego IDE. Pozostałe dwie biblioteki należy pobrać ze strony Adafruit Github. Postępuj zgodnie z samouczkiem dotyczącym interfejsu LCD wymienionym w sekcji wymagań wstępnych, jeśli nie masz pewności, jak dodać bibliotekę.
#zawierać
Jeśli korzystałeś z samouczka, powinieneś wiedzieć, że możliwe jest wyświetlanie obrazów bitmapowych na wyświetlaczu LCD. Musimy więc przekonwertować wymagany obraz na kod mapy bitowej za pomocą oprogramowania wspomnianego w samouczku, możesz wybrać dowolny obraz z Internetu i użyć go, konwertując go na kod mapy bitowej. Upewnij się, że obraz jest na tyle prosty, że można go wyświetlić na naszym ekranie LCD, sprawdź podgląd, zanim spróbujesz na ekranie LCD. W naszym programie użyliśmy dwóch znaków bitmapowych, jeden to statek kosmiczny, a drugi to statek wroga, kod bitmapowy dla obu jest dodawany do naszego kodu, jak pokazano poniżej.
// Dane bitmapowe dla SpaceShip static const unsigned char PROGMEM ship = { B00000000, B00000000, B00000001, B00000000, B00000011, B10000000, B00000010, B10000000, B00000010, B11000000, B00000111, B11000000, B0011001000, B11001100, B11001000, B11001000, B11001100 B01111111, B11111100, B01111111, B11111100, B01111111, B11111100, B00011111, B11110000, B00000111, B11100000, B00000000, B00000000, }; // Dane bitmapowe dla wroga static const unsigned char PROGMEM wrogowie = { B00000101, B11000000, B00001011, B11100000, B00000011, B11100000, B00110011, B11111000, B01111111, B11111100, B10111111, B11111010, B01110111, B11011100, B01111110, B11111100, B00111111, B11111100, B11101111, B11101110, B11000001, B00000110, B01111110, B11111100, B00111111, B11111100, B11101111, B11101110, B11000001, B00000110, B10000001, B000000, B000000, B1000000, B100000000 ;
Musimy określić piny, do których podłączony jest wyświetlacz Nokia LCD 5110. Komunikacja z wyświetlaczem odbywa się za pomocą komunikacji SPI, jeśli postępowałeś zgodnie ze schematem obwodu powyżej, kod do inicjalizacji LCD będzie wyglądał następująco, nie musisz go zmieniać.
Wyświetlacz Adafruit_PCD8544 = Adafruit_PCD8544 (7, 6, 5, 4, 3); // Określ styki, do których podłączony jest wyświetlacz LCD
W funkcji konfiguracji po prostu uruchamiamy monitor szeregowy z szybkością 9600 bodów, abyśmy mogli debugować rzeczy, a następnie inicjalizować wyświetlacz LCD. Musimy też ustawić kontrast wyświetlacza LCD, każdy wyświetlacz będzie działał najlepiej na innym poziomie kontrastu, więc pobaw się wartością, aby sprawdzić, która najbardziej Ci odpowiada. Na koniec usuwamy również ekran wyświetlacza, aby zacząć od nowa.
void setup () { Serial.begin (9600); // Monitor szeregowy do debugowania display.begin (); // Rozpocznij wyświetlanie komunikacji LCD.setContrast (30); // Ustaw kontrast wyświetlacza display.clearDisplay (); // czyści ekran i rozpoczyna nowy }
Po wyczyszczeniu ekranu wskakujemy do funkcji pętli i tam wyświetlamy ekran gry. Ekran gry to nic innego, jak wyświetla podstawowy szkielet gry wraz z wynikiem i poziomem prędkości. Użyliśmy funkcji linii, aby narysować trzy linie jako granice, a po prawej stronie wyświetlamy wynik tekstu i prędkość, tak jak w starych ręcznych urządzeniach do gier retro.
void gamescreen () { // narysuj ramkę ekranu display.drawLine (0, 0, 0, 47, BLACK); display.drawLine (50, 0, 50, 47, CZARNY); display.drawLine (0, 47, 50, 47, CZARNY); // Wprowadź domyślne teksty display.setTextSize (1); display.setTextColor (CZARNY); display.setCursor (52,2); display.println ("Prędkość"); display.setCursor (54,12); display.println (prędkość_gry); display.setCursor (52,25); display.println ("Wynik"); display.setCursor (54,35); display.println (wynik); }
Następnie musimy uzyskać dane wejściowe od użytkownika, aby umożliwić mu sterowanie statkiem kosmicznym. Sygnał wejściowy zostanie odebrany z modułu Joystick, który jest podłączony do styku A1. Wartość analogowa z czujnika wyniesie 512, jeśli nie zostanie przesunięty, i będzie rosnąć i maleć podczas przesuwania wzdłuż osi X. Używamy tych wartości do określenia, czy użytkownik chce przejść w lewo czy w prawo. Jeśli masz trudności ze zrozumieniem poniższego programu, powinieneś przeczytać poradnik dotyczący joysticka, który łączy się z Arduino, o którym mowa w wymaganiach wstępnych.
// Pobierz dane wejściowe od użytkownika Joy_X = analogRead (A1); // Odczytaj wartość X z Joysticka if (Joy_X <312 && POS! = 1 && control == true) // Jeśli joystick porusza się w prawo {POS--; control = false;} // Zmniejsz pozycję statku kosmicznego else if (Joy_X> 712 && POS! = 3 && control == true) // Jeśli joystick porusza się w prawo {POS ++; control = false;} // Zwiększ pozycję statku kosmicznego else if (Joy_X> 502 && Joy_X <522) // Jeśli joystick z powrotem do pozycji początkowej control = true; // Przygotuj do następnego ruchu // Dane wejściowe otrzymane od użytkownika
Po uzyskaniu od użytkownika pozycji statku kosmicznego musimy ustawić statek kosmiczny w tym konkretnym miejscu. Używamy poniższej funkcji i przekazujemy wartość pozycji jako parametr, a następnie w oparciu o pozycję, w której statek kosmiczny jest umieszczony na odpowiednim torze.
void player_car (char pos) // Umieść statek kosmiczny na podstawie wybranej przez użytkownika pozycji { if (pos == 1) display.drawBitmap (2, 32, ship, 15, 15, BLACK); if (pos == 2) display.drawBitmap (18, 32, statek, 15, 15, CZARNY); if (pos == 3) display.drawBitmap (34, 32, statek, 15, 15, CZARNY); }
Teraz, gdy nasz statek kosmiczny jest umieszczony na ekranie i jest gotowy do wyścigów, musimy przedstawić wrogie statki, które będą rywalizować wraz z graczem. Za każdym razem, gdy statek wroga przechodzi przez ekran, zakładamy, że nie żyje, a kiedy jest martwy, musimy stworzyć nowy statek kosmiczny. Poniższa funkcja robi to samo. Tworzy nową pozycję dla dwóch wrogich statków i umieszcza je u góry ekranu.
if (invalid_dead) // Sprawdzenie, czy statki wroga są martwe {// Jeśli są martwe wrogiepos = POS; // stwórz pierwszego wroga nad statkiem kosmicznym wroga_1_pos = random (0,4); // stwórz drugiego wroga w innym losowym miejscu wrogie_fazy = 0; // Doprowadź wroga z góry z góry przeciwnik_dead = false; // Wróg jest tworzony, więc nie jest już martwy }
Po umieszczeniu wrogich statków na górze ekranu musimy go sprowadzić w dół tak, aby włócznie jakby nasz gracz ścigał się w górę, w tym celu wystarczy zwiększyć fazę (miejsce, w którym wyświetlany jest obraz) tak, aby schodzi powoli. To samo dotyczy obu statków wroga, jak pokazano poniżej
wrogie_ statki (wrogiepos, faza_ wroga); nieprzyjacielska faza ++; // Umieść pierwszego wroga na ekranie i zepchnij go na wroga unknown_phase ++; // Umieść drugiego wroga na ekranie i pokonaj go
Poniżej przedstawiono funkcję wrogiego okrętu , bardzo podobną do funkcji samochodu gracza, ale mamy tu dwa parametry. Jedna służy do umieszczania wroga na torze, a druga do przesuwania wroga w dół.
void disease_ship (int place, int phase) // Umieść wrogi_ship w nowym miejscu i fazie { if (place == 1) display.drawBitmap (2, phase, nieprzyjaciel, 15, 15, BLACK); if (miejsce == 2) display.drawBitmap (18, faza, wróg, 15, 15, CZARNY); if (miejsce == 3) display.drawBitmap (34, faza, wróg, 15, 15, CZARNY); }
Następny fragment kodu powinien sprawdzić, czy statek kosmiczny ominął statek wroga. Aby to sprawdzić, musimy znać pozycję statków wroga i statku kosmicznego gracza. Ponieważ wiemy wszystko, musimy tylko sprawdzić, czy pozycja statku kosmicznego jest taka sama, jak statek wroga. Sprawdzamy to tylko wtedy, gdy wrogi statek zbliżył się do statku kosmicznego. Jeśli gracz nie uniknął wroga, oznacza to koniec gry.
if (wrogie_fazy> 22 && ((wrogiepos == POS) - (wrogie_pos == POS))) // Jeśli statek kosmiczny dotknie któregoś z wrogów game_over (); // Wyświetl koniec gry
Jeśli gracz skutecznie uniknął wroga, powinniśmy go zabić i dać graczowi punkt. Aby to zrobić, po prostu sprawdzamy, czy wróg dotarł do dołu ekranu, a jeśli tak, zabijamy go za pomocą poniższego kodu
if (failure_phase> 40) // Jeśli kosmiczny statek ucieknie wrogom {wrog_dead = true; score ++;} // Zwiększ wynik i zabij wrogów
Cóż by to było za zabawne, gdybyśmy nie zwiększali trudności gry w miarę zdobywania wysokich wyników. Używamy więc innej funkcji, która następnie monitoruje wynik gracza i na podstawie wyniku zwiększa szybkość gry. Szybkość jest faktycznie kontrolowana za pomocą funkcji opóźnienia, która kontroluje interwał odświeżania gry, dzięki czemu gra jest szybka lub wolna.
void Level_Controller () // Zwiększa prędkość gry w oparciu o wynik. { if (score> = 0 && score <= 10) // Jeśli wynik 0-10 { game_speed = 0; opóźnienie (80); // spowolnij grę o 80 ms } if (score> 10 && score <= 20) // If score 10-40 { game_speed = 1; opóźnienie (70); // spowolnij grę o 70 ms } if (score> 20 && score <= 30) // If score 20-40 { game_speed = 2; opóźnienie (60); // spowolnij grę o 60 ms } if (score> 30 && score <= 40) // If score 30-40 { game_speed = 3; opóźnienie (50); // spowolnij grę o 50 ms } }
Działanie gry Arduino Space Racer:
Po upewnieniu się, że sprzęt i program są zrozumiałe, wystarczy zbudować obwód i przesłać kod na płytkę Arduino. Powinieneś zauważyć, że zaczyna się gra, jak pokazano poniżej
Użyj joysticka, aby uciec z wrogiego statku, poruszając się w lewo lub w prawo. Za unikanie każdego wroga otrzymasz jeden wynik zwiększony. Gdy wynik jest wysoki, szybkość gry również rośnie, to znaczy prędkość wzrasta o 10 ms za każde zdobyte 10 punktów. Możesz przejść dalej i rozbudować tę grę, aby wprowadzić nowe poziomy lub wprowadzić zmiany sprzętowe, aby sterować nią za pomocą ruchu za pomocą akcelerometru. Kreatywność to jedyne ograniczenie. W celach informacyjnych nauczysz się używać akcelerometru z Arduino tutaj.
Mam nadzieję, że rozumiesz projekt i cieszysz się jego budowaniem. Jeśli napotkałeś jakiś problem, aby to zadziałało, możesz opublikować problem w sekcji komentarzy poniżej lub skorzystać z forów, aby uzyskać pomoc techniczną. Miłego grania !!
Sprawdź pełny kod i film demonstracyjny poniżej.