Dziś przestudiujemy wnętrze gry Tetris napisanej pod platformą arduino i matryca LED.
Autorem tego domowego produktu jest AlexGyver, autor kanału YouTube o tej samej nazwie. Witamy w cudownym świecie kwadratowych pikseli.
Zacznijmy od historii. Tetris to gra, w której liczby składające się z 4 kwadratów spadają z góry na dół. W różnych kombinacjach kształty te można obracać i przesuwać w lewo i prawo. Celem gry jest zbieranie poziomych poziomów, które są usuwane, a punkty są przyznawane. Przegrana jest uważana za moment, w którym nowa figurka nie ma gdzie upaść. Tetris został wynaleziony przez radzieckiego programistę Aleksieja Leonidowicza Pażitnova.
Oryginalna wersja Pascal pojawiła się 6 czerwca 1984 r. Od tego czasu Tetris przeszedł długą drogę i został przeniesiony na wszystkie platformy, na których ogólnie można grać, a także na urządzenia nieprzeznaczone do gier, takie jak kalkulator techniczny, oscyloskop i, nie uwierzysz, lutownica.
Pod względem liczby sprzedanych wersji komercyjnych Tetris przewyższa każdą inną grę w historii ludzkości. Tylko dla jednego Game Boya sprzedano 35 milionów egzemplarzy, nie wspominając już o przenośnej Brick Game, którą prawie wszystkie miały jednocześnie.
Rozpoczniemy wdrażanie tetris na arduino i matrycy kolorów z analizą „kul”. Matryca składa się z trójkolorowych diod adresowych. Problem z tego typu matrycą polega na tym, że jest zbyt fajny. Kolor każdego piksela jest kodowany za pomocą 24 bitów, czyli 8 bitów na każdy komponent: czerwony, zielony i niebieski. Nie ma tego typu danych na arduino, są następujące - 32 bity.
Kolory wszystkich diod LED powinny być przechowywane w pamięci RAM, ponieważ je zmienimy. Ponadto, dla matrycy 16 na 16 mamy dokładnie 1 KB zajętej pamięci dynamicznej, a arduino nano ma tylko 2 z nich.
Dodaj jeszcze kilka bibliotek i zacznij pisać kod, pamięć się skończy. Autor w zasadzie nie używa na przykład arduino mega, gdzie jest więcej pamięci. Celem jest stworzenie gry na arduino nano przy użyciu prostych, standardowych i dobrze znanych narzędzi, ale jednocześnie niestandardowych podejść i „kul”, a przy ich pomocy osiągnięcie najbardziej optymalnego kodu.
Pierwszą „kulą” będzie odmowa osobnego przechowywania w pamięci pozycji postaci i ogólnie wszystkiego, co dzieje się na ekranie.Musimy przechowywać współrzędne punktów karmienia i współrzędne punktów już upuszczonych figur, to znaczy, że potrzebujemy maksymalnie 1 kolejnej, dwuwymiarowej 16 na 16, a to aż 256 bajtów.
Ty i ja mamy już zestaw kolorów dla wszystkich pikseli, użyjmy go. Rzeczywiście, oprócz faktu, że możemy umieścić kolorową kropkę na matrycy, możemy zmierzyć światło istniejącego punktu, abyśmy mogli pracować z kolorami.
Tetris zaczyna się od spadającego bloku, który jest kontrolowany za pomocą przycisków i ma 2 współrzędne w układzie współrzędnych macierzy. To bardzo proste, budujemy zegar, zgodnie z którym blok spadnie. To jest biblioteka autora, którą możesz przeczytać na stronie.
Do przetwarzania przycisków autor używa również swojej biblioteki. Schemat połączeń przycisków jest absurdalnie prosty: 4 przyciski, 8 przewodów.
Na każdym kroku timera narysujemy punkt o jeden piksel poniżej starego i narysujemy stary punkt na czarno, czyli zgasimy diodę LED. Klikając przycisk, robimy to samo, ale ze współrzędną poziomą. Cóż, dla przyzwoitości ograniczymy rozmiar matrycy, aby punkt nie wykraczał poza pole.
Widzisz, nic skomplikowanego. Ale to nie trwa długo, ponieważ nadszedł czas na rysowanie liczb. Będziemy pracować w następujący sposób: zachowamy odniesienie do punktu zaopatrzenia, który już napisaliśmy, nazwiemy go punktem głównym lub blokiem głównym. Główny blok porusza się w układzie współrzędnych macierzy, już to zrobiliśmy. Wszystkie liczby Tetris składają się z 4 bloków, dlatego, nawiasem mówiąc, nazywa się Tetris.
W związku z tym pozostaje nam zakończyć dodawanie 3 kolejnych bloków do bloku głównego. Napiszmy ich współrzędne w układzie współrzędnych bloku głównego, tak aby blok główny był zawsze poniżej. To bardzo proste, weź postać odwróconej litery T. Główny blok od dołu do środka ma współrzędne 0,0 w układzie współrzędnych.
Górny blok to 0,1, prawy to 1,1, a lewy to -1,1.
Weź literę G. Dolny blok to 0.0, następny 0.1, następny 0.2 i krawędź litery 1.2.
Zapisujemy te współrzędne do tablicy w następującej formie: {0,1, 0,2, 1,2} i upuszczamy tablicę do pamięci flash, aby nie marnować pamięci dynamicznej. Co do rotacji liczb. Nie można obracać figur. To jest banalne, bardzo trudno jest wytłumaczyć mikrokontrolerowi, jak to zrobić. Aby to zrobić, musisz ustawić środek obrotu, jakoś rozłożyć figurę na części i poszukać nowych współrzędnych dla każdej części, biorąc pod uwagę silną pikselizację, co oczywiście doprowadzi do błędów i okaże się nonsens. Problem został rozwiązany bardzo prosto, zachowamy w pamięci wszystkie 4 pozycje dla wszystkich liczb i wszystkich.
Właściwie teraz pozostaje losowo wybrać liczbę figurek i narysować ją wokół spadającego bloku. Tutaj, dla wszystkich 3 pozostałych bloków, bierzemy współrzędne z pamięci flash, tłumaczymy je na globalne współrzędne macierzy i włączamy diody LED. Nawiasem mówiąc, kolor jest również wybierany losowo spośród 6 najprostszych i najjaśniejszych kolorów przestrzeni rgb. Kąt obrotu figury na początku rundy jest również ustawiany losowo, a kiedy naciśniesz przycisk w górę, po prostu weź następny zestaw współrzędnych, aby narysować i obrócić go zgodnie z ruchem wskazówek zegara. Przenoszenie kształtu działa tak samo. Najpierw usuwamy figurę w poprzedniej pozycji, czyli narysujemy ją na czarno, a następnie w nowej pozycji narysujemy aktualny kolor figury. Podczas skrętu ponownie usuwamy starą pozycję i po prostu rysujemy nową.
Oprogramowanie układowe można pobrać pod adresem. Przeanalizujemy tylko esencję. Zacznijmy od sprawdzenia lewej i prawej ściany oraz dołu. Wszystko jest bardzo proste z dnem, patrzymy na każdy krok upadku, czy podstawa osiągnęła wysokość 0, nie jest to trudne, ale za każdym razem, gdy naciskamy przycisk sterowania, musimy sprawdzić, czy skrajny punkt figury dotknął bocznych ścian matrycy.
W przypadku dotknięcia nie poruszaj figurką. To samo dotyczy rotacji liczb. Na przykład, jeśli nowe położenie figury wykracza poza ściany, wówczas obrót jest zabroniony, a ponieważ wszystkie figurki, które mamy, mają różne kształty, skrajne bloki są różne. Możliwe byłoby pomalowanie poszczególnych skrajnych bloków dla każdej figury, aby uprościć pracę mikrokontrolera, ale należy wziąć pod uwagę, że wymyślili go do tego.
Wszystko jest bardzo proste. Ale następne zadanie jest o wiele bardziej interesujące. Musimy sprawdzić kolizje z blokami już leżącymi poniżej.Gdybyśmy mieli tablicę zawierającą stan wszystkich komórek w polu, byłoby to łatwiejsze, ale użyjemy tablicy kolorów dla pikseli taśmy, dzięki czemu będziemy mieli najfajniejszą „kulę”. Jaki jest rzeczywisty problem? Wszystko wydaje się proste, zielona figurka spadnie i powinniśmy sprawdzać każdy krok upadku, każdą zmianę w bok i każdą próbę obrócenia, czy figurka w nowej pozycji spoczywa na już leżących figurach. Jeśli dla wszystkich bloków otaczający kolor jest równy czerni lub jest równy kolorowi figury, wówczas pozwalamy na ruch w pożądanym kierunku. Będzie to działać, dopóki kształt pod nami nie będzie tego samego koloru co kształt opadający. To właściwie „kula”: odmalujemy upadły kształt na inny kolor. Odbarwia niezauważalnie dla oczu, ale jest zauważalny dla programu. Wystarczy nieznacznie zwiększyć jasność bieżącego koloru kształtu i to wszystko.
Postać spadła na spód lub inną figurę, jej jasność nie wzrosła zauważalnie, a w nowej rundzie spadające postacie nie będą już mylić swojego koloru z własnym, spadną na nią i tak samo ustalone, lekko zwiększając jasność.
Nawiasem mówiąc, gdy naciśniesz przycisk, postać pędzi z dużą prędkością i zajmuje swoje miejsce.
Nasze Tetris pozostawia ostatni szlif, mianowicie kontrolę i czyszczenie poziomych poziomów. Tutaj wszystko jest proste. Po ustaleniu figury w bieżącej rundzie poruszamy się wzdłuż linii i porównujemy kolory pikseli z czernią. Jeśli nie ma jednego czarnego piksela w całej linii, wyczyścimy całą linię.
Wykryte linie są wypełnione białym, następnie jasność stopniowo spada do zera i uzyskuje się animację. Ponadto wszystkie piksele, zaczynając od pierwszej wypełnionej linii do góry, są przesuwane w dół o liczbę linii, które zostały usunięte. Ten proces powtarza się, dopóki nie zostaną ukończone poziomy. Sprawdzamy również, czy osiągnęliśmy szczyt, co oznacza przegraną. W takim przypadku wyświetlane jest konto równe liczbie wyczyszczonych poziomów.
Konto jest wyświetlane w liczbach, które są przechowywane w pamięci jako zestaw zer i jedynek, za pomocą których diody LED są następnie włączane lub wyłączane. Tak wygląda Tetris zapisany w macierzy adresów. Dziękuję za uwagę. Do zobaczenia wkrótce!
Wideo: