Kazalo:

Arduino-nadzorovana igra platforme z igralno palico in IR sprejemnikom: 3 koraki (s slikami)
Arduino-nadzorovana igra platforme z igralno palico in IR sprejemnikom: 3 koraki (s slikami)

Video: Arduino-nadzorovana igra platforme z igralno palico in IR sprejemnikom: 3 koraki (s slikami)

Video: Arduino-nadzorovana igra platforme z igralno palico in IR sprejemnikom: 3 koraki (s slikami)
Video: Переработка энкодера колеса прокрутки мыши и его тестирование с помощью Arduino Nano 2024, November
Anonim
Arduino nadzorovana igra platforme z igralno palico in IR sprejemnikom
Arduino nadzorovana igra platforme z igralno palico in IR sprejemnikom

Danes bomo uporabili mikrokrmilnik Arduino za nadzor preproste platformerske igre na osnovi C#. Arduino uporabljam za prevzem vnosa iz modula krmilne palice in pošiljanje tega vnosa v aplikacijo C#, ki posluša in dekodira vnos prek serijske povezave. Čeprav za dokončanje projekta ne potrebujete nobenih predhodnih izkušenj pri ustvarjanju video iger, bo morda trajalo nekaj časa, da se absorbirajo nekatere stvari, ki se dogajajo v "zanki igre", o kateri bomo razpravljali kasneje.

Za dokončanje tega projekta boste potrebovali:

  • Skupnost Visual Studio
  • Arduino Uno (ali podobno)
  • Krmilni modul krmilne palice
  • Potrpežljivost

Če ste pripravljeni na začetek, nadaljujte!

1. korak: Priključite igralno palico in IR LED

Priključite krmilno palčko in IR LED
Priključite krmilno palčko in IR LED
Priključite krmilno palčko in IR LED
Priključite krmilno palčko in IR LED

Tu je povezava dokaj preprosta. Vključil sem diagrame, ki prikazujejo samo priključeno igralno palico, pa tudi nastavitve, ki jih uporabljam, ki vključujejo igralno palico in infrardečo LED za nadzor igre z daljinskim upravljalnikom, ki je priložen številnim kompletom Arduino. To ni obvezno, vendar se mi je zdela kul ideja, da bi lahko igral brezžično.

Pri namestitvi so uporabljeni zatiči:

  • A0 (analogno) <- Vodoravno ali osi X
  • A1 (analogno) <- Navpična ali Y-os
  • Pin 2 <- Vhod stikala za krmilno palčko
  • Pin 2 <- Infrardeči LED vhod
  • VCC <- 5V
  • Tla
  • Tla #2

2. korak: Ustvarite novo skico

Ustvarite novo skico
Ustvarite novo skico

Začeli bomo z ustvarjanjem naše skice Arduino. Ta poišče krmilno palčko za spremembe in te spremembe pošlje v program C# vsakih nekaj milisekund. V dejanski videoigri bi serijska vrata v zanki igre preverili za vnos, vendar sem igro začel kot poskus, zato hitrost sličic dejansko temelji na številu dogodkov na serijskih vratih. Projekt sem pravzaprav začel v sestrinskem projektu Arduino, Processing, vendar se je izkazalo, da je bil veliko, veliko počasnejši in nisem mogel obvladati števila škatel na zaslonu.

Torej, najprej ustvarite novo skico v programu za urejanje kod Arduino. Pokazal bom svojo kodo in nato razložil, kaj počne:

#include "IRremote.h"

// IR spremenljivke int sprejemnik = 3; // Signalni pin IR sprejemnika IRrecv unrecv (sprejemnik); // ustvari primerek 'unrecv' decode_results rezultatov; // ustvari primerek 'decode_results' // Igralna palica/spremenljivke igre int xPos = 507; int yPos = 507; bajt joyXPin = A0; bajt veseljeYPin = A1; bajt joySwitch = 2; hlapni bajt clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // Privzeto = povprečna hitrost int speedIncrement = 25; // Znesek za povečanje/zmanjšanje hitrosti z Y vhodom brez podpisa dolg tok = 0; // Zadržuje trenutni časovni žig int wait = 40; // ms za čakanje med sporočili [Opomba: nižje čakanje = hitrejša hitrost sličic] volatile bool buttonPressed = false; // Merimo, če je gumb pritisnjen void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, skok, PADANJE); tok = milis (); // Nastavitev trenutnega časa // Nastavitev infrardečega sprejemnika: unrecv.enableIRIn (); // Zagon sprejemnika} // nastavitev void loop () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Ročaj Joystick X premaknite ne glede na čas: if (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Če bi se le malo premaknilo …? currentSpeed //… samo vrnite trenutno hitrost: getSpeed (yPos); // yPos spremenite le, če se krmilna palica močno premakne // int distance =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); tok = milis (); }} // zanka int getSpeed (int yPos) {// Negativne vrednosti označujejo, da je igralna ročica premaknjena navzgor, če (yPos 1023? 1023: currentSpeed + speedIncrement;} drugače, če (yPos> minMoveHigh) // Interpretirano "navzdol" {// zaščiti pred gre pod 0 vrnitev currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // tipka za označbo je bila pritisnjena.} // skok // ko je gumb pritisnjen na daljinsko, ročaj z ustreznim odzivom void translateIR (decode_results results) // ukrepa na podlagi prejete IR kode {switch (results.value) {case 0xFF18E7: //Serial.println(" 2 "); currentSpeed += speedIncrement * 2; break; primer 0xFF10EF: //Serial.println(" 4 "); xPos = -900; break; primer 0xFF38C7: //Serial.println(" 5"); jump (); break; primer 0xFF5AA5: // Serijski. println ("6"); xPos = 900; break; primer 0xFF4AB5: //Serial.println(" 8 "); currentSpeed -= speedIncrement * 2; break; privzeto: //Serial.println (" drug gumb "); break;} // Končno stikalo} // END translateIR

Poskušal sem ustvariti kodo, ki je večinoma samoumevna, vendar je treba omeniti nekaj stvari. Ena stvar, ki sem jo poskušal pojasniti, je bila v naslednjih vrsticah:

int minYMoveUp = 520;

int minYMoveDown = 500;

Ko se program izvaja, analogni vhod iz krmilne palice ponavadi skače, običajno ostane pri približno 507. Če želite to popraviti, se vhod ne spremeni, razen če je večji od minYMoveUp ali manjši od minYMoveDown.

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, skok, PADANJE);

Metoda attachInterrupt () nam omogoča, da kadar koli prekinemo običajno zanko, tako da lahko vnesemo vnos, na primer pritisk gumba ob pritisku gumba krmilne palice. Tu smo prekinitev priložili v vrstico pred njo z uporabo metode pinMode (). Pomembna opomba pri tem je, da morate za priključitev prekinitve na Arduino Uno uporabiti bodisi pin 2 ali 3. Drugi modeli uporabljajo različne zatiče, zato boste morda morali preveriti, katere zatiče vaš model uporablja na spletnem mestu Arduino. Drugi parameter je za metodo povratnega klica, ki se tukaj imenuje ISR ali "rutina prekinitve storitev". Ne sme sprejeti nobenih parametrov ali vrniti ničesar.

Serial.print (…)

To je vrstica, ki bo pošiljala naše podatke v igro C#. Tukaj v igro pošljemo odčitavanje osi X, odčitavanje osi Y in spremenljivko hitrosti. Te odčitke lahko razširimo tako, da vključimo druge vložke in odčitke, da bi bila igra bolj zanimiva, tukaj pa bomo uporabili le nekaj.

Če ste pripravljeni preizkusiti svojo kodo, jo naložite v Arduino in pritisnite [Shift] + [Ctrl] + [M], da odprete serijski monitor in preverite, ali imate kakšen izhod. Če prejemate podatke iz Arduina, smo pripravljeni preiti na del kode C# …

3. korak: Ustvarite projekt C#

Za prikaz naše grafike sem sprva začel projekt v obdelavi, kasneje pa sem se odločil, da bi bilo prepočasi prikazovati vse predmete, ki jih moramo prikazati. Zato sem se odločil za uporabo C#, ki se je izkazal za veliko bolj gladko in bolj odzivno pri obravnavi našega vnosa.

Za del projekta C# je najbolje, da preprosto prenesete datoteko.zip in jo izvlečete v svojo mapo, nato pa jo spremenite. V datoteki zip sta dve mapi. Če želite odpreti projekt v Visual Studiu, v Raziskovalcu vnesite mapo RunnerGame_CSharp. Tukaj dvokliknite datoteko.sln (rešitev) in VS bo naložil projekt.

Za igro sem ustvaril nekaj različnih razredov. Ne bom se spuščal v vse podrobnosti o vsakem razredu, bom pa dal pregled, čemu so namenjeni glavni razredi.

Razred škatle

Ustvaril sem razred box, ki vam omogoča ustvarjanje preprostih pravokotnih predmetov, ki jih lahko narišete na zaslonu v obliki oken. Ideja je ustvariti razred, ki ga je mogoče razširiti z drugimi razredi, ki bi morda želeli narisati nekakšno grafiko. Ključna beseda "virtual" se uporablja tako, da jih lahko drugi razredi preglasijo (s ključno besedo "override"). Na ta način lahko dobimo enako vedenje za razred Player in razred Platform, kadar je to potrebno, in tudi spremenimo predmete, kot jih potrebujemo.

Ne skrbite preveč za vse nepremičnine in kličite. Ta razred sem napisal, da bi ga lahko razširil za katero koli igro ali grafični program, ki bi ga morda želel narediti v prihodnosti. Če morate na hitro narisati pravokotnik, vam ni treba zapisati velikega razreda, kot je ta. Dokumentacija C# ima dobre primere, kako to storiti.

Vendar bom predstavil nekaj logike svojega razreda "Box":

javni navidezni bool IsCollidedX (Box otherObject) {…}

Tu preverimo trke s predmeti v smeri X, saj mora igralec le preveriti trke v smeri Y (gor in dol), če je z njim poravnan na zaslonu.

javni navidezni bool IsCollidedY (polje otherObject) {…}

Ko smo nad ali pod drugim objektom igre, preverimo, ali obstajajo trki Y.

javni navidezni bool IsCollided (polje otherObject) {…}

Ta združuje trke X in Y, pri čemer se prikaže, ali je s tem trčen kateri koli predmet.

javna virtualna praznina OnPaint (grafična grafika) {…}

Z zgornjo metodo posredujemo kateri koli grafični objekt in ga uporabljamo med izvajanjem programa. Ustvarjamo vse pravokotnike, ki jih bo morda potrebno narisati. To bi lahko uporabili za različne animacije. Za naše namene se bodo pravokotniki dobro odrezali tako na platformah kot na predvajalniku.

Razred znakov

Razred Character razširja moj razred Box, zato imamo določeno fiziko izven škatle. Ustvaril sem metodo "CheckForCollisions" za hitro preverjanje vseh platform, ki smo jih ustvarili glede trka. Metoda "Jump" nastavi igralčevo hitrost navzgor na spremenljivko JumpSpeed, ki se nato okvirno po okvirju spreminja v razredu MainWindow.

Trki se tukaj obravnavajo nekoliko drugače kot v razredu Box. V tej igri sem se odločil, da lahko, če skočimo navzgor, skočimo skozi platformo, vendar bo našega igralca ujela na poti navzdol, če bo trčila z njo.

Razred platforme

V tej igri uporabljam samo konstruktor tega razreda, ki za vnos vzame koordinato X in izračuna vse lokacije X platform v razredu MainWindow. Vsaka platforma je nastavljena na naključni Y-koordinati od 1/2 zaslona do 3/4 višine zaslona. Višina, širina in barva so tudi naključno ustvarjene.

Razred MainWindow

Tu postavimo vso logiko, ki jo bomo uporabili med igranjem. Najprej v konstruktorju natisnemo vsa vrata COM, ki so na voljo programu.

foreach (vrata niza v SerialPort. GetPortNames ())

Console. WriteLine ("AVAILABLE PORTS:" + port);

Izberemo, na katerem bomo sprejeli komunikacijo, glede na vrata, ki jih vaš Arduino že uporablja:

SerialPort = nov SerialPort (SerialPort. GetPortNames () [2], 9600, Parity. None, 8, StopBits. One);

Bodite pozorni na ukaz: SerialPort. GetPortNames () [2]. [2] pomeni, katera serijska vrata uporabiti. Na primer, če bi program natisnil "COM1, COM2, COM3", bi poslušali COM3, ker se oštevilčenje začne pri 0 v matriki.

Tudi v konstruktorju ustvarimo vse platforme s pol-naključnim razmikom in postavitvijo v smeri Y na zaslonu. Vse platforme so dodane objektu List, ki je v C# preprosto zelo uporabniku prijazen in učinkovit način za upravljanje matrične strukture podatkov. Nato ustvarimo Player, ki je naš predmet Character, nastavimo rezultat na 0 in GameOver nastavimo na false.

zasebna statična praznina DataReceived (pošiljatelj objekta, SerialDataReceivedEventArgs e)

To je metoda, ki se pokliče ob prejemu podatkov na serijska vrata. Tu uporabimo vso svojo fiziko, se odločimo, ali bomo igro prikazali, premaknili platforme itd. Če ste kdaj ustvarili igro, imate na splošno tako imenovano "zanko igre", ki se pokliče vsakič, ko okvir osveži. V tej igri metoda DataReceived deluje kot zanka igre, samo manipulira s fiziko, ko podatki prejemajo od krmilnika. Morda bi bilo bolje, če bi v glavnem oknu nastavili časovnik in osvežili predmete na podlagi prejetih podatkov, a ker je to projekt Arduino, sem želel narediti igro, ki je dejansko tekla na podlagi podatkov, ki prihajajo iz nje.

Skratka, ta postavitev daje dobro osnovo za razširitev igre v nekaj uporabnega. Čeprav fizika ni povsem popolna, za naše namene deluje dovolj dobro, to je, da Arduino uporabimo za nekaj, kar je vsem všeč: igranje iger!

Priporočena: