Inhoudsopgave:

Arduino - pianotegels: 16 stappen (met afbeeldingen)
Arduino - pianotegels: 16 stappen (met afbeeldingen)

Video: Arduino - pianotegels: 16 stappen (met afbeeldingen)

Video: Arduino - pianotegels: 16 stappen (met afbeeldingen)
Video: Hoe werkt een lichtshow - stap voor stap! 2024, Juli-
Anonim
Arduino - Pianotegels
Arduino - Pianotegels

Hallo internetmensen, dit gaat over hoe je kunt maken wat ZEKER geen afzetterij is van een mobiel spel op een arduino uno r3.

dus om te beginnen heb je alle onderdelen nodig, die als volgt zijn! 1x Arduino Uno r3 ($ 42)

2x LCD-toetsenbordscherm ($ 19 per stuk)

5x knoppen

5x 220Ω weerstanden

28x draden

Oké, als je eenmaal alle onderdelen hebt, is het tijd om te beginnen!

Stap 1: Bedrading

Bedrading
Bedrading
Bedrading
Bedrading
Bedrading
Bedrading

Begin met het aansluiten van je arduino en vrienden zoals weergegeven in het diagram, Zorg ervoor dat de knoppen op de juiste manier zijn gekoppeld, met de A0-4-slots aan de grondzijde van de knoprails, anders zal de arduino denken dat de knoppen constant worden ingedrukt in plaats van alleen op een pers.

Stap 2: Verklaringsverklaringen

Alle code hier zou voor je void setup en void loop moeten gaan, dit komt omdat al deze variabelen en objecten worden gebruikt in verschillende van de functies die we zullen opzetten.

Begin met het plaatsen van:

#erbij betrekken

bovenaan je code, vertelt dit de arduino om de bibliotheek "LiquidCrystal.h" en de functies die er deel van uitmaken te gebruiken.

De volgende stap is het definiëren van de pinnen die we gebruiken voor onze knoppen door deze code onder onze #include te plaatsen:

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

We definiëren de termen btnEnter en btn1 tot btn 4 om de code voor ons gemakkelijker leesbaar te maken, of indien nodig te wijzigen. Het betekent dat wanneer we btn1 typen, de arduino weet dat we in feite de knop 15 bedoelen. Hoewel we de poorten poort 15, 16, 17 en 18 noemen, zijn ze op de arduino gelabeld als A1 A2 A3 en A4, dit komt omdat het zijn poorten die specifiek worden gebruikt voor analoge ingangen, hoewel we ze alleen gebruiken voor digitale ingangen.

Vervolgens gaan we de objecten maken die de Liquid Crystal Displays zullen besturen. Om dit te doen, plaatst u deze code onder onze definities

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

Wat dit doet, is de Arduino vertellen dat wanneer we lcdLeft of lcdRight aanroepen, we verwijzen naar een LiquidCrystal-object. De nummers in de bijgevoegde haakjes vertellen de Arduino welke poorten het object zou moeten gebruiken om berichten naar het LCD-scherm te sturen wanneer we hun functies gebruiken.

Nu moeten we de variabelen declareren door het volgende stukje code onder de objectdeclaraties te plaatsen:

// deze variabelen zijn opties die je kunt wijzigen - hogere getallen = hogere spelsnelheid upint intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// variabelen instellen voor de gameboolean bolPlay; //tracks als de speler int intScore; // volgt de score van de speler int intDiff; //gewoon een esthetisch ding om te vertellen hoe moeilijk het spel is // stel variabelen in voor invoer int intEnter; // houdt bij of de gebruiker op de enter-knop drukt int intInput; // houdt bij op welke knoppen de gebruiker drukt boolean bolTilePressed; //zorg ervoor dat de speler niet per ongeluk 5x op een knop drukt en verliest //variabelen instellen voor turn int intTick; // telt millies (per lus) op tot intDelay int intDelay; // de tijd dat het programma wacht tot de volgende beurt in millis int intGameSpeed; // een beetje foutopsporingsopties boolean bolSerialBoard; //wanneer waar, wordt het bord in de seriële monitor afgedrukt

We declareren een variabele door het gegevenstype op te geven en vervolgens de naam van de variabele, bijv. int thisIsAnInteger

Booleaanse variabelen, zoals bolSerialBoard en bolPlay kunnen slechts één van de twee waarden hebben, waar of onwaar.

Integer-variabele (int) zoals intScore en intInput kunnen hele getallen als waarden aannemen, zoals 1, 5 of 100.

Enkele andere opmerkelijke gegevenstypen die we hier niet gebruiken, zijn een string, een stuk tekst, en een float, een decimaal getal.

Elk van de variabelen hier wordt op verschillende plaatsen door het programma gebruikt, hier is een samenvatting van wat elk doet

bolPlay vertelt het programma of het menu moet worden weergegeven of dat het eigenlijke spel moet worden uitgevoerd.

intScore volgt de score van de speler als ze tegels raken, intDiff wordt in het hoofdmenu gebruikt om het programma te vertellen welk stukje tekst op de LCD's moet worden afgedrukt, intEnter wordt gebruikt om het programma te vertellen of de enter-knop (meest links) wordt ingedrukt, intInput wordt gebruikt om het programma te vertellen welke van de andere 4 knoppen is ingedrukt.

bolTilePressed wordt gebruikt om ervoor te zorgen dat het programma alleen verder leest wanneer de knop wordt ingedrukt en niet wanneer deze wordt ingedrukt.

intGameSpeed, intGameSpeedEasy, intGameSpeedMedium en intGameSpeedHard worden gebruikt om te bepalen hoe snel het spel moet versnellen op basis van de geselecteerde moeilijkheidsgraad.

intTick en intDelay worden gebruikt om te voorkomen dat het programma het bord beweegt bij elke lus.

bolSerialBoard wordt gebruikt om het programma het bord naar de seriële monitor van de Arduino te laten sturen als een reeks getallen voor testdoeleinden.

Eindelijk is het tijd om ons bord als een array te declareren met behulp van deze code:

// stel game arrayint in 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} };

Een array is een matrix die elk punt waarop wiskunde kan worden aangeroepen of kan worden gewijzigd.

Je code zou er nu ongeveer zo uit moeten zien;

// include bibliotheken #include

// deze variabelen zijn opties die je kunt wijzigen - hogere getallen = snellere spelsnelheid

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

// Definieer pinnen

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

// maak LCD-objecten (n, ~, n, ~, ~, n)

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

// stel spelarray in

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

// variabelen instellen voor het spel

booleaanse bolPlay; //tracks als de speler int intScore; // volgt de score van de speler int intDiff; // gewoon een esthetisch ding om te vertellen op welke moeilijkheidsgraad het spel zich bevindt

//variabelen instellen voor invoer

int intEnter; // houdt bij of de gebruiker op de enter-knop drukt int intInput; // houdt bij op welke knoppen de gebruiker drukt boolean bolTilePressed; //zorg ervoor dat de speler niet per ongeluk 5x op een knop drukt en verliest

// variabelen instellen voor turn

int intTick; // telt millies (per lus) op tot intDelay int intDelay; // de tijd dat het programma wacht tot de volgende beurt in millis int intGameSpeed;

// een beetje debug-opties

booleaanse bolSerialBoard; //wanneer waar, wordt het bord in de seriële monitor afgedrukt

Stap 3: De Setup-functie

De setup-lus is een functie die door de Arduino slechts één keer wordt gelezen wanneer deze voor het eerst wordt gestart.

In de setup-lus stellen we alleen de waarden van een paar van onze variabelen in, want in plaats van ze een waarde in te stellen bij het declareren, doen we het hier.

Begin met het plaatsen van deze code in uw Void Setup.

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

Elke regel stelt gewoon een variabele in op een waarde.

bolPlay is ingesteld op false, zodat het spel niet begint te spelen.

intScore is ingesteld op 0, omdat je score natuurlijk begint bij 0.

intTick begint bij 0 omdat het programma momenteel niets telt.

intDelay is ingesteld op 1000 omdat dat de snelheid is waarmee de tegels beginnen.

intDiff is gewoon een ascetisch ding, zodat het programma weet wat het moet schrijven voor de moeilijkheidsgraad van het spel.

intGameSpeed is ingesteld op wat intGameSpeedMedium ook is, wat betekent dat het is ingesteld op de gemiddelde moeilijkheidsgraad.

Zet deze code vervolgens in de Void Setup onder de code die je zojuist hebt ingevoerd.

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

Serieel.begin(9600);

Dit vertelt de arduino om te beginnen met communiceren met de computer via de seriële monitor (zichtbaar door op de knop in de rechterbovenhoek van de arduino IDE te klikken).

Uw Void Setup zou er nu ongeveer zo uit moeten zien!

void setup() { Serial.begin(9600); //start de seriële monitor // stel de variabelen in bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; //begin lcd's lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

Stap 4: De lusfunctie

De lusfunctie wordt uitgevoerd door de arduino elke iteratie van de arduino.

Kopieer de volgende code naar je Void Loop.

void loop() { invoer(); // controleer voor het spelen van invoer if (bolPlay == true) {if (intTick >= intDelay){ // controleer of het spel een beurt moet spelen of moet blijven wachten Serial.println ("~~~~~~~ ~~");//print om aan te geven dat het bord verder gaat //writeSerial(); // als de optie is ingeschakeld, schrijf het bord in seriële buttonsGame(); // controleer op spelerinvoer playBoard (); // verplaats het bord en voeg een nieuwe tegel toe clearLcd(); // maak de LCD's schoon voordat je drawBoard tekent (); // teken het bord op de lcd's bottomCheck (); intTick = 0; // reset intTick } else { buttonsGame(); // controleer op spelerinvoer clearLcd (); // maak de LCD's schoon voordat je drawBoard () tekent; // teken het bord op de lcd's intTick = intTick + intGameSpeed; // voeg toe aan vink } } else { clearLcd (); // maak de LCD's schoon voordat je de titel tekent (); //display titel en score info buttonsMenu(); // lees spelerinvoer clearBoard (); // zorg ervoor dat het hele bord = 0} vertraging (10); // vertraag de Arduino met een kort moment}

wanneer bolPlay gelijk is aan true, betekent dit dat het spel aan het spelen is en dat alle code voor wanneer het spel wordt gespeeld moet worden uitgevoerd, maar we willen alleen dat het bord een nieuwe tegel toevoegt en naar beneden gaat wanneer intTick groter is dan onze intDelay, anders willen we de gebruiker nog steeds toestaan om op een knop te drukken om een tegel te raken en voor intTick om in snelheid te verhogen.

De meeste van deze code maakt gebruik van functies die we nog moeten maken, en we zullen ze in de volgende stappen maken. Het doel van deze functies is als volgt.

Input leest welke knoppen de gebruiker heeft ingedrukt.

buttonsGame bepaalt wat de knoppen doen in het spel, en niet in het menu

playBoard voegt een nieuwe tegel toe aan het bord en verplaatst vervolgens alles op het bord een veld naar beneden

clearLCD reinigt de LCD's om ervoor te zorgen dat er geen geesten achter de tegels achterblijven

drawBoard doorloopt arrGame en drukt het af op de LCD's

clearBoard wist het hele arrGame wanneer het spel niet in het spel is

bottomCheck controleert de onderkant van arrGame op een foutconditie

titel geeft de titel en score-informatie van het spel weer in het menu

knoppen menu regelt wat de invoer van de gebruiker doet in het menu.

gameOver is een andere functie, hoewel deze hier niet wordt aangeroepen, omdat deze in plaats daarvan wordt aangeroepen in de bottomCheck en buttonsGame-functies.

Stap 5: De ClearLCD-functie

om een functie te maken beginnen we door dit toe te voegen aan de code

ongeldige functienaam() {

}

de "functionName" kan van alles zijn, zolang het nog niet bestaat.

Kopieer deze code in je programma:

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

dit loopt door de hele array door 2 getelde lussen te gebruiken om door elk punt op de LCD's te gaan en een spatie te schrijven.

Zonder te worden gereset naar niets, behouden de LCD's alles wat eerder is geschreven

Stap 6: De DrawBoard-functie

kopieer deze code naar je programma

void drawBoard () { for (int i = 1; i <= 15; i++) { // teken kolommen 1 en 2 op het linker LCD-scherm // als de tegel = 0 niets schrijven, = 1 schrijven "#", = 2 schrijf "@" lcdLeft.setCursor(i, 1); // stel in op de eerste kolom (meest links) if (arrGame[0] == 1) {lcdLeft.write("#");} if (arrGame[0] == 2) {lcdLeft.write("@");} lcdLeft.setCursor(i, 0); // zet op de tweede kolom (midden links) if (arrGame[1] == 1) {lcdLeft.write("#");} if (arrGame[1] == 2) {lcdLeft.write("@");} lcdRight.setCursor(i, 1); // zet op de derde kolom (midden rechts) if (arrGame[2] == 1) {lcdRight.write("#");} if (arrGame[2] == 2) {lcdRight.write("@");} lcdRight.setCursor(i, 0); // zet op de vierde kolom (meest rechts) if (arrGame[3] == 1) {lcdRight.write("#");} if (arrGame[3] == 2) {lcdRight.schrijven("@");} } }

dit gebruikt een lus om door elke rij van het bord te gaan, het controleert vervolgens of een kolom in de rij gelijk is aan 1 of 2, op basis daarvan drukt het vervolgens op het LCD-scherm een hashtag af, voor een tegel die nog moet worden hit, of een @ voor een hittegel.

Stap 7: De PlayBoard-functie

kopieer deze code in je programma.

void playBoard() { for (int i = 0; i <= 3; i++){arrGame[0] = 0;} //wis de bovenste rij arrGame[0][random(0, 4)] = 1; // stel een willekeurig punt op de bovenste rij in als tegel voor (int i = 15; i>= 1; i--) { // werk van de onderkant van het bord naar de top voor (int ii = 0; ii <= 3; ii ++){ // voor elk collum arrGame[ii] = arrGame[i - 1][ii]; } } }

deze code begint met het wissen van de hele bovenste rij naar 0, of geen tegel, en stelt vervolgens een willekeurige tegel in op een 1, en een niet-gehitte tegel.

Het gaat dan door een getelde lus in omgekeerde richting, van 15 naar 1, waarbij de rij wordt ingesteld op gelijk aan wat de rij erboven gelijk is aan, waardoor het bord naar beneden beweegt op de LCD's

Stap 8: De ClearBoard-functie

kopieer deze code in je programma.

void clearBoard () {// reset tick and delay-waarden intTick = 0; intDelay = 1000; // ga door het bord en zet alles op 0 voor (int i = 0; i <= 15; i++){ for (int ii = 0; ii <= 3; ii++){ arrGame[ii] = 0; } } }

Deze code wordt uitgevoerd wanneer het spel niet speelt om ervoor te zorgen dat het geheel van arrGame is ingesteld op 0, of geen tegels, door getelde lussen te gebruiken om door de array te gaan.

De code stelt ook de waarden van intDelay en intTick opnieuw in.

Stap 9: de titelfunctie

kopieer de volgende code in je programma

void title () { // schrijf titel op LCD en ruimte voor score lcdRight.setCursor (0, 0); lcdRight.write("Pianotegels"); lcdRight.setCursor(0, 1); lcdRight.write("Score: "); // zet de partituur om in een string char strScore [3]; sprintf(strScore, "%d", intScore); // toon score op LCD lcdRight.write (strScore); // voeg de moeilijke lcdRight.setCursor (10, 1) toe; if (intDiff == 0){ lcdRight.write("Eenvoudig"); } if (intDiff == 1){ lcdRight.write("Medium"); } if (intDiff == 2){ lcdRight.write("Hard"); } //Druk op een klein beetje instructie lcdLeft.setCursor (0, 0); lcdLeft.write("Druk op Enter"); lcdLeft.setCursor(0, 1); lcdLeft.write("om te beginnen!"); }

Deze code schrijft de titel van het spel en de score op de LCD's, het doet dit door de LCD te vertellen waar te beginnen met typen met behulp van LCD.setCursor en vervolgens de tekenreeks in LCD.write te schrijven.

Hier wordt ook een nieuwe variabele gemaakt, strScore, die wordt gebruikt om intScore om te zetten in een string- of char-gegevenstype met behulp van de sprintf-functie.

intDiff wordt hier ook gebruikt, op basis van zijn waarden drukt het de verschillende moeilijkheidsgraden af.

Stap 10: De functie Knoppenmenu

plaats de volgende code in je programma:

void buttonsMenu(){ // wanneer enter wordt ingedrukt, start het spel en reset de scorewaarde if (intEnter == 1){ bolPlay = true; intScore = 0; speelbord(); tekenbord(); } // wanneer knop 3 wordt ingedrukt, schakelt u de foutopsporingsoptie in om het bord serieel af te drukken if (intInput == 3){ if (bolSerialBoard == false){ Serial.println ("Serial Board Active"); bolSerialBoard = waar; } else { Serial.println ("Seriële kaart uitgeschakeld"); bolSerialBoard = false; } } //stel de spelsnelheid in op gemakkelijk moeilijkheidsgraad if (intInput == 0){ Serial.print("Spel ingesteld op gemakkelijk ("); Serial.print(intGameSpeedEasy); Serial.println("ms versnelling)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // zet de spelsnelheid op gemiddelde moeilijkheidsgraad if (intInput == 1){ Serial.print("Spel ingesteld op medium ("); Serial.print(intGameSpeedMedium); Serial.println("ms versnelling)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // zet de spelsnelheid op moeilijk als (intInput == 2){ Serial.print("Spel ingesteld op hard ("); Serial.print(intGameSpeedHard); Serial.println("ms-versnelling)"); intDiff = 2; intGameSpeed = intGameSpeedHard; } }

deze code wordt alleen uitgevoerd wanneer bolPlay gelijk is aan false in de void Loop

als intEnter is ingesteld op 1 betekent dit dat de enter-knop is ingedrukt, als deze wordt ingedrukt, stelt het programma bolPlay in op true en begint het spel.

Het programma leest dan waar intInput gelijk aan is. als het gelijk is aan 0, wordt de eerste knop van links ingedrukt, naar rechts omhoog tot 3. Als intInput gelijk is aan 4, wordt er geen knop ingedrukt.

als de knoppen 0-2 worden ingedrukt, verandert de moeilijkheidsgraad van het spel, en past ook de waarde van de spelsnelheid aan, wat betekent dat het sneller zal versnellen.

als knop 3 wordt ingedrukt, activeert of deactiveert het spel een debug-modus waarbij het hele bord in de seriële monitor wordt afgedrukt om te helpen bij het vinden van problemen in het programma.

Stap 11: De ButtonsGame-functie

kopieer de volgende code in je programma

void buttonsGame(){ if (intInput != 4) { //als een knop wordt ingedrukt if (bolTilePressed == false){ // alleen als bolTilePressed false is triggeractie voor het controleren van een druk op een knop bolTilePressed = true; // stel vervolgens bolTilePressed in op true om ervoor te zorgen dat het niet opnieuw wordt geactiveerd int intLowestTile = 0; //in te stellen op de tegel met de laagste tegel int intCheckedTile = 15; // om bij te houden welke tegels zijn gecontroleerd terwijl (intLowestTile == 0) { // zolang het niet is ingesteld op iets controleer tegels voor (int i = 0; i 100) { // zo lang als int vertraging is niet lager dan 100 intDelay = intDelay - 20; // neem er een waarde van } } else { Serial.println ("Verkeerde knop ingedrukt"); spel is over(); //anders game over } } } } }

De code wordt alleen uitgevoerd wanneer bolPlay gelijk is aan true in de void Loop.

Like buttonsMenu gebaseerd op de waarde van intInput controleert het om te zien of de speler een tegel heeft geraakt of gemist.

Het doet dit door arrGame van onder naar boven te doorlopen met behulp van een while-lus om te kijken welke rij het laagst is met een niet-hittegel. Vervolgens wordt gecontroleerd of de plek in die rij die overeenkomt met de ingedrukte knop een niet-hittegel is of niet, als deze niet is geraakt, wordt deze gelijk aan 2 in plaats van 1, wat betekent dat deze wordt weergegeven als een @, anders wordt de gameOver functie die we nog moeten creëren.

Deze functie maakt ook gebruik van de bolTilePressed-variabele door deze in te stellen op true wanneer een knop wordt ingedrukt en op false wanneer er geen knop wordt ingedrukt. Dit is om ervoor te zorgen dat de gebruiker niet per ongeluk het spel verliest omdat het programma dacht dat ze de knop meerdere keren ingedrukt hadden gehouden.

Stap 12: De GameOver-functie

Kopieer de volgende code in je programma

void gameOver() { Serial.println("Game Over!"); Serial.print("Je score was: "); Serial.println(intScore); Serial.print("Je snelheid was: "); Serial.println(intDelay); bolPlay = onwaar; }

Dit wordt geactiveerd door ofwel de checkBottom of buttonsGame-functies en activeert het einde van het spel door bolPlay in te stellen op false.

Het drukt ook een bericht af in de seriële monitor voor de gebruikersscore en de snelheidstegels werden in milliseconden toegevoegd.

Stap 13: De invoerfunctie

Kopieer de volgende code in je programma.

void input () { intEnter = digitalRead (btnEnter); //lees voer in // lees welke van de andere ingangen, of als er geen is ingesteld op 4 if (digitalRead(btn1) == HIGH){intInput = 0;} else { if (digitalRead(btn2) == HIGH){intInput = 1;} else {if (digitalRead(btn3) == HOOG){intInput = 2;} else {if (digitalRead(btn4) == HOOG){intInput = 3;} else {intInput = 4; }}}} //serial print de invoer if (intEnter == 1){Serial.println("Enter Pressed! ");} if (intInput != 4){ Serial.print("Button Press: "); Seriële.println(intInput); } else { // als er geen knop wordt ingedrukt reset bolTilePressed bolTilePressed = false; } }

Deze code wordt gebruikt bij de buttonsGame en buttonsMenu functies. op basis van de knoppen die de gebruiker heeft ingedrukt, wordt de waarde van intInput ingesteld, of als er geen knop wordt ingedrukt, wordt intInput gelijk gesteld aan 4.

Als er geen knop wordt ingedrukt, wordt hier BolTilePressed gereset voor de knoppenGame-functie.

Het drukt ook een bericht af op de seriële monitor waarop de knop wordt ingedrukt.

Stap 14: De BottomCheck-functie

kopieer de volgende code naar je programma.

void bottomCheck() { for (int i = 0; i <= 3; i++){ // for the 4 collumns if (arrGame [15] == 1){ // if a tile is at the bottom Serial.println("Tegel onderaan"); arrGame[15] = 2; tekenbord(); vertraging (400); arrGame[15] = 1; tekenbord(); vertraging (400); arrGame[15] = 2; tekenbord(); vertraging (400); arrGame[15] = 1; tekenbord(); vertraging (400); spel is over(); } } }

met behulp van een lus controleert deze code de onderste rij van arrGame op niet-hittegels (tegels gelijk aan 1). Als er een niet-hittegel onder aan het scherm is, zal de tegel knipperen en vervolgens de game over-functie activeren.

Stap 15: De WriteSerial-functie

kopieer de volgende code in je programma

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

Dit is de functie gevolgd door de debug-optie die kan worden ingeschakeld in de functie buttonsMenu. Als bolSerialBoard is ingesteld op true in die functie, gaat het door arrGame en drukt het hele bord af naar de seriële monitor voor testdoeleinden met behulp van een array.

Stap 16: Voltooiing

Voltooiing!
Voltooiing!

Al uw code mag niet compleet zijn en er ongeveer zo uitzien!

/* * Naam - Pianotegels; Arduino * Door - Domenic Marulli * Datum - 11/*

/ bibliotheken opnemen

#erbij betrekken

// deze variabelen zijn opties die je kunt wijzigen - hogere getallen = snellere spelsnelheid

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

// Definieer pinnen

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

// maak LCD-objecten (n, ~, n, ~, ~, n)

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

// stel spelarray in

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

// variabelen instellen voor het spel

booleaanse bolPlay; //tracks als de speler int intScore; // volgt de score van de speler int intDiff; // gewoon een esthetisch ding om te vertellen op welke moeilijkheidsgraad het spel zich bevindt

//variabelen instellen voor invoer

int intEnter; // houdt bij of de gebruiker op de enter-knop drukt int intInput; // houdt bij op welke knoppen de gebruiker drukt boolean bolTilePressed; //zorg ervoor dat de speler niet per ongeluk 5x op een knop drukt en verliest

// variabelen instellen voor turn

int intTick; // telt millies (per lus) op tot intDelay int intDelay; // de tijd dat het programma wacht tot de volgende beurt in millis int intGameSpeed;

// een beetje debug-opties

booleaanse bolSerialBoard; //wanneer waar, wordt het bord in de seriële monitor afgedrukt

//de setup die een keer wordt uitgevoerd

void setup() { Serial.begin(9600); //start de seriële monitor // stel de variabelen in bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; //begin lcd's lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

//de lus die elke 10 milliseconden wordt uitgevoerd

void loop() { invoer(); // controleer voor het spelen van invoer if (bolPlay == true) {if (intTick >= intDelay){ // controleer of het spel een beurt moet spelen of moet blijven wachten Serial.println ("~~~~~~~ ~~");//print om aan te geven dat het bord verder gaat //writeSerial(); // als de optie is ingeschakeld, schrijf het bord in seriële buttonsGame(); // controleer op spelerinvoer playBoard (); // verplaats het bord en voeg een nieuwe tegel toe clearLcd(); // maak de LCD's schoon voordat je drawBoard () tekent; // teken het bord op de lcd's bottomCheck (); intTick = 0; // reset intTick } else { buttonsGame(); // controleer op spelerinvoer clearLcd (); // maak de LCD's schoon voordat je drawBoard () tekent; // teken het bord op de lcd's intTick = intTick + intGameSpeed; // voeg toe aan vink } } else { clearLcd (); // maak de LCD's schoon voordat je de titel tekent (); //display titel en score info buttonsMenu(); // lees spelerinvoer clearBoard (); // zorg ervoor dat het hele bord = 0} vertraging (10); // vertraag de Arduino met een kort moment}

// reinigt het lcd-scherm, zodat niet-ingevoerde cellen daar niet achterblijven

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

// tekent het bord op de lcd's

void drawBoard () { for (int i = 1; i <= 15; i++) { // teken kolommen 1 en 2 op het linker LCD-scherm // als de tegel = 0 niets schrijven, = 1 schrijven "#", = 2 schrijf "@" lcdLeft.setCursor(i, 1); // stel in op de eerste kolom (meest links) if (arrGame[0] == 1) {lcdLeft.write("#");} if (arrGame[0] == 2) {lcdLeft.write("@");} lcdLeft.setCursor(i, 0); // zet op de tweede kolom (midden links) if (arrGame[1] == 1) {lcdLeft.write("#");} if (arrGame[1] == 2) {lcdLeft.write("@");} lcdRight.setCursor(i, 1); // zet op de derde kolom (midden rechts) if (arrGame[2] == 1) {lcdRight.write("#");} if (arrGame[2] == 2) {lcdRight.write("@");} lcdRight.setCursor(i, 0); // zet op de vierde kolom (meest rechts) if (arrGame[3] == 1) {lcdRight.write("#");} if (arrGame[3] == 2) {lcdRight.schrijven("@");} } }

// verplaatst het bord naar beneden en plaatst een willekeurige waarde als tegel

void playBoard() { for (int i = 0; i <= 3; i++){arrGame[0] = 0;} //wis de bovenste rij arrGame[0][random(0, 4)] = 1; // stel een willekeurig punt op de bovenste rij in als tegel voor (int i = 15; i>= 1; i--) { // werk van de onderkant van het bord naar de top voor (int ii = 0; ii <= 3; ii ++){ // voor elk collum arrGame[ii] = arrGame[i - 1][ii]; } } }

// zet het hele bord op 0 en zet variabelen terug naar pregame

void clearBoard () {// reset tick and delay-waarden intTick = 0; intDelay = 1000; // ga door het bord en zet alles op 0 voor (int i = 0; i <= 15; i++){ for (int ii = 0; ii <= 3; ii++){ arrGame[ii] = 0; } } }

// geeft het hoofdmenu weer op de LCD's

void title () { // schrijf titel op LCD en ruimte voor score lcdRight.setCursor (0, 0); lcdRight.write("Pianotegels"); lcdRight.setCursor(0, 1); lcdRight.write("Score: "); // zet de partituur om in een string char strScore [3]; sprintf(strScore, "%d", intScore); // toon score op LCD lcdRight.write (strScore); // voeg de moeilijke lcdRight.setCursor (10, 1) toe; if (intDiff == 0){ lcdRight.write("Eenvoudig"); } if (intDiff == 1){ lcdRight.write("Medium"); } if (intDiff == 2){ lcdRight.write("Hard"); } //Druk op een klein beetje instructie lcdLeft.setCursor (0, 0); lcdLeft.write("Druk op Enter"); lcdLeft.setCursor(0, 1); lcdLeft.write("om te beginnen!"); }

// controleert de knoppen en wat ze moeten doen als het spel niet beschikbaar is

void buttonsMenu(){ // wanneer enter wordt ingedrukt, start het spel en reset de scorewaarde if (intEnter == 1){ bolPlay = true; intScore = 0; speelbord(); tekenbord(); } // wanneer knop 3 wordt ingedrukt, schakelt u de foutopsporingsoptie in om het bord serieel af te drukken if (intInput == 3){ if (bolSerialBoard == false){ Serial.println ("Serial Board Active"); bolSerialBoard = waar; } else { Serial.println ("Seriële kaart uitgeschakeld"); bolSerialBoard = false; } } //stel de spelsnelheid in op gemakkelijk moeilijkheidsgraad if (intInput == 0){ Serial.print("Spel ingesteld op gemakkelijk ("); Serial.print(intGameSpeedEasy); Serial.println("ms versnelling)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // zet de spelsnelheid op gemiddelde moeilijkheidsgraad if (intInput == 1){ Serial.print("Spel ingesteld op medium ("); Serial.print(intGameSpeedMedium); Serial.println("ms versnelling)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // zet de spelsnelheid op moeilijk als (intInput == 2){ Serial.print("Spel ingesteld op hard ("); Serial.print(intGameSpeedHard); Serial.println("ms-versnelling)"); intDiff = 2; intGameSpeed = intGameSpeedHard; } }

// controleert de knoppen en wat te doen tijdens het spel

void buttonsGame(){ if (intInput != 4) { //als een knop wordt ingedrukt if (bolTilePressed == false){ // alleen als bolTilePressed false is triggeractie voor het controleren van een druk op een knop bolTilePressed = true; // stel vervolgens bolTilePressed in op true om ervoor te zorgen dat het niet opnieuw wordt geactiveerd int intLowestTile = 0; //in te stellen op de tegel met de laagste tegel int intCheckedTile = 15; // om bij te houden welke tegels zijn gecontroleerd terwijl (intLowestTile == 0) { // zolang het niet is ingesteld op iets controleer tegels voor (int i = 0; i 100) { // zo lang als int vertraging is niet lager dan 100 intDelay = intDelay - 20; // neem er een waarde van } } else { Serial.println ("Verkeerde knop ingedrukt"); spel is over(); //anders game over } } } } }

void gameOver() {

Serial.println ("Game Over!"); Serial.print("Je score was: "); Serial.println(intScore); Serial.print("Je snelheid was: "); Serial.println(intDelay); bolPlay = onwaar; }

// controleert op spelersinvoer

void input () { intEnter = digitalRead (btnEnter); //lees voer in // lees welke van de andere ingangen, of als er geen is ingesteld op 4 if (digitalRead(btn1) == HIGH){intInput = 0;} else { if (digitalRead(btn2) == HIGH){intInput = 1;} else {if (digitalRead(btn3) == HOOG){intInput = 2;} else {if (digitalRead(btn4) == HOOG){intInput = 3;} else {intInput = 4; }}}} //serial print de invoer if (intEnter == 1){Serial.println("Enter Pressed! ");} if (intInput != 4){ Serial.print("Button Press: "); Seriële.println(intInput); } else { // als er geen knop wordt ingedrukt reset bolTilePressed bolTilePressed = false; } }

//controleert de onderkant van het bord op fouten

void bottomCheck() { for (int i = 0; i <= 3; i++){ // for the 4 collumns if (arrGame [15] == 1){ // if a tile is at the bottom Serial.println("Tegel onderaan"); arrGame[15] = 2; tekenbord(); vertraging (400); arrGame[15] = 1; tekenbord(); vertraging (400); arrGame[15] = 2; tekenbord(); vertraging (400); arrGame[15] = 1; tekenbord(); vertraging (400); spel is over(); } } }

// drukt het bord af in de seriële monitor als bolSerialBoard waar is

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

Zodra alle code is ingevoerd, uploadt u naar uw arduino en geniet u ervan!

Aanbevolen: