Spisu treści:

Arduino - Piano Tiles: 16 kroków (ze zdjęciami)
Arduino - Piano Tiles: 16 kroków (ze zdjęciami)

Wideo: Arduino - Piano Tiles: 16 kroków (ze zdjęciami)

Wideo: Arduino - Piano Tiles: 16 kroków (ze zdjęciami)
Wideo: 35 przerażających filmów o duchach: mega kompilacja z 2023 r. [V1] 2024, Lipiec
Anonim
Arduino - płytki fortepianowe
Arduino - płytki fortepianowe

Witajcie internetowi, to będzie o tym, jak zrobić coś, co ZDECYDOWANIE nie jest zdzierstwem z gry mobilnej na arduino uno r3.

więc na początek będziesz potrzebować wszystkich części, które są następujące! 1x Arduino Uno r3 (42 USD)

2x osłona klawiatury LCD (19 USD za sztukę)

5x przyciski

Rezystory 5x 220Ω

28x przewody

W porządku, gdy masz już wszystkie części, czas zacząć!

Krok 1: Okablowanie

Okablowanie
Okablowanie
Okablowanie
Okablowanie
Okablowanie
Okablowanie

Zacznij od podłączenia arduino i znajomych, jak pokazano na schemacie, Upewnij się, że przyciski są połączone we właściwy sposób, z gniazdami A0-4 na dolnej stronie szyny przycisków, w przeciwnym razie arduino pomyśli, że przyciski są przytrzymywane stale, a nie tylko po naciśnięciu.

Krok 2: Oświadczenia deklaracji

Cały kod powinien być umieszczony przed void setup i void loop, ponieważ wszystkie te zmienne i obiekty są używane w kilku funkcjach, które skonfigurujemy.

Zacznij od wstawienia:

#włączać

na górze twojego kodu mówi arduino, aby używał biblioteki "LiquidCrystal.h" i funkcji, które są jej częścią.

Następnym krokiem jest zdefiniowanie pinów, których używamy dla naszych przycisków, umieszczając ten kod poniżej naszego #include:

#definiuj btnEnter A0#definiuj btn1 15 #definiuj btn2 16 #definiuj btn3 17 #definiuj btn4 18

Definiujemy terminy btnEnter i btn1 do btn 4, aby kod był dla nas łatwiejszy do odczytania lub zmiany w razie potrzeby. Oznacza to, że gdy wpiszemy btn1, arduino będzie wiedziało, że w rzeczywistości mamy na myśli przycisk 15. Chociaż wywołujemy porty 15, 16, 17 i 18, są one oznaczone na arduino jako A1 A2 A3 i A4, ponieważ są to porty używane specjalnie dla wejść analogowych, chociaż używamy ich tylko dla wejść cyfrowych.

Następnie stworzymy obiekty, które będą sterować wyświetlaczami ciekłokrystalicznymi. Aby to zrobić, umieść ten kod poniżej naszych definicji

LiquidCrystal lcdLeft (8, 9, 12, 10, 11, 13);LiquidCrystal lcdRight(2, 3, 4, 5, 6, 7);

To, co to robi, mówi arduino, że kiedy wywołujemy lcdLeft lub lcdRight, odwołujemy się do obiektu LiquidCrystal. Liczby w dołączonych nawiasach informują arduino, których portów obiekt powinien używać do wysyłania wiadomości na wyświetlacz LCD, gdy korzystamy z ich funkcji.

Teraz musimy zadeklarować zmienne, umieszczając kolejny fragment kodu pod deklaracjami obiektów:

//te zmienne to opcje, które możesz zmienić - wyższe liczby = większa szybkość gry upint intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

//ustaw zmienne dla gameboolean bolPlay; //śledzi, czy odtwarzacz int intScore; //śledzi wynik gracza int intDiff; //tylko estetyczna rzecz, aby powiedzieć, na jakim poziomie trudności jest gra //ustaw zmienne wejściowe int intEnter; //śledzi, czy użytkownik naciśnie przycisk enter int intInput; //śledzi, które przyciski naciska użytkownik boolean bolTilePressed; //upewnij się, że gracz nie naciśnie przypadkowo przycisku 5x i nie straci //ustaw zmiennych dla turn int intTick; //zlicza milimetry (na pętlę) aż do intDelay int intDelay; //czas oczekiwania programu do następnej tury w milis int intGameSpeed; //abit opcji debugowania boolean bolSerialBoard; //jeśli true wypisze płytę na monitorze szeregowym

Zmienną deklarujemy podając typ danych, a następnie nazwę zmiennej, np. int thisIsAnInteger

Zmienne logiczne, takie jak bolSerialBoard i bolPlay, mogą mieć tylko jedną z dwóch wartości, true lub false.

Zmienna całkowita (int), taka jak intScore i intInput, może przyjmować liczby całkowite jako wartości, takie jak 1, 5 lub 100.

Niektóre inne godne uwagi typy danych, których tutaj nie używamy, to ciąg znaków, który jest fragmentem tekstu, oraz zmiennoprzecinkowa, która jest liczbą dziesiętną.

Każda ze zmiennych tutaj jest używana w kilku różnych miejscach przez program, oto streszczenie tego, co robi każda z nich

bolPlay mówi programowi, czy menu powinno być wyświetlone, czy też właściwa gra powinna być uruchomiona.

intScore śledzi wynik gracza, który uderza w płytki, intDiff jest używany w menu głównym, aby poinformować program, jaki fragment tekstu ma zostać wydrukowany na wyświetlaczu LCD, intEnter służy do poinformowania programu, czy naciśnięto przycisk enter (najbardziej po lewej), intInput służy do poinformowania programu, który z pozostałych 4 przycisków został naciśnięty.

bolTilePressed służy do upewnienia się, że program odczytuje tylko po naciśnięciu przycisku, a nie po jego przytrzymaniu.

intGameSpeed, intGameSpeedEasy, intGameSpeedMedium i intGameSpeedHard służą do kontrolowania, jak szybko gra powinna przyspieszyć w zależności od wybranego poziomu trudności.

intTick i intDelay służą do zatrzymania programu przed przesuwaniem planszy za każdym razem, gdy wykonuje pętlę.

bolSerialBoard służy do umożliwienia programowi wysłania płytki do monitora szeregowego arduino jako serii liczb w celach testowych.

Wreszcie nadszedł czas, aby zadeklarować naszą tablicę jako tablicę za pomocą tego kodu:

// skonfiguruj grę arrayint arrGame[16][4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} };

Tablica to macierz, w której dowolny punkt można wywołać w celu matematyki lub zmienić.

Twój kod powinien teraz wyglądać mniej więcej tak;

// dołącz biblioteki#include

//te zmienne to opcje, które możesz zmienić - wyższe liczby = szybsze przyspieszenie gry

int intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// Zdefiniuj szpilki

#define btnEnter A0 #define btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

// tworzenie obiektów LCD (n, ~, n, ~, ~, n)

LiquidCrystal lcdLeft(8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight(2, 3, 4, 5, 6, 7);

// skonfiguruj tablicę gier

int arrGame[16][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} };

//ustaw zmienne do gry

boole'owskie bolPlay; //śledzi, czy odtwarzacz int intScore; //śledzi wynik gracza int intDiff; //tylko estetyczna rzecz, aby powiedzieć, na jakim poziomie trudności jest gra

//ustaw zmienne dla danych wejściowych

int intEnter; //śledzi, czy użytkownik naciśnie przycisk enter int intInput; //śledzi, które przyciski naciska użytkownik boolean bolTilePressed; //upewnij się, że gracz nie naciśnie przypadkowo przycisku 5 razy i nie przegra

//ustaw zmienne dla turn

int intZaznacz; //zlicza milimetry (na pętlę) aż do intDelay int intDelay; //czas oczekiwania programu do następnej tury w milis int intGameSpeed;

//trochę opcji debugowania

boolean bolSerial Board; //jeśli true wypisze płytę na monitorze szeregowym

Krok 3: Funkcja konfiguracji

Pętla konfiguracji to funkcja odczytywana przez arduino tylko raz, gdy się uruchamia.

W pętli konfiguracji po prostu ustawiamy wartości kilku naszych zmiennych, ponieważ zamiast ustawiać im wartość podczas deklarowania, robimy to tutaj.

Zacznij od umieszczenia tego kodu w konfiguracji pustki.

bolPlay = false;intScore = 0; intTick = 0; wewnOpóźnienie = 1000; intRóż = 1; intGameSpeed = intGameSpeedMedium;

Każda linia po prostu ustawia zmienną na wartość.

bolPlay jest ustawiony na false, aby gra nie rozpoczęła się.

intScore jest ustawione na 0, ponieważ naturalnie Twój wynik zaczyna się od 0.

intTick zaczyna się od 0, ponieważ program aktualnie nic nie liczy.

intDelay jest ustawione na 1000, ponieważ jest to szybkość, z jaką rozpoczynają się kafelki.

intDiff jest po prostu ascetyczną rzeczą, aby program wiedział, co napisać dla trudności gry.

intGameSpeed jest ustawiony na dowolny intGameSpeedMedium, co oznacza, że jest ustawiony na średni poziom trudności.

Następnie umieść ten kod w konfiguracji Void pod kodem, który właśnie wstawiłeś.

lcdLeft.begin(16, 2);lcdRight.begin(16, 2);

Serial.początek(9600);

To każe arduino rozpocząć komunikację z komputerem przez monitor szeregowy (widoczny po kliknięciu przycisku w prawym górnym rogu arduino IDE).

Twoja konfiguracja Pustki powinna teraz wyglądać mniej więcej tak!

void setup() { Serial.begin(9600); //uruchom monitor szeregowy //ustaw zmienne bolPlay = false; intScore = 0; intTick = 0; wewnOpóźnienie = 1000; intRóż = 1; intGameSpeed = intGameSpeedMedium; //rozpocznij lcdLeft.begin(16, 2); lcdPrawo.początek(16, 2); }

Krok 4: Funkcja pętli

Funkcja pętli jest uruchamiana przez arduino w każdej iteracji arduino.

Skopiuj następujący kod do swojej pętli pustki.

void loop() { input(); //sprawdź odtwarzanie danych wejściowych if (bolPlay == true){ if (intTick >= intDelay){ //sprawdź, czy gra powinna zagrać turę lub kontynuować oczekiwanie Serial.println("~~~~~~~ ~~");//print oznaczający ruch tablicy //writeSerial(); //jeśli opcja jest włączona zapisz planszę do portu szeregowego buttonsGame(); //sprawdź wejścia gracza playBoard(); //przesuń planszę i dodaj nowy kafelek clearLcd(); //wyczyść wyświetlacze LCD przed rysowaniem DrawBoard(); //narysuj planszę na bottomCheck(); intTick = 0; //resetuj intTick } else { buttonsGame(); //sprawdź wejścia odtwarzacza clearLcd(); //wyczyść wyświetlacze LCD przed rysowaniem DrawBoard(); //narysuj planszę na lcd intTick = intTick + intGameSpeed; //dodaj do zaznaczenia } } else { clearLcd(); //wyczyść wyświetlacze LCD przed narysowaniem title(); //wyświetlanie tytułu i informacji o wyniku buttonMenu(); //odczytaj wejście odtwarzacza clearBoard(); //upewnij się, że cała tablica = 0 } delay(10); //opóźnij arduino o krótką chwilę }

gdy bolPlay jest równe true oznacza to, że gra jest w toku, a cały kod do czasu, w którym gra się toczy, powinien zostać uruchomiony, ale chcemy tylko, aby plansza dodała nowy kafelek i przesunęła się w dół, gdy intTick jest większy niż nasz intDelay, w przeciwnym razie nadal chcemy, aby użytkownik mógł nacisnąć przycisk, aby uderzyć w kafelek i aby intTick zwiększył prędkość.

Większość tego kodu korzysta z funkcji, których jeszcze nie stworzyliśmy i zrobimy je w następnych krokach. Cel tych funkcji jest następujący.

Wejście odczytuje, które przyciski nacisnął użytkownik.

buttonsGame steruje działaniem przycisków w grze, a nie w menu

playBoard dodaje nowy kafelek do planszy, a następnie przesuwa wszystko na planszy o jedno miejsce w dół

clearLCD czyści wyświetlacze LCD, aby upewnić się, że za płytkami nie pozostały żadne duchy

DrawBoard przechodzi przez arrGame i drukuje go na wyświetlaczach LCD

clearBoard czyści całą arrGame, gdy gra nie jest w grze

bottomCheck sprawdza dno arrGame pod kątem awarii

title wyświetla tytuł gry i informacje o wyniku w menu

menu przycisków steruje czynnościami wprowadzonymi przez użytkownika w menu.

gameOver to kolejna funkcja, chociaż nie jest tutaj wywoływana, ponieważ jest wywoływana w funkcjach bottomCheck i buttonsGame.

Krok 5: Funkcja ClearLCD

tworzenie funkcji zaczynamy od dodania tego do kodu

void nazwa funkcji () {

}

"functionName" może być dowolne, o ile jeszcze nie istnieje.

Skopiuj ten kod do swojego programu:

void clearLcd() { for (int i = 0; i <= 15; i++){ for (int ii = 0; ii <= 1; ii++){ lcdLeft.setCursor(i, ii); lcdLeft.write(" "); lcdRight.setCursor(i, ii); lcdRight.write(" "); } } }

przebiega to przez całą tablicę za pomocą 2 zliczonych pętli, aby przejść przez każdy punkt na wyświetlaczach LCD i zapisać spację.

Bez resetowania do niczego wyświetlacze LCD zachowają to, co zostało napisane wcześniej

Krok 6: Funkcja DrawBoard

skopiuj ten kod do swojego programu

void drawBoard() { for (int i = 1; i <= 15; i++){ //narysuj kolumny 1 i 2 na lewym LCD //jeśli kafelek = 0 nic nie napisz, = 1 napisz "#", = 2 napisz "@" lcdLeft.setCursor(i, 1); //ustaw na pierwszą kolumnę (najdalej po lewej) if (arrGame[0] == 1) {lcdLeft.write("#");} if (arrGame[0] == 2) {lcdLeft.write("@");} lcdLeft.setCursor(i, 0); //ustaw na drugą kolumnę (w środku po lewej) if (arrGame[1] == 1) {lcdLeft.write("#");} if (arrGame[1] == 2) {lcdLeft.write("@");} lcdRight.setCursor(i, 1); //ustaw na trzecią kolumnę (w środku po prawej) if (arrGame[2] == 1) {lcdRight.write("#");} if (arrGame[2] == 2) {lcdRight.write("@");} lcdRight.setCursor(i, 0); //ustaw na czwartą kolumnę (najbardziej po prawej) if (arrGame[3] == 1) {lcdRight.write("#");} if (arrGame[3] == 2) {lcdRight.pisać("@");} } }

wykorzystuje pętlę do przejścia przez każdy wiersz planszy, a następnie sprawdza, czy jakakolwiek kolumna w rzędzie jest równa 1 lub 2, na tej podstawie drukuje na wyświetlaczu LCD albo hashtag, aby kafelek jeszcze nie był hit lub @ dla płytki trafienia.

Krok 7: Funkcja PlayBoard

skopiuj ten kod do swojego programu.

void playBoard() { for (int i = 0; i <= 3; i++){arrGame[0] = 0;} //wyczyść górny wiersz arrGame[0][random(0, 4)] = 1; //ustaw losowy punkt w górnym rzędzie jako kafelek for (int i = 15; i>= 1; i--){ //pracując od dołu planszy do góry for (int ii = 0; ii <= 3; ii ++){ //dla każdego zbioru przypGry[ii] = przypGry[i - 1][ii]; } } }

ten kod zaczyna się od wyczyszczenia całego górnego rzędu do 0 lub braku płytki, a następnie ustawia jedną losową płytkę na 1 i nietrafioną płytkę.

Następnie przechodzi przez zliczoną pętlę w odwrotnej kolejności, od 15 do 1, ustawiając rząd tak, aby był równy dowolnemu rzędowi nad nim, co powoduje, że płyta przesuwa się w dół wyświetlacza LCD

Krok 8: Funkcja ClearBoard

skopiuj ten kod do swojego programu.

void clearBoard() { //resetuj wartości tików i opóźnień intTick = 0; wewnOpóźnienie = 1000; //przejrzyj planszę i ustaw wszystko na 0 for (int i = 0; i <= 15; i++){ for (int ii = 0; ii <= 3; ii++){ arrGame[ii] = 0; } } }

Ten kod jest uruchamiany, gdy gra nie jest odtwarzana, aby upewnić się, że cała arrGame jest ustawiona na 0 lub nie ma kafelków, używając zliczonych pętli do przejścia przez tablicę.

Kod resetuje również wartości intDelay i intTick.

Krok 9: Funkcja tytułu

skopiuj następujący kod do swojego programu

void title() { //zapisz tytuł na LCD i spację na wynik lcdRight.setCursor(0, 0); lcdRight.write("Płytki fortepianowe"); lcdRight.setCursor(0, 1); lcdRight.write("Wynik: "); //przekonwertuj wynik na łańcuch znaków strScore[3]; sprintf(strScore, "%d", intScore); //wyświetl wynik na LCD lcdRight.write(strScore); //dodaj trudność lcdRight.setCursor(10, 1); if (intDiff == 0){ lcdRight.write("Łatwy"); } if (intDiff == 1){ lcdRight.write("Średni"); } if (intDiff == 2){ lcdRight.write("Twardy"); } //Naciśnij trochę instrukcji lcdLeft.setCursor(0, 0); lcdLeft.write("Naciśnij Enter"); lcdLeft.setCursor(0, 1); lcdLeft.write("na początek!"); }

Ten kod zapisuje tytuł gry i wynik na wyświetlaczach LCD, mówi wyświetlaczowi LCD, gdzie zacząć pisać za pomocą LCD.setCursor, a następnie zapisuje ciąg w LCD.write.

W tym miejscu tworzona jest również nowa zmienna strScore, która służy do konwersji intScore na typ danych typu string lub char za pomocą funkcji sprintf.

IntDiff jest tutaj również używany, na podstawie jego wartości wyświetla różne opcje trudności.

Krok 10: Funkcja menu przycisków

wstaw następujący kod do swojego programu

void buttonsMenu(){ // po naciśnięciu enter uruchom grę i zresetuj wartość wyniku if (intEnter == 1){ bolPlay = true; intScore = 0; Deska do gry(); Tablica Rysunkowa(); } // po naciśnięciu przycisku 3 włącz opcję debugowania drukowania tablicy w trybie szeregowym if (intInput == 3){ if (bolSerialBoard == false){ Serial.println("Płyta szeregowa aktywna"); bolSerialBoard = prawda; } else { Serial.println("Płyta szeregowa wyłączona"); bolSerialBoard = false; } } //ustaw szybkość gry na łatwy if (intInput == 0){ Serial.print("Gra ustawiona na łatwy ("); Serial.print(intGameSpeedEasy); Serial.println("akceleracja ms)"); intRóż = 0; intGameSpeed = intGameSpeedŁatwy; } //ustaw prędkość gry na średni poziom trudności if (intInput == 1){ Serial.print("Gra ustawiona na średnią ("); Serial.print(intGameSpeedMedium); Serial.println("akceleracja ms)"); intRóż = 1; intGameSpeed = intGameSpeedMedium; } //ustaw szybkość gry na wysoki poziom trudności if (intInput == 2){ Serial.print("Gra ustawiona na trudną ("); Serial.print(intGameSpeedHard); Serial.println("akceleracja ms)"); intRóż = 2; intGameSpeed = intGameSpeedHard; } }

ten kod jest uruchamiany tylko wtedy, gdy bolPlay ma wartość false w void Loop

jeśli intEnter jest ustawione na 1 oznacza to, że naciśnięto klawisz enter, jeśli jest wciśnięty, program ustawia bolPlay na true i gra się rozpoczyna.

Następnie program odczytuje, co jest równe intInput. jeśli jest równe 0 to wciskany jest pierwszy przycisk od lewej, idąc w prawo aż do 3. Jeśli intInput jest równe 4 żaden przycisk nie jest wciskany.

jeśli naciśniesz przyciski 0-2, gra zmieni poziom trudności, dostosowując również wartość prędkości gry, co oznacza, że będzie przyspieszać szybciej.

po naciśnięciu przycisku 3 gra aktywuje lub dezaktywuje tryb debugowania, w którym cała płyta jest drukowana na monitorze szeregowym, aby pomóc w znalezieniu problemów w programie.

Krok 11: Funkcja ButtonsGame

skopiuj następujący kod do swojego programu

void buttonsGame(){ if (intInput != 4) { //jeżeli przycisk zostanie naciśnięty if (bolTilePressed == false){ //tylko jeżeli bolTilePressed to false akcja wyzwalania w celu sprawdzenia przycisku naciśnij bolTilePressed = true; //następnie ustaw bolTilePressed na true, aby upewnić się, że nie zostanie ponownie wyzwolony acidentilly int intLowestTile = 0; //ustawić na kafelek z najniższym kafelkiem intCheckedTile = 15; //aby śledzić, które kafelki zostały sprawdzone while (intLwestTile == 0) { //o ile nie jest ustawione na nic, sprawdzaj kafelki dla (int i = 0; i 100){ //dopóki int opóźnienie nie mniejsze niż 100 intDelay = intDelay - 20; //weź z niego wartość } } else { Serial.println("Naciśnięto błędny przycisk"); koniec gry(); //w przeciwnym razie koniec gry } } } } }

Kod jest uruchamiany tylko wtedy, gdy bolPlay jest równe true w void Loop.

Podobnie jak buttonsMenu na podstawie wartości intInput sprawdza, czy gracz trafił w kafelek, czy nie.

Robi to, przechodząc przez arrGame od dołu do góry za pomocą pętli while, aby wyszukać, który wiersz jest najniższy za pomocą kafelka unhit. Następnie sprawdza, czy miejsce w tym wierszu odpowiadające wciśniętemu przyciskowi jest płytką nietrafioną, czy nie, jeśli jest nietrafiona, ustawia ją na 2 zamiast 1, co oznacza, że będzie wyświetlana jako @, w przeciwnym razie uruchamia gameOver funkcję, którą mamy jeszcze stworzyć.

Ta funkcja wykorzystuje również zmienną bolTilePressed, ustawiając ją na true po naciśnięciu przycisku i false, gdy żaden przycisk nie zostanie naciśnięty. Ma to na celu zapewnienie, że użytkownik przypadkowo nie straci gry, ponieważ program myślał, że wielokrotnie nacisnął przycisk, gdy go przytrzymał.

Krok 12: Funkcja GameOver

Skopiuj następujący kod do swojego programu

void gameOver() { Serial.println("Koniec gry!"); Serial.print("Twój wynik to: "); Serial.println(intScore); Serial.print("Twoja prędkość wynosiła: "); Serial.println(intDelay); bolPlay = fałsz; }

Jest to wywoływane przez funkcję checkBottom lub buttonsGame i uruchamia koniec gry, ustawiając bolPlay na false.

Drukuje również komunikat na monitorze szeregowym dla wyniku użytkowników, a kafelki szybkości zostały dodane w milisekundach.

Krok 13: Funkcja wprowadzania

Skopiuj następujący kod do swojego programu.

void input() { intEnter = digitalRead(btnEnter); //odczytaj wprowadź //odczytaj które z pozostałych wejść lub jeśli żadne nie jest ustawione na 4 if (digitalRead(btn1) == HIGH){intInput = 0;} else { if (digitalRead(btn2) == HIGH){intInput = 1;} else { if (digitalRead(btn3) == HIGH){intInput = 2;} else { if (digitalRead(btn4) == HIGH){intInput = 3;} else { intInput = 4; }}}} //serial drukuj dane wejściowe if (intEnter == 1){Serial.println("Naciśnięto Enter! ");} if (intInput != 4){ Serial.print("Naciśnięcie przycisku: "); Serial.println(wejście); } else { //jeśli nie zostanie naciśnięty żaden przycisk zresetuj bolTilePressed bolTilePressed = false; } }

Ten kod jest używany z funkcjami buttonGame i buttonsMenu. na podstawie przycisków, które nacisnął użytkownik, ustawia wartość intInput, lub jeśli nie zostanie naciśnięty żaden przycisk, ustawia wartość intInput na 4.

Jeśli nie zostanie naciśnięty żaden przycisk, w tym miejscu bolTilePressed jest resetowany dla funkcji buttonsGame.

Drukuje również komunikat do monitora szeregowego, na którym naciśnięto przycisk.

Krok 14: Funkcja BottomCheck

skopiuj następujący kod do swojego programu.

void bottomCheck() { for (int i = 0; i <= 3; i++){ //dla 4 kolumn if (arrGame[15] == 1){ //jeśli kafelek jest na dole Serial.println("Kafelek na dole"); gra[15] = 2; Tablica Rysunkowa(); opóźnienie(400); ArrGame[15] = 1; Tablica Rysunkowa(); opóźnienie(400); ArrGame[15] = 2; Tablica Rysunkowa(); opóźnienie(400); ArrGame[15] = 1; Tablica Rysunkowa(); opóźnienie(400); koniec gry(); } } }

za pomocą pętli ten kod sprawdza dolny rząd arrGame pod kątem nietrafionych płytek (kafelki równe 1), jeśli na dole ekranu znajduje się nietrafiona płytka, zostanie ona mignięta, a następnie uruchomi funkcję game over.

Krok 15: Funkcja WriteSerial

skopiuj następujący kod do swojego programu

void writeSerial() { if (bolSerialBoard == true){ for (int i = 0; i <= 15; i ++){ for (int ii = 0; ii <= 3; ii++){ Serial.print(arrGame [ii]); Serial.print(", "); } Serial.println(""); } } }

Jest to funkcja, po której następuje opcja debugowania, którą można włączyć w funkcji buttonsMenu. Jeśli bolSerialBoard jest ustawione na true w tej funkcji, przejdzie przez arrGame i wydrukuje całą planszę na monitorze szeregowym w celach testowych za pomocą tablicy.

Krok 16: Zakończenie

Ukończenie!
Ukończenie!

Cały Twój kod nie powinien być kompletny i wyglądać mniej więcej tak!

/* * Nazwa - Płytki fortepianowe; Arduino * Przez - Domenic Marulli * Data - 11/*

/ włącz biblioteki

#włączać

//te zmienne to opcje, które możesz zmienić - wyższe liczby = szybsze przyspieszenie gry

int intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// Zdefiniuj szpilki

#define btnEnter A0 #define btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

// tworzenie obiektów LCD (n, ~, n, ~, ~, n)

LiquidCrystal lcdLeft(8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight(2, 3, 4, 5, 6, 7);

// skonfiguruj tablicę gier

int arrGame[16][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} };

//ustaw zmienne do gry

boole'owskie bolPlay; //śledzi, czy odtwarzacz int intScore; //śledzi wynik gracza int intDiff; //tylko estetyczna rzecz, aby powiedzieć, na jakim poziomie trudności jest gra

//ustaw zmienne dla danych wejściowych

int intEnter; //śledzi, czy użytkownik naciśnie przycisk enter int intInput; //śledzi, które przyciski naciska użytkownik boolean bolTilePressed; //upewnij się, że gracz nie naciśnie przypadkowo przycisku 5 razy i nie przegra

//ustaw zmienne dla turn

int intZaznacz; //zlicza milimetry (na pętlę) aż do intDelay int intDelay; //czas oczekiwania programu do następnej tury w milis int intGameSpeed;

//trochę opcji debugowania

boolean bolSerial Board; //jeśli true wypisze płytę na monitorze szeregowym

//instalator, który zostanie uruchomiony raz

void setup() { Serial.begin(9600); //uruchom monitor szeregowy //ustaw zmienne bolPlay = false; intScore = 0; intTick = 0; wewnOpóźnienie = 1000; intRóż = 1; intGameSpeed = intGameSpeedMedium; //rozpocznij lcdLeft.begin(16, 2); lcdPrawo.początek(16, 2); }

//pętla, która będzie uruchamiana co 10 milisekund

void loop() { input(); //sprawdź odtwarzanie danych wejściowych if (bolPlay == true){ if (intTick >= intDelay){ //sprawdź, czy gra powinna zagrać turę lub kontynuować oczekiwanie Serial.println("~~~~~~~ ~~");//print oznaczający ruch tablicy //writeSerial(); //jeśli opcja jest włączona zapisz planszę do portu szeregowego buttonsGame(); //sprawdź wejścia gracza playBoard(); //przesuń planszę i dodaj nowy kafelek clearLcd(); //wyczyść wyświetlacze LCD przed rysowaniem DrawBoard(); //narysuj planszę na bottomCheck(); intTick = 0; //resetuj intTick } else { buttonsGame(); //sprawdź wejścia odtwarzacza clearLcd(); //wyczyść wyświetlacze LCD przed rysowaniem DrawBoard(); //narysuj planszę na lcd intTick = intTick + intGameSpeed; //dodaj do zaznaczenia } } else { clearLcd(); //wyczyść wyświetlacze LCD przed narysowaniem title(); //wyświetlanie tytułu i informacji o wyniku buttonMenu(); //odczytaj wejście odtwarzacza clearBoard(); //upewnij się, że cała tablica = 0 } delay(10); //opóźnij arduino o krótką chwilę }

//czyści lcd, aby nie zostały tam żadne niewypełnione komórki

void clearLcd() { for (int i = 0; i <= 15; i++){ for (int ii = 0; ii <= 1; ii++){ lcdLeft.setCursor(i, ii); lcdLeft.write(" "); lcdRight.setCursor(i, ii); lcdRight.write(" "); } } }

//rysuje planszę na lcd

void drawBoard() { for (int i = 1; i <= 15; i++){ //narysuj kolumny 1 i 2 na lewym LCD //jeśli kafelek = 0 nic nie napisz, = 1 napisz "#", = 2 napisz "@" lcdLeft.setCursor(i, 1); //ustaw na pierwszą kolumnę (najdalej po lewej) if (arrGame[0] == 1) {lcdLeft.write("#");} if (arrGame[0] == 2) {lcdLeft.write("@");} lcdLeft.setCursor(i, 0); //ustaw na drugą kolumnę (w środku po lewej) if (arrGame[1] == 1) {lcdLeft.write("#");} if (arrGame[1] == 2) {lcdLeft.write("@");} lcdRight.setCursor(i, 1); //ustaw na trzecią kolumnę (w środku po prawej) if (arrGame[2] == 1) {lcdRight.write("#");} if (arrGame[2] == 2) {lcdRight.write("@");} lcdRight.setCursor(i, 0); //ustaw na czwartą kolumnę (najbardziej po prawej) if (arrGame[3] == 1) {lcdRight.write("#");} if (arrGame[3] == 2) {lcdRight.pisać("@");} } }

//przesuwa planszę w dół i umieszcza losową wartość jako kafelek

void playBoard() { for (int i = 0; i <= 3; i++){arrGame[0] = 0;} //wyczyść górny wiersz arrGame[0][random(0, 4)] = 1; //ustaw losowy punkt w górnym rzędzie jako kafelek for (int i = 15; i>= 1; i--){ //pracując od dołu planszy do góry for (int ii = 0; ii <= 3; ii ++){ //dla każdego zbioru przypGry[ii] = przypGry[i - 1][ii]; } } }

//ustawia całą planszę na 0 i resetuje zmienne do stanu sprzed gry

void clearBoard() { //resetuj wartości tików i opóźnień intTick = 0; wewnOpóźnienie = 1000; //przejrzyj planszę i ustaw wszystko na 0 for (int i = 0; i <= 15; i++){ for (int ii = 0; ii <= 3; ii++){ arrGame[ii] = 0; } } }

// wyświetla menu główne na wyświetlaczu LCD

void title() { //zapisz tytuł na LCD i spację na wynik lcdRight.setCursor(0, 0); lcdRight.write("Płytki fortepianowe"); lcdRight.setCursor(0, 1); lcdRight.write("Wynik: "); //przekonwertuj wynik na łańcuch znaków strScore[3]; sprintf(strScore, "%d", intScore); //wyświetl wynik na LCD lcdRight.write(strScore); //dodaj trudność lcdRight.setCursor(10, 1); if (intDiff == 0){ lcdRight.write("Łatwy"); } if (intDiff == 1){ lcdRight.write("Średni"); } if (intDiff == 2){ lcdRight.write("Twardy"); } //Naciśnij trochę instrukcji lcdLeft.setCursor(0, 0); lcdLeft.write("Naciśnij Enter"); lcdLeft.setCursor(0, 1); lcdLeft.write("na początek!"); }

// sprawdza przyciski i co z nimi zrobić poza grą

void buttonsMenu(){ // po naciśnięciu enter uruchom grę i zresetuj wartość wyniku if (intEnter == 1){ bolPlay = true; intScore = 0; Deska do gry(); Tablica Rysunkowa(); } // po naciśnięciu przycisku 3 włącz opcję debugowania drukowania tablicy w trybie szeregowym if (intInput == 3){ if (bolSerialBoard == false){ Serial.println("Płyta szeregowa aktywna"); bolSerialBoard = prawda; } else { Serial.println("Płyta szeregowa wyłączona"); bolSerialBoard = false; } } //ustaw szybkość gry na łatwy if (intInput == 0){ Serial.print("Gra ustawiona na łatwy ("); Serial.print(intGameSpeedEasy); Serial.println("akceleracja ms)"); intRóż = 0; intGameSpeed = intGameSpeedŁatwy; } //ustaw prędkość gry na średni poziom trudności if (intInput == 1){ Serial.print("Gra ustawiona na średnią ("); Serial.print(intGameSpeedMedium); Serial.println("akceleracja ms)"); intRóż = 1; intGameSpeed = intGameSpeedMedium; } //ustaw szybkość gry na wysoki poziom trudności if (intInput == 2){ Serial.print("Gra ustawiona na trudną ("); Serial.print(intGameSpeedHard); Serial.println("akceleracja ms)"); intRóż = 2; intGameSpeed = intGameSpeedHard; } }

// sprawdza przyciski i co z nimi zrobić podczas gry

void buttonsGame(){ if (intInput != 4) { //jeżeli przycisk zostanie naciśnięty if (bolTilePressed == false){ //tylko jeżeli bolTilePressed to false akcja wyzwalania w celu sprawdzenia przycisku naciśnij bolTilePressed = true; //następnie ustaw bolTilePressed na true, aby upewnić się, że nie zostanie ponownie wyzwolony acidentilly int intLowestTile = 0; //ustawić na kafelek z najniższym kafelkiem intCheckedTile = 15; //aby śledzić, które kafelki zostały sprawdzone while (intLwestTile == 0) { //o ile nie jest ustawione na nic, sprawdzaj kafelki dla (int i = 0; i 100){ //dopóki int opóźnienie nie mniejsze niż 100 intDelay = intDelay - 20; //weź z niego wartość } } else { Serial.println("Naciśnięto błędny przycisk"); koniec gry(); //w przeciwnym razie koniec gry } } } } }

nieważne zakończenie gry() {

Serial.println("Koniec gry!"); Serial.print("Twój wynik to: "); Serial.println(intScore); Serial.print("Twoja prędkość wynosiła: "); Serial.println(intDelay); bolPlay = fałsz; }

// sprawdza wejście gracza

void input() { intEnter = digitalRead(btnEnter); //odczytaj wprowadź //odczytaj które z pozostałych wejść lub jeśli żadne nie jest ustawione na 4 if (digitalRead(btn1) == HIGH){intInput = 0;} else { if (digitalRead(btn2) == HIGH){intInput = 1;} else { if (digitalRead(btn3) == HIGH){intInput = 2;} else { if (digitalRead(btn4) == HIGH){intInput = 3;} else { intInput = 4; }}}} //serial drukuj dane wejściowe if (intEnter == 1){Serial.println("Naciśnięto Enter! ");} if (intInput != 4){ Serial.print("Naciśnięcie przycisku: "); Serial.println(wejście); } else { //jeśli nie zostanie naciśnięty żaden przycisk zresetuj bolTilePressed bolTilePressed = false; } }

//sprawdza dno płytki pod kątem awarii

void bottomCheck() { for (int i = 0; i <= 3; i++){ //dla 4 kolumn if (arrGame[15] == 1){ //jeśli kafelek jest na dole Serial.println("Kafelek na dole"); gra[15] = 2; Tablica Rysunkowa(); opóźnienie(400); ArrGame[15] = 1; Tablica Rysunkowa(); opóźnienie(400); gra[15] = 2; Tablica Rysunkowa(); opóźnienie(400); ArrGame[15] = 1; Tablica Rysunkowa(); opóźnienie(400); koniec gry(); } } }

//wypisuje płytę do monitora szeregowego, jeśli bolSerialBoard jest prawdziwe

void writeSerial() { if (bolSerialBoard == true){ for (int i = 0; i <= 15; i ++){ for (int ii = 0; ii <= 3; ii++){ Serial.print(arrGame [ii]); Serial.print(", "); } Serial.println(""); } } }

Po wprowadzeniu całego kodu prześlij go na swoje arduino i ciesz się!

Zalecana: