Cuprins:
- Pasul 1: Conectați joystick-ul și LED-ul IR
- Pasul 2: Creați o schiță nouă
- Pasul 3: Creați proiectul C #
Video: Joc de platformă controlat de Arduino cu joystick și receptor IR: 3 pași (cu imagini)
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:46
Astăzi, vom folosi un microcontroler Arduino pentru a controla un simplu joc platformer bazat pe C #. Folosesc Arduino pentru a prelua intrarea de la un modul joystick și a trimite acea intrare către aplicația C # care ascultă și decodează intrarea printr-o conexiune Serial. Deși nu aveți nevoie de experiență anterioară în construirea de jocuri video pentru a finaliza proiectul, poate necesita ceva timp pentru a absorbi unele dintre lucrurile care se întâmplă în „bucla jocului”, despre care vom discuta mai târziu.
Pentru a finaliza acest proiect, veți avea nevoie de:
- Comunitatea Visual Studio
- Un Arduino Uno (sau similar)
- Un modul de control al joystick-ului
- Răbdare
Dacă sunteți gata să începeți, continuați!
Pasul 1: Conectați joystick-ul și LED-ul IR
Aici, conectarea este destul de simplă. Am inclus diagrame care arată doar joystick-ul conectat, precum și configurarea pe care o folosesc, care include joystick-ul plus un LED cu infraroșu pentru controlul jocului cu o telecomandă, care vine cu multe kituri Arduino. Acest lucru este opțional, dar mi s-a părut o idee interesantă să poți face jocuri wireless.
Pinii utilizați în configurare sunt:
- A0 (analog) <- Axa orizontală sau X
- A1 (analogic) <- Axa verticală sau Y
- Pinul 2 <- Intrare comutator joystick
- Pin 2 <- Intrare LED cu infraroșu
- VCC <- 5V
- Sol
- Terenul # 2
Pasul 2: Creați o schiță nouă
Vom începe cu crearea fișierului nostru de schiță Arduino. Aceasta sondează joystick-ul pentru modificări și trimite aceste modificări programului C # la fiecare câteva milisecunde. Într-un joc video propriu-zis, am verifica portul serial într-o buclă de joc pentru intrare, dar am început jocul ca un experiment, deci frecvența se bazează de fapt pe numărul de evenimente de pe portul serial. De fapt, începusem proiectul în cadrul proiectului sora Arduino, Procesare, dar se pare că a fost mult, mult mai lent și nu putea rezolva numărul de cutii de pe ecran.
Deci, mai întâi creați o nouă schiță în programul de editare a codului Arduino. Îmi voi arăta codul și apoi voi explica ce face:
#include „IRremote.h”
// Variabile IR int receptor = 3; // Pinul de semnal al receptorului IR IRrecv irrecv (receptor); // creați instanța rezultatelor 'irrecv' decode_results; // creați instanța „decode_results” // Joystick / variabile de joc int xPos = 507; int yPos = 507; octet joyXPin = A0; octet joyYPin = A1; octet joySwitch = 2; octet volatil clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int CurrentSpeed = 550; // Implicit = o viteză medie int speedIncrement = 25; // Suma pentru creșterea / scăderea vitezei cu intrarea Y curent lung nesemnat = 0; // Păstrează timestamp curent int wait = 40; // ms pentru a aștepta între mesaje [Notă: așteptare mai mică = framerate mai rapid] buton volatil bool Apăsat = fals; // Măsurați dacă butonul este apăsat setare nulă () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, jump, FALLING); curent = milis (); // Configurați ora curentă // Configurați receptorul infraroșu: irrecv.enableIRIn (); // Porniți receptorul} // setup void loop () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Manevrați mișcarea Joystick X indiferent de momentul: if (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Dacă s-ar muta doar puțin …? currentSpeed // … doar returnează viteza curentă: getSpeed (yPos); // Schimbați yPos numai dacă joystick-ul s-a mutat semnificativ // int distance =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); curent = milis (); }} // buclă int getSpeed (int yPos) {// Valorile negative indică joystick-ul deplasat în sus dacă (yPos 1023? 1023: currentSpeed + speedIncrement;} else if (yPos> minMoveHigh) // Interpretat „Down” {// Protejați de mergând sub 0 return currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Indicați butonul a fost apăsat.} // jump // Când este apăsat un buton pe la distanță, gestionați răspunsul corespunzător void translateIR (decode_results results) // ia măsuri pe baza codului IR primit {switch (results.value) {case 0xFF18E7: //Serial.println("2 "); currentSpeed + = speedIncrement * 2; break; case 0xFF10EF: //Serial.println("4 "); xPos = -900; break; case 0xFF38C7: //Serial.println("5"); jump (); break; case 0xFF5AA5: // Serial. println ("6"); xPos = 900; break; case 0xFF4AB5: //Serial.println("8 "); currentSpeed - = speedIncrement * 2; break; implicit: //Serial.println (" alt buton "); pauză;} // Comutator de sfârșit} // ÎNCHEI traducereIR
Am încercat să creez codul pentru a fi în mare parte auto-explicativ, dar sunt câteva lucruri demne de menționat. Un lucru pe care am încercat să-l explic a fost în următoarele rânduri:
int minYMoveUp = 520;
int minYMoveDown = 500;
Când programul rulează, intrarea analogică de la joystick tinde să sară în jur, rămânând de obicei la aproximativ 507. Pentru a corecta acest lucru, intrarea nu se schimbă decât dacă este mai mare decât minYMoveUp sau mai mică decât minYMoveDown.
pinMode (joySwitch, INPUT_PULLUP);
attachInterrupt (0, jump, FALLING);
Metoda attachInterrupt () ne permite să întrerupem bucla normală în orice moment, astfel încât să putem prelua date, cum ar fi apăsarea butonului când se face clic pe butonul joystick-ului. Aici am atașat întreruperea în linia dinaintea ei, folosind metoda pinMode (). O notă importantă aici este că pentru a atașa o întrerupere pe Arduino Uno, trebuie să utilizați fie pinul 2, fie 3. Alte modele utilizează pini de întrerupere diferiți, deci poate fi necesar să verificați ce pini utilizează modelul dvs. pe site-ul web Arduino. Al doilea parametru este pentru metoda de apel invers, numită aici un ISR sau o „rutină de întrerupere a serviciului”. Nu ar trebui să ia parametri sau să returneze nimic.
Serial.print (…)
Aceasta este linia care ne va trimite datele către jocul C #. Aici, trimitem jocului citirea axei X, citirea axei Y și o variabilă de viteză. Aceste citiri pot fi extinse pentru a include alte intrări și citiri pentru a face jocul mai interesant, dar aici vom folosi doar câteva.
Dacă sunteți gata să vă testați codul, încărcați-l pe Arduino și apăsați [Shift] + [Ctrl] + [M] pentru a deschide monitorul serial și a vedea dacă obțineți ieșiri. Dacă primiți date de la Arduino, suntem gata să trecem la partea C # a codului …
Pasul 3: Creați proiectul C #
Pentru a afișa grafica noastră, am început inițial un proiect în Procesare, dar ulterior am decis că ar fi prea lent să arăt toate obiectele pe care trebuie să le afișăm. Așadar, am ales să folosesc C #, care s-a dovedit a fi mult mai ușor și mai receptiv la manipularea informațiilor noastre.
Pentru partea C # a proiectului, cel mai bine este să descărcați pur și simplu fișierul.zip și să îl extrageți în propriul folder, apoi să îl modificați. Există două dosare în fișierul zip. Pentru a deschide proiectul în Visual Studio, introduceți folderul RunnerGame_CSharp în Windows Explorer. Aici, faceți dublu clic pe fișierul.sln (soluție), iar VS va încărca proiectul.
Există câteva clase diferite pe care le-am creat pentru joc. Nu voi intra în toate detaliile despre fiecare clasă, dar voi oferi o imagine de ansamblu a ceea ce sunt clasele principale.
Clasa Box
Am creat clasa casetă pentru a vă permite să creați obiecte dreptunghiulare simple care pot fi desenate pe ecran într-o formă de ferestre. Ideea este de a crea o clasă care poate fi extinsă folosind alte clase care ar putea dori să deseneze un fel de grafică. Cuvântul cheie „virtual” este utilizat astfel încât alte clase să le suprascrie (folosind cuvântul cheie „suprascrie”). În acest fel, putem obține același comportament pentru clasa Player și clasa Platform atunci când avem nevoie și, de asemenea, putem modifica obiectele oricum ar trebui.
Nu vă faceți griji prea mult cu privire la toate proprietățile și trageți apeluri. Am scris această clasă, astfel încât să o pot extinde pentru orice joc sau program grafic pe care aș vrea să îl realizez în viitor. Dacă trebuie să desenați pur și simplu un dreptunghi din mers, nu trebuie să scrieți o clasă mare ca aceasta. Documentația C # conține exemple bune despre cum să faceți acest lucru.
Cu toate acestea, voi expune o parte din logica clasei mele „Box”:
public virtual bool IsCollidedX (Caseta otherObject) {…}
Aici verificăm dacă există coliziuni cu obiecte în direcția X, deoarece jucătorul trebuie să verifice dacă există coliziuni în direcția Y (în sus și în jos) dacă este aliniat cu acesta pe ecran.
public virtual bool IsCollidedY (Caseta otherObject) {…}
Când suntem peste sau sub un alt obiect de joc, verificăm dacă există coliziuni Y.
public virtual bool IsCollided (Caseta otherObject) {…}
Aceasta combină coliziunile X și Y, returnând dacă vreun obiect este ciocnit cu acesta.
gol virtual virtual OnPaint (grafică grafică) {…}
Folosind metoda de mai sus, trecem orice obiect grafic și îl folosim pe măsură ce programul rulează. Creăm orice dreptunghi care ar putea fi necesar să fie desenat. Totuși, aceasta ar putea fi utilizată pentru o varietate de animații. În scopurile noastre, dreptunghiurile vor merge bine atât pentru platforme, cât și pentru jucător.
Clasa personajului
Clasa Character extinde clasa mea Box, așa că avem anumite fizici în afara cutiei. Am creat metoda „CheckForCollisions” pentru a verifica rapid toate platformele pe care le-am creat pentru o coliziune. Metoda „Salt” setează viteza ascendentă a jucătorului la variabila JumpSpeed, care este apoi modificată cadru cu cadru în clasa MainWindow.
Coliziunile sunt tratate ușor diferit aici decât în clasa Box. Am decis în acest joc că, dacă sărim în sus, putem sări printr-o platformă, dar acesta ne va prinde jucătorul la coborâre dacă se ciocnește cu ea.
Clasa platformei
În acest joc, folosesc doar constructorul acestei clase care ia o coordonată X ca intrare, calculând toate locațiile X ale platformelor din clasa MainWindow. Fiecare platformă este configurată la o coordonată Y aleatorie de la 1/2 ecran la 3/4 din înălțimea ecranului. Înălțimea, lățimea și culoarea sunt, de asemenea, generate aleatoriu.
Clasa MainWindow
Aici punem toată logica pe care trebuie să o folosim în timp ce jocul rulează. În primul rând, în constructor, imprimăm toate porturile COM disponibile pentru program.
foreach (port șir în SerialPort. GetPortNames ())
Console. WriteLine ("PORTURI DISPONIBILE:" + port);
Alegem pe care vom accepta comunicările, în funcție de portul pe care îl folosește deja Arduino:
SerialPort = SerialPort nou (SerialPort. GetPortNames () [2], 9600, Parity. None, 8, StopBits. One);
Acordați o atenție deosebită comenzii: SerialPort. GetPortNames () [2]. [2] semnifică portul serial de utilizat. De exemplu, dacă programul ar fi tipărit „COM1, COM2, COM3”, am asculta pe COM3, deoarece numerotarea începe de la 0 în matrice.
De asemenea, în constructor, creăm toate platformele cu spațierea semi-aleatorie și plasarea în direcția Y pe ecran. Toate platformele sunt adăugate unui obiect List, care în C # este pur și simplu un mod foarte ușor de utilizat și eficient de a gestiona o structură de date de tip matrice. Apoi creăm Playerul, care este obiectul nostru Personaj, setăm scorul la 0 și setăm GameOver la fals.
private static nul DataReceived (expeditor obiect, SerialDataReceivedEventArgs e)
Aceasta este metoda care este apelată atunci când datele sunt primite pe portul serial. Aici aplicăm toată fizica noastră, decidem dacă afișăm jocul, mutăm platformele etc. Dacă ați construit vreodată un joc, în general aveți ceea ce se numește „buclă de joc”, care se numește de fiecare dată cadru reîmprospătează. În acest joc, metoda DataReceived acționează ca buclă de joc, manipulând fizica doar pe măsură ce datele sunt primite de la controler. S-ar putea să fi funcționat mai bine să configurați un cronometru în fereastra principală și să reîmprospătați obiectele pe baza datelor primite, dar, deoarece acesta este un proiect Arduino, am vrut să fac un joc care să ruleze de fapt pe baza datelor care vin din acesta.
În concluzie, această configurație oferă o bază bună pentru extinderea jocului în ceva utilizabil. Deși fizica nu este destul de perfectă, funcționează suficient de bine pentru scopurile noastre, adică să folosim Arduino pentru ceva ce îi place tuturor: jocuri!
Recomandat:
Platforma de bază IoT cu RaspberryPi, WIZ850io: Driver de dispozitiv platformă: 5 pași (cu imagini)
Platforma de bază IoT cu RaspberryPi, WIZ850io: Platform Device Driver: Cunosc platforma RaspberryPi pentru IoT. Recent WIZ850io este anunțat de WIZnet. Așa că am implementat o aplicație RaspberryPi prin modificarea Ethernet SW, deoarece pot gestiona cu ușurință un cod sursă. Puteți testa Driverul dispozitivului platformei prin RaspberryPi
Joc inteligent de baschet arcade cu cercuri de numărare a scorurilor folosind platforma încorporată Evive- Arduino: 13 pași
Joc inteligent de baschet arcade cu cercuri de numărare a scorurilor folosind platforma încorporată Evive- Arduino: Dintre toate jocurile de acolo, cele mai distractive sunt jocurile arcade. Deci, ne-am gândit de ce să nu facem unul singur acasă! Și iată-ne, cel mai distractiv joc DIY pe care l-ai fi jucat până acum - DIY Arcade Basketball Game! Nu numai că este
Consola de joc Arduino Pocket + A-Maze - Joc Maze: 6 pași (cu imagini)
Arduino Pocket Game Console + A-Maze - Maze Game: Bine ați venit la primul meu instructable! Proiectul pe care vreau să îl împărtășesc astăzi este jocul de labirint Arduino, care a devenit o consolă de buzunar la fel de capabilă ca Arduboy și consolele similare bazate pe Arduino. Poate fi intermitent cu jocurile mele (sau ale dvs.) viitoare datorită expo
Receptor infraroșu și receptor IR (TSOP1738) cu Arduino: 10 pași
Telecomandă cu infraroșu și receptor IR (TSOP1738) cu Arduino: Acest instructiv este destinat începătorilor Arduino. Acesta este unul dintre proiectele mele anterioare cu Arduino. M-am bucurat foarte mult când l-am realizat și sper să vă placă și vouă. Cea mai atractivă caracteristică a acestui proiect este „ldquo; Control wireless”. Si asta e
Joc labirint de controlat cu smartphone: 5 pași (cu imagini)
Joc labirint pentru a controla cu smartphone: Joc labirint pentru a controla cu telefonul inteligent. Labirintul se mișcă în funcție de panta smartphone-ului. În primul rând, vă rugăm să consultați videoclipul. Imaginea mișcării1. Raspberry Pi este un server Websocket. Smartphone-ul este un client Websocket. Smartphone-ul trimite ti