Innehållsförteckning:

Arduino - Pianoplattor: 16 steg (med bilder)
Arduino - Pianoplattor: 16 steg (med bilder)

Video: Arduino - Pianoplattor: 16 steg (med bilder)

Video: Arduino - Pianoplattor: 16 steg (med bilder)
Video: CS50 2015 – 10-я неделя 2024, Juli
Anonim
Arduino - Pianoplattor
Arduino - Pianoplattor

Hej internet folk, Det här kommer att handla om hur man gör det som DEFINITIVT inte är en rip off av ett mobilspel på en arduino uno r3.

så för att börja behöver du alla delar, som är följande! 1x Arduino Uno r3 ($ 42)

2x LCD -knappsatssköld (19 $ styck)

5x knappar

5x 220Ω motstånd

28x trådar

Okej, när du har alla delar är det dags att komma igång!

Steg 1: Kabeldragning

Kabeldragning
Kabeldragning
Kabeldragning
Kabeldragning
Kabeldragning
Kabeldragning

Börja med att koppla ihop din arduino och vänner som visas i diagrammet, Se till att knapparna är länkade åt rätt håll, med A0-4-facken på knappskenens undersida, annars kommer arduinoen istället att tro att knapparna hålls nedtryckta hela tiden istället för bara vid ett tryck.

Steg 2: Deklarationsförklaringar

All kod här bör gå före din tomrumsinställning och tomrumsslinga, detta beror på att alla dessa variabler och objekt används i flera av de funktioner vi kommer att konfigurera.

Börja med att sätta:

#omfatta

högst upp i din kod säger detta till arduino att använda biblioteket "LiquidCrystal.h" och de funktioner som är en del av det.

Nästa steg är att definiera stiften som vi använder för våra knappar genom att sätta den här koden under vår #include:

#define btnAnge A0 #definiera btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

Vi definierar termerna btnEnter och btn1 till btn 4 för att göra koden lättare för oss att läsa, eller ändra om det behövs. Det betyder att när vi skriver btn1 kommer arduino att veta att vi faktiskt menar knappen 15. Även om vi anropar portarna 15, 16, 17 och 18, är de märkta på arduino som A1 A2 A3 och A4, detta beror på att de är portar som används specifikt för analoga ingångar, även om vi bara använder dem för digitala ingångar.

Därefter ska vi skapa de objekt som kommer att styra Liquid Crystal Displays. För att göra detta, lägg den här koden under våra definieringar

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

Vad detta gör är att säga till arduinoen att när vi ringer lcdLeft eller lcdRight hänvisar vi till ett LiquidCrystal -objekt. Siffrorna i de bifogade parenteserna berättar för arduino vilken port objektet ska använda för att skicka meddelanden till LCD -skärmen när vi använder deras funktioner.

Nu måste vi deklarera variablerna genom att sätta nästa kodbit under objektdeklarationerna:

// dessa variabler är alternativ som du kan ändra - högre siffror = snabbare spelhastighet upint intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// konfigurera variabler för gameboolean bolPlay; // spårar om spelaren int intScore; // spårar spelarens poäng int intDiff; // bara en estetisk sak för att berätta vilken svårighet spelet är på // ställa in variabler för input int intEnter; // spårar om användaren trycker på enter -knappen int intInput; // spårar vilka knappar användaren trycker på boolean bolTilePressed; // se till att spelaren inte av misstag trycker på en knapp 5x och förlorar // ställer in variabler för turn int intTick; // räknar upp millies (per loop) tills intDelay int intDelay; // den tid programmet väntar till nästa tur i millis int intGameSpeed; // abit av felsökningsalternativ booleskt bolSerialBoard; // när true kommer att skriva ut kortet i den seriella bildskärmen

Vi deklarerar en variabel genom att ange datatypen och sedan variabelns namn, ex. int thisIsAnInteger

Booleanska variabler, till exempel bolSerialBoard och bolPlay kan bara ha ett av två värden, sant eller falskt.

Integer variabel (int) som intScore och intInput kan ta heltal som värden, till exempel 1, 5 eller 100.

Några andra anmärkningsvärda datatyper som vi inte använder här är en sträng, som är en bit text, och en float, som är ett decimaltal.

Var och en av variablerna här används på flera olika platser av programmet, här är en sammanfattning av vad var och en gör

bolPlay berättar för programmet om menyn ska visas eller om det faktiska spelet ska köras.

intScore spårar spelarens poäng när de träffar brickor, intDiff används på huvudmenyn för att berätta för programmet vilken bit text som ska skrivas ut på LCD -skärmen, intEnter används för att berätta för programmet om enter -knappen (längst till vänster) trycks in, intInput används för att berätta för programmet vilken av de andra 4 knapparna som trycks ned.

bolTilePressed används för att se till att programmet bara läser på när knappen trycks in och inte när den hålls inne.

intGameSpeed, intGameSpeedEasy, intGameSpeedMedium och intGameSpeedHard används för att styra hur snabbt spelet ska snabbas upp baserat på vilken svårighet som väljs.

intTick och intDelay används för att stoppa programmet från att flytta kortet varje gång det går i loop.

bolSerialBoard används för att låta dig få programmet att skicka kortet till arduinos seriella bildskärm som en serie nummer för teständamål.

Slutligen är det dags att deklarera vår styrelse som en array med denna kod:

// konfigurera game 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}};

En matris är en matris som varje punkt som kan kallas för matematik eller ska ändras.

Din kod ska nu se ut ungefär så här;

// inkludera bibliotek#inkludera

// Dessa variabler är alternativ som du kan ändra - högre siffror = snabbare spelhastighet

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

// Definiera stift

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

// skapa LCD -objekt (n, ~, n, ~, ~, n)

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

// ställa in spelarray

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}};

// ställa in variabler för spelet

booleskt bolPlay; // spårar om spelaren int intScore; // spårar spelarens poäng int intDiff; // bara en estetisk sak för att berätta vilken svårighet spelet har

// konfigurera variabler för inmatning

int intEnter; // spårar om användaren trycker på enter -knappen int intInput; // spårar vilka knappar användaren trycker på boolean bolTilePressed; // se till att spelaren inte av misstag trycker på en knapp 5x och förlorar

// ställa in variabler för tur

int intTick; // räknar upp millies (per loop) tills intDelay int intDelay; // den tid programmet väntar till nästa tur i millis int intGameSpeed;

// abit av felsökningsalternativ

booleskt bolSerialBoard; // när true kommer att skriva ut kortet i den seriella bildskärmen

Steg 3: Inställningsfunktionen

Installationsslingan är en funktion som läses av arduino bara en gång när den initialt startar.

I installationsslingan ställer vi bara in värdena för några av våra variabler för att istället för att ställa in dem ett värde när vi deklarerar dem gör vi det här.

Börja med att sätta in den här koden i din ogiltiga installation.

bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium;

Varje rad ställer bara in en variabel till ett värde.

bolPlay är inställd på falskt så att spelet inte börjar spela.

intScore är 0, eftersom din poäng naturligtvis börjar på 0.

intTick börjar vid 0 eftersom programmet för närvarande inte räknar något.

intDelay är satt till 1000 eftersom det är den hastighet brickorna börjar med.

intDiff är bara en asketisk sak så att programmet vet vad man ska skriva för spelets svårigheter.

intGameSpeed är inställd på vad intGameSpeedMedium är, vilket betyder att det är inställt på medelstora svårigheter.

Lägg sedan den här koden i den ogiltiga installationen under koden du precis lade in.

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

Serial.begin (9600);

Detta berättar för arduino att börja kommunicera med datorn via den seriella bildskärmen (synlig genom att klicka på knappen längst upp till höger på arduino IDE).

Din ogiltiga installation bör nu se ut ungefär så här!

void setup () {Serial.begin (9600); // starta seriell bildskärm // konfigurera variablerna bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; // börja lcd's lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

Steg 4: Loop -funktionen

Loop -funktionen drivs av arduino varje iteration av arduino.

Kopiera följande kod till din Void Loop.

void loop () {input (); // kolla om det finns uppspelning om (bolPlay == true) {if (intTick> = intDelay) {// kolla om spelet ska spela en tur eller fortsätt att vänta Serial.println ("~~~~~~~ ~~ "); // skriv ut för att markera att styrelsen går vidare // writeSerial (); // om alternativet är aktiverat skriv in kortet i seriella knapparGame (); // kontrollera spelarens ingångar playBoard (); // flytta brädet och lägg till en ny platta clearLcd (); // rengör LCD -skärmarna innan du ritar drawBoard (); // rita brädet på LCD: ns bottenCheck (); intTick = 0; // reset intTick} else {buttonsGame (); // kontrollera spelarens ingångar clearLcd (); // rengör LCD -skärmarna innan du ritar drawBoard (); // rita tavlan på LCD: ns intTick = intTick + intGameSpeed; // lägg till i tick}} else {clearLcd (); // rengör LCD -skärmarna innan du drar titel (); // visa titel och poänginformation knapparMeny (); // läs spelarens ingång clearBoard (); // se till att hela kortet = 0} fördröjning (10); // fördröja arduino med ett kort ögonblick}

när bolPlay är lika med true betyder det att spelet spelas, och all kod för när spelet spelas ska köras, men vi vill bara att brädan ska lägga till en ny bricka och flytta ner när intTick är större än vår intDelay, annars vill vi fortfarande tillåta användaren att trycka på en knapp för att träffa en bricka och för intTick att öka i hastighet.

De flesta av den här koden använder funktioner som vi ännu inte ska göra, och vi kommer att göra dem i nästa steg. Syftet med dessa funktioner är följande.

Ingången läser vilka knappar användaren har tryckt på.

buttonsGame styr vad knapparna gör när de är i spelet och inte i menyn

playBoard lägger till en ny bricka på brädet och flyttar sedan allt i brädet ner ett utrymme

clearLCD rengör LCD -skärmarna för att se till att inga spöken lämnas bakom brickorna

drawBoard går igenom arrGame och skriver ut det på LCD -skärmarna

clearBoard rensar hela arrGame när spelet inte spelas

bottomCheck kontrollerar botten av arrGame efter ett fel

titel visar spelets titel och poänginformation på menyn

knappar -menyn styr vad användarens inmatningar gör när de är i menyn.

gameOver är en annan funktion, även om den inte kallas här som den istället kallas i bottenCheck och buttonsGame -funktioner.

Steg 5: ClearLCD -funktionen

för att skapa en funktion börjar vi med att lägga till detta i koden

void functionName () {

}

"functionName" kan vara vad som helst, så länge det inte redan finns.

Kopiera den här koden till ditt program:

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 (""); }}}

detta löper genom hela matrisen med hjälp av 2 räknade loopar för att gå igenom varje punkt på LCD -skärmarna och skriva ett mellanslag.

Utan att återställas till ingenting kommer LCD -skärmarna att behålla det som skrevs tidigare

Steg 6: DrawBoard -funktionen

kopiera den här koden till ditt program

void drawBoard () {för (int i = 1; i <= 15; i ++) {// draw collums 1 and 2 on the left LCD // if the brick = 0 write nothing, = 1 write "#", = 2 skriv "@" lcdLeft.setCursor (i, 1); // ställ in på den första kolumnen (längst till vänster) if (arrGame [0] == 1) {lcdLeft.write ("#");} if (arrGame [0] == 2) {lcdLeft.write ("@");} lcdLeft.setCursor (i, 0); // ställ in på den andra kolumnen (mitt till vänster) if (arrGame [1] == 1) {lcdLeft.write ("#");} if (arrGame [1] == 2) {lcdLeft.write ("@");} lcdRight.setCursor (i, 1); // ställ in på den tredje kolumnen (mitt till höger) if (arrGame [2] == 1) {lcdRight.write ("#");} if (arrGame [2] == 2) {lcdRight.write ("@");} lcdRight.setCursor (i, 0); // ställ in på den fjärde kolumnen (längst till höger) if (arrGame [3] == 1) {lcdRight.write ("#");} if (arrGame [3] == 2) {lcdRight.write ("@");}}}

detta använder en loop för att gå igenom varje rad på brädet, det kontrollerar sedan om någon kolumn i raden är lika med 1 eller 2, baserat på att den sedan skriver ut på LCD -skärmen antingen en hashtag, för att en kakel inte ska vara hit, eller en @ för en träffkakel.

Steg 7: PlayBoard -funktionen

kopiera den här koden till ditt program.

void playBoard () {för (int i = 0; i <= 3; i ++) {arrGame [0] = 0;} // rensa den översta raden arrGame [0] [random (0, 4)] = 1; // ställ in en slumpmässig punkt på den översta raden som en kakel för (int i = 15; i> = 1; i-) {// arbeta från brädans botten till toppen för (int ii = 0; ii <= 3; ii ++) {// för varje collum arrGame [ii] = arrGame [i - 1] [ii]; }}}

den här koden börjar med att rensa hela den översta raden till 0, eller ingen kakel, och ställer sedan in en slumpmässig kakel till en 1 och ohit kakel.

Den går sedan genom en räknad slinga i omvänd ordning, från 15 till 1, och sätter raden till lika oavsett vilken rad ovanför den är lika med, vilket får tavlan att röra sig nedåt LCD -skärmen

Steg 8: ClearBoard -funktionen

kopiera den här koden till ditt program.

void clearBoard () {// återställ kryss- och fördröjningsvärden intTick = 0; intDelay = 1000; // gå igenom tavlan och ställ allt till 0 för (int i = 0; i <= 15; i ++) {för (int ii = 0; ii <= 3; ii ++) {arrGame [ii] = 0; }}}

Denna kod körs när spelet inte spelas för att se till att hela arrGame är inställt på 0, eller inga brickor, genom att använda räknade loopar för att gå igenom matrisen.

Koden återställer också värdena för intDelay och intTick.

Steg 9: Titelfunktionen

kopiera följande kod till ditt program

void title () {// skriv titel på LCD och plats för poäng lcdRight.setCursor (0, 0); lcdRight.write ("Pianoskivor"); lcdRight.setCursor (0, 1); lcdRight.write ("Poäng:"); // konvertera poängen till en sträng char strScore [3]; sprintf (strScore, "%d", intScore); // visa poäng på LCD lcdRight.write (strScore); // lägg till diffictuly lcdRight.setCursor (10, 1); if (intDiff == 0) {lcdRight.write ("Easy"); } if (intDiff == 1) {lcdRight.write ("Medium"); } if (intDiff == 2) {lcdRight.write ("Hard"); } // Tryck på lite instruktion lcdLeft.setCursor (0, 0); lcdLeft.write ("Tryck på Enter"); lcdLeft.setCursor (0, 1); lcdLeft.write ("att börja!"); }

Denna kod skriver spelets titel och poängen på LCD -skärmarna, den gör detta genom att berätta för LCD -skärmen var man ska börja skriva med LCD.setCursor och sedan skriva strängen i LCD.write.

En ny variabel skapas också här, strScore, den används för att konvertera intScore till en sträng- eller char -datatyp med hjälp av sprintf -funktionen.

intDiff används också här, baserat på dess värden skriver det ut de olika svårighetsalternativen.

Steg 10: Funktionen ButtonsMenu

sätt in följande kod i ditt program

void buttonsMenu () {// när enter trycks in starta spelet och återställ poängvärdet om (intEnter == 1) {bolPlay = true; intScore = 0; playBoard (); drawBoard (); } // när knapp 3 trycks in, aktivera felsökningsalternativ för att skriva ut kortet i serie om (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active"); bolSerialBoard = true; } else {Serial.println ("Serial Board Disabled"); bolSerialBoard = false; }} // ställ in spelhastigheten till lätt svårighet om (intInput == 0) {Serial.print ("Game set to easy ("); Serial.print (intGameSpeedEasy); Serial.println ("ms acceleration)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // ställ in spelhastigheten till medelhög svårighet om (intInput == 1) {Serial.print ("Game set to medium ("); Serial.print (intGameSpeedMedium); Serial.println ("ms acceleration)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // ställ in spelhastigheten till svår svårighet om (intInput == 2) {Serial.print ("Game set to hard ("); Serial.print (intGameSpeedHard); Serial.println ("ms acceleration)"); intDiff = 2; intGameSpeed = intGameSpeedHard; }}

den här koden körs bara när bolPlay är lika med falskt i void Loop

om intEnter är inställt på 1 betyder det att enter -knappen har tryckts in, om det trycks in ställer programmet in bolPlay till true och spelet startar.

Programmet läser sedan vad intInput är lika med. om det är lika med 0 trycks den första knappen från vänster, går upp till höger upp till 3. Om intInput är lika med 4 trycks ingen knapp.

om knapparna 0-2 trycks in ändrar spelet svårigheten, vilket också justerar spelets hastighet, vilket betyder att det kommer att accelerera snabbare.

om knapp 3 trycks in kommer spelet att aktivera eller inaktivera ett felsökningsläge där hela kortet skrivs ut i den seriella bildskärmen för att hjälpa till att hitta problem i programmet.

Steg 11: ButtonsGame -funktionen

kopiera följande kod till ditt program

void buttonsGame () {if (intInput! = 4) {// om en knapp trycks in om (bolTilePressed == false) {// bara om bolTilePressed är falsk utlösaråtgärd för att kontrollera en knapptryckning bolTilePressed = true; // ställ sedan in bolTilePressed till true för att se till att det inte utlöses oavsiktligt int intLowestTile = 0; // ska ställas in på brickan med den lägsta brickan int intCheckedTile = 15; // för att hålla reda på vilka brickor som har kontrollerats medan (intLowestTile == 0) {// så länge det inte är inställt på något, kontrollera brickor för (int i = 0; i 100) {// så länge int fördröjning är inte lägre än 100 intDelay = intDelay - 20; // ta ett värde från det}} else {Serial.println ("Fel knapp tryckt"); gameOver (); // annars är spelet över}}}}}

Koden körs bara när bolPlay är lika med true i void Loop.

Som knappar Meny baserat på värdet av intInput kontrollerar den om spelaren har träffat en bricka eller missat en.

Det gör detta genom att gå igenom arrGame från botten till toppen med hjälp av en while -slinga för att leta efter vilken rad som är den lägsta med en unhit -kakel. Den kontrollerar sedan om platsen på den raden som motsvarar knappen tryckt är en ohäftad kakel eller inte, om den är ohäftad ställer den in till lika med 2 istället för 1, vilket betyder att den kommer att visas som en @, annars utlöser det gameOver funktion som vi ännu inte ska skapa.

Denna funktion använder också variabeln bolTilePressed genom att ställa in den till true när en knapp trycks in och falsk när ingen knapp trycks in. Detta för att säkerställa att användaren inte av misstag förlorar spelet eftersom programmet trodde att de tryckte på knappen flera gånger när de höll ner det.

Steg 12: GameOver -funktionen

Kopiera följande kod till ditt program

void gameOver () {Serial.println ("Game Over!"); Serial.print ("Din poäng var:"); Serial.println (intScore); Serial.print ("Din hastighet var:"); Serial.println (intDelay); bolPlay = false; }

Detta utlöses av antingen checkBottom eller buttonsGame -funktionerna och utlöser slutet av spelet genom att ställa in bolPlay som falskt.

Det skriver också ut ett meddelande i seriell bildskärm för användarnas poäng och hastighetsbrickorna lades till i millisekunder.

Steg 13: Inmatningsfunktionen

Kopiera följande kod till ditt program.

void input () {intEnter = digitalRead (btnEnter); // läs enter // läs vilken av de andra ingångarna, eller om ingen är inställd på 4 om (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; }}}}} // seriell skriv ut ingångarna om (intEnter == 1) {Serial.println ("Enter Pressed!");} if (intInput! = 4) {Serial.print ("Button Press:"); Serial.println (intInput); } annat {// om ingen knapp trycks in återställ bolTilePressed bolTilePressed = false; }}

Denna kod används med knapparna Spel och knappar Menyfunktioner. baserat på knapparna som användaren har tryckt på ställer det in värdet för intInput, eller om ingen knapp trycks in ställer det intInput till lika med 4.

Om ingen knapp trycks in återställs bolTilePressed för knapparnaGame -funktionen.

Det skriver också ut ett meddelande till den seriella bildskärmen där knappen trycks ned.

Steg 14: BottomCheck -funktionen

kopiera följande kod till ditt program.

void bottomCheck () {för (int i = 0; i <= 3; i ++) {// för de fyra kolumnerna om (arrGame [15] == 1) {// om det finns en bricka längst ner i serien.println ("Kakel längst ner"); arrGame [15] = 2; drawBoard (); fördröjning (400); arrGame [15] = 1; drawBoard (); fördröjning (400); arrGame [15] = 2; drawBoard (); fördröjning (400); arrGame [15] = 1; drawBoard (); fördröjning (400); gameOver (); }}}

med hjälp av en loop kontrollerar den här koden den nedre raden av arrGame för alla ohit -brickor (brickor lika med 1), om det finns en unhit -bricka längst ner på skärmen kommer den att blinka brickan och sedan utlösa spelet över -funktionen.

Steg 15: WriteSerial -funktionen

kopiera följande kod till ditt program

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

Detta är funktionen följt av felsökningsalternativet som kan aktiveras i knapparna Menyfunktion. Om bolSerialBoard är inställt på true i den funktionen går det igenom arrGame och skriver ut hela kortet i seriell bildskärm för teständamål med hjälp av en array.

Steg 16: Slutförande

Komplettering!
Komplettering!

Hela din kod ska inte vara komplett och se ut ungefär så här!

/ * * Namn - Pianoplattor; Arduino * Av - Domenic Marulli * Datum - 11/ *

/ inkludera bibliotek

#omfatta

// Dessa variabler är alternativ som du kan ändra - högre siffror = snabbare spelhastighet

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

// Definiera stift

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

// skapa LCD -objekt (n, ~, n, ~, ~, n)

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

// ställa in spelarray

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}};

// ställa in variabler för spelet

booleskt bolPlay; // spårar om spelaren int intScore; // spårar spelarens poäng int intDiff; // bara en estetisk sak för att berätta vilken svårighet spelet har

// konfigurera variabler för inmatning

int intEnter; // spårar om användaren trycker på enter -knappen int intInput; // spårar vilka knappar användaren trycker på boolean bolTilePressed; // se till att spelaren inte av misstag trycker på en knapp 5x och förlorar

// ställa in variabler för tur

int intTick; // räknar upp millies (per loop) tills intDelay int intDelay; // den tid programmet väntar till nästa tur i millis int intGameSpeed;

// abit av felsökningsalternativ

booleskt bolSerialBoard; // när true kommer att skriva ut kortet i den seriella bildskärmen

// installationen som kommer att köras en gång

void setup () {Serial.begin (9600); // starta seriell bildskärm // konfigurera variablerna bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; // börja lcd's lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

// slingan som kommer att köras var 10: e millisekon

void loop () {input (); // kolla om det finns uppspelning om (bolPlay == true) {if (intTick> = intDelay) {// kolla om spelet ska spela en tur eller fortsätt att vänta Serial.println ("~~~~~~~ ~~ "); // skriv ut för att markera att styrelsen går vidare // writeSerial (); // om alternativet är aktiverat skriv in kortet i seriella knapparGame (); // kontrollera spelarens ingångar playBoard (); // flytta brädet och lägg till en ny platta clearLcd (); // rengör LCD -skärmarna innan du ritar drawBoard (); // rita brädet på LCD: ns bottenCheck (); intTick = 0; // reset intTick} else {buttonsGame (); // kontrollera spelarens ingångar clearLcd (); // rengör LCD -skärmarna innan du ritar drawBoard (); // rita tavlan på LCD: ns intTick = intTick + intGameSpeed; // lägg till i tick}} else {clearLcd (); // rengör LCD -skärmarna innan du drar titel (); // visa titel och poänginformation knapparMeny (); // läs spelarens ingång clearBoard (); // se till att hela kortet = 0} fördröjning (10); // fördröja arduino med ett kort ögonblick}

// rengör LCD -skärmen, så att alla ointresserade celler inte lämnas där

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 (""); }}}

// ritar brädet på LCD -skärmarna

void drawBoard () {för (int i = 1; i <= 15; i ++) {// draw collums 1 and 2 on the left LCD // if the brick = 0 write nothing, = 1 write "#", = 2 skriv "@" lcdLeft.setCursor (i, 1); // ställ in på den första kolumnen (längst till vänster) if (arrGame [0] == 1) {lcdLeft.write ("#");} if (arrGame [0] == 2) {lcdLeft.write ("@");} lcdLeft.setCursor (i, 0); // ställ in på den andra kolumnen (mitt till vänster) if (arrGame [1] == 1) {lcdLeft.write ("#");} if (arrGame [1] == 2) {lcdLeft.write ("@");} lcdRight.setCursor (i, 1); // ställ in på den tredje kolumnen (mitt till höger) if (arrGame [2] == 1) {lcdRight.write ("#");} if (arrGame [2] == 2) {lcdRight.write ("@");} lcdRight.setCursor (i, 0); // ställ in på den fjärde kolumnen (längst till höger) if (arrGame [3] == 1) {lcdRight.write ("#");} if (arrGame [3] == 2) {lcdRight.write ("@");}}}

// flyttar tavlan nedåt och placerar ett slumpmässigt värde som en kakel

void playBoard () {för (int i = 0; i <= 3; i ++) {arrGame [0] = 0;} // rensa den översta raden arrGame [0] [random (0, 4)] = 1; // ställ in en slumpmässig punkt på den översta raden som en kakel för (int i = 15; i> = 1; i-) {// arbeta från brädans botten till toppen för (int ii = 0; ii <= 3; ii ++) {// för varje collum arrGame [ii] = arrGame [i - 1] [ii]; }}}

// ställer in hela kortet till 0 och återställer variabler till förspel

void clearBoard () {// återställ kryss- och fördröjningsvärden intTick = 0; intDelay = 1000; // gå igenom tavlan och ställ allt till 0 för (int i = 0; i <= 15; i ++) {för (int ii = 0; ii <= 3; ii ++) {arrGame [ii] = 0; }}}

// visar huvudmenyn på LCD -skärmarna

void title () {// skriv titel på LCD och plats för poäng lcdRight.setCursor (0, 0); lcdRight.write ("Pianoskivor"); lcdRight.setCursor (0, 1); lcdRight.write ("Poäng:"); // konvertera poängen till en sträng char strScore [3]; sprintf (strScore, "%d", intScore); // visa poäng på LCD lcdRight.write (strScore); // lägg till diffictuly lcdRight.setCursor (10, 1); if (intDiff == 0) {lcdRight.write ("Easy"); } if (intDiff == 1) {lcdRight.write ("Medium"); } if (intDiff == 2) {lcdRight.write ("Hard"); } // Tryck på lite instruktion lcdLeft.setCursor (0, 0); lcdLeft.write ("Tryck på Enter"); lcdLeft.setCursor (0, 1); lcdLeft.write ("att börja!"); }

// kontrollerar knapparna och vad de ska göra för dem när de inte är i spel

void buttonsMenu () {// när enter trycks in starta spelet och återställ poängvärdet om (intEnter == 1) {bolPlay = true; intScore = 0; playBoard (); drawBoard (); } // när knapp 3 trycks in, aktivera felsökningsalternativ för att skriva ut kortet i serie om (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active"); bolSerialBoard = true; } else {Serial.println ("Serial Board Disabled"); bolSerialBoard = false; }} // ställ in spelhastigheten till lätt svårighet om (intInput == 0) {Serial.print ("Game set to easy ("); Serial.print (intGameSpeedEasy); Serial.println ("ms acceleration)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // ställ in spelhastigheten till medelhög svårighet om (intInput == 1) {Serial.print ("Game set to medium ("); Serial.print (intGameSpeedMedium); Serial.println ("ms acceleration)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // ställ in spelhastigheten till svår svårighet om (intInput == 2) {Serial.print ("Game set to hard ("); Serial.print (intGameSpeedHard); Serial.println ("ms acceleration)"); intDiff = 2; intGameSpeed = intGameSpeedHard; }}

// kontrollerar knapparna och vad de ska göra för dem medan de är i spelet

void buttonsGame () {if (intInput! = 4) {// om en knapp trycks in om (bolTilePressed == false) {// bara om bolTilePressed är falsk utlösaråtgärd för att kontrollera en knapptryckning bolTilePressed = true; // ställ sedan in bolTilePressed till true för att se till att det inte utlöses oavsiktligt int intLowestTile = 0; // ska ställas in på brickan med den lägsta brickan int intCheckedTile = 15; // för att hålla reda på vilka brickor som har kontrollerats medan (intLowestTile == 0) {// så länge det inte är inställt på något, kontrollera brickor för (int i = 0; i 100) {// så länge int fördröjning är inte lägre än 100 intDelay = intDelay - 20; // ta ett värde från det}} else {Serial.println ("Fel knapp tryckt"); gameOver (); // annars är spelet över}}}}}

void gameOver () {

Serial.println ("Game Over!"); Serial.print ("Din poäng var:"); Serial.println (intScore); Serial.print ("Din hastighet var:"); Serial.println (intDelay); bolPlay = false; }

// kontrollerar spelarens inmatning

void input () {intEnter = digitalRead (btnEnter); // läs enter // läs vilken av de andra ingångarna, eller om ingen är inställd på 4 om (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; }}}}} // seriell skriv ut ingångarna om (intEnter == 1) {Serial.println ("Enter Pressed!");} if (intInput! = 4) {Serial.print ("Button Press:"); Serial.println (intInput); } annat {// om ingen knapp trycks in återställ bolTilePressed bolTilePressed = false; }}

// kontrollerar botten av brädet för fel

void bottomCheck () {för (int i = 0; i <= 3; i ++) {// för de fyra kolumnerna om (arrGame [15] == 1) {// om det finns en bricka längst ner i serien.println ("Kakel längst ner"); arrGame [15] = 2; drawBoard (); fördröjning (400); arrGame [15] = 1; drawBoard (); fördröjning (400); arrGame [15] = 2; drawBoard (); fördröjning (400); arrGame [15] = 1; drawBoard (); fördröjning (400); gameOver (); }}}

// skriver ut kortet i den seriella bildskärmen om bolSerialBoard är sant

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

När all kod har matats in, ladda upp till din arduino och njut!

Rekommenderad: