Sadržaj:

Platformerska igra s Arduino kontrolom s joystickom i IC prijemnikom: 3 koraka (sa slikama)
Platformerska igra s Arduino kontrolom s joystickom i IC prijemnikom: 3 koraka (sa slikama)

Video: Platformerska igra s Arduino kontrolom s joystickom i IC prijemnikom: 3 koraka (sa slikama)

Video: Platformerska igra s Arduino kontrolom s joystickom i IC prijemnikom: 3 koraka (sa slikama)
Video: Закодил Google Dino на Arduino! [Arduino GameDev] 2024, Juli
Anonim
Platformerska igra s Arduino kontrolom s joystickom i IC prijemnikom
Platformerska igra s Arduino kontrolom s joystickom i IC prijemnikom

Danas ćemo koristiti Arduino mikrokontroler za kontrolu jednostavne platformerske igre zasnovane na C#. Koristim Arduino za preuzimanje unosa iz modula joystick -a i slanje tog unosa u aplikaciju C# koja sluša i dekodira ulaz preko serijske veze. Iako vam ne treba nikakvo prethodno iskustvo u izgradnji video igara da biste dovršili projekt, možda će vam trebati neko vrijeme da upijete neke stvari koje se događaju u "petlji igre", o čemu ćemo kasnije govoriti.

Da biste dovršili ovaj projekat, trebat će vam:

  • Zajednica Visual Studio
  • Arduino Uno (ili slično)
  • Modul kontrolera džojstika
  • Strpljenje

Ako ste spremni za početak, nastavite!

Korak 1: Priključite joystick i IC LED diodu

Priključite joystick i IC LED
Priključite joystick i IC LED
Priključite joystick i IC LED
Priključite joystick i IC LED

Ovdje je spajanje prilično jednostavno. Uključio sam dijagrame koji prikazuju samo priključeni džojstik, kao i postavke koje koristim, koje uključuju džojstik i infracrvenu LED diodu za kontrolu igre s daljinskim upravljačem, koji dolazi s mnogo Arduino kompleta. Ovo nije obavezno, ali činilo se kao super ideja biti u mogućnosti raditi bežične igre.

Igle koje se koriste u postavljanju su:

  • A0 (analogno) <- Horizontalna ili X os
  • A1 (analogno) <- Okomita ili Y-osa
  • Pin 2 <- Ulaz za prekidač džojstika
  • Pin 2 <- Infracrveni LED ulaz
  • VCC <- 5V
  • Ground
  • 2. osnova

Korak 2: Kreirajte novu skicu

Kreirajte novu skicu
Kreirajte novu skicu

Počet ćemo s stvaranjem naše Arduino datoteke skice. Ovo anketira joystick za promjene i šalje te promjene u C# program svakih nekoliko milisekundi. U stvarnoj video igri provjeravali bismo serijski port u petlji igre radi unosa, ali igru sam započeo kao eksperiment, pa se framerate zapravo temelji na broju događaja na serijskom portu. Zapravo sam započeo projekt u sestrinskom projektu Arduino, Processing, ali pokazalo se da je to bilo mnogo, puno sporije i nisam mogao podnijeti broj kutija na ekranu.

Dakle, prvo stvorite novu skicu u programu za uređivanje koda Arduino. Pokazat ću svoj kôd, a zatim objasniti šta radi:

#include "IRremote.h"

// IC varijable int prijemnik = 3; // Signalni pin IC prijemnika IRrecv unrecv (prijemnik); // kreirajte instancu 'unrecv' decode_results rezultata; // kreirajte instancu 'decode_results' // Joystick/varijable igre int xPos = 507; int yPos = 507; bajt joyXPin = A0; bajt joyYPin = A1; bajt joySwitch = 2; volatile byte clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // Zadano = prosječna brzina int speedIncrement = 25; // Iznos za povećanje/smanjenje brzine s Y ulazom bez znaka duga struja = 0; // Zadržava trenutnu vremensku oznaku int wait = 40; // ms za čekanje između poruka [Napomena: niže čekanje = brži frame rate] volatile bool buttonPressed = false; // Mjerenje ako je dugme pritisnuto void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, skok, PADANJE); struja = milis (); // Postavljanje trenutnog vremena // Postavljanje infracrvenog prijemnika: unrecv.enableIRIn (); // Pokretanje prijemnika} // postavljanje void loop () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Rukovanje Joystick X pokretom bez obzira na vrijeme: if (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Kad bi se samo malo pomaknuo …? currentSpeed //… samo vratiti trenutnu brzinu: getSpeed (yPos); // Promijenite yPos samo ako se džojstik značajno pomaknuo // int distance =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); struja = milis (); }} // petlja int getSpeed (int yPos) {// Negativne vrijednosti pokazuju da je joystick pomaknut prema gore ako (yPos 1023? 1023: currentSpeed + speedIncrement;} inače if (yPos> minMoveHigh) // Tumačeno "Dolje" {// Zaštitite od ide ispod 0 return currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Označeno dugme je pritisnuto.} // skok // Kada je dugme pritisnuto na daljinski, rukuje odgovarajućim odgovorom void translateIR (decode_results results) // poduzima radnje na osnovu primljenog IR koda {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: // Serijski. println ("6"); xPos = 900; break; case 0xFF4AB5: //Serial.println("8 "); currentSpeed -= speedIncrement * 2; break; default: //Serial.println (" drugo dugme "); break;} // Krajnji prekidač} // END translateIR

Pokušao sam stvoriti kôd koji će sam po sebi objašnjavati, ali postoji nekoliko stvari koje vrijedi spomenuti. Jedna stvar koju sam pokušao objasniti bila je u sljedećim redovima:

int minYMoveUp = 520;

int minYMoveDown = 500;

Dok je program pokrenut, analogni ulaz sa upravljačke palice ima tendenciju skakanja, obično se zadržavajući na 507. Da bi se to ispravilo, ulaz se ne mijenja osim ako je veći od minYMoveUp ili manji od minYMoveDown.

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, skok, PADANJE);

Metoda attachInterrupt () omogućava nam da prekinemo normalnu petlju u bilo koje vrijeme, tako da možemo unositi unos, poput pritiska na dugme kada se pritisne dugme na joystick -u. Ovdje smo priložili prekid u liniji prije njega, koristeći metodu pinMode (). Ovdje je važna napomena da za dodavanje prekida na Arduino Uno morate koristiti pin 2 ili 3. Drugi modeli koriste različite pinove prekida, pa ćete možda morati provjeriti koje pinove vaš model koristi na web stranici Arduino. Drugi parametar je za metodu povratnog poziva, koja se ovdje naziva ISR ili "Routine usluge prekida". Ne bi trebao uzimati nikakve parametre niti vraćati ništa.

Serial.print (…)

Ovo je linija koja će poslati naše podatke u igru C#. Ovdje u igru šaljemo očitanje osi X, očitanje osi Y i varijablu brzine. Ova se čitanja mogu proširiti uključivanjem drugih ulaza i čitanja kako bi igra postala zanimljivija, ali ovdje ćemo upotrijebiti samo nekoliko.

Ako ste spremni testirati svoj kôd, prenesite ga na Arduino i pritisnite [Shift] + [Ctrl] + [M] da biste otvorili serijski monitor i vidjeli imate li izlaz. Ako primate podatke iz Arduina, spremni smo za prijelaz na C# dio koda …

Korak 3: Kreirajte C# projekt

Da bih prikazao našu grafiku, u početku sam započeo projekt u procesu obrade, ali sam kasnije odlučio da bi bilo presporo prikazati sve objekte koje trebamo prikazati. Stoga sam odlučio koristiti C#, koji se pokazao mnogo glatkijim i osjetljivijim pri rukovanju našim unosom.

Za C# dio projekta, najbolje je jednostavno preuzeti.zip datoteku i izdvojiti je u vlastitu mapu, a zatim je izmijeniti. U zip datoteci postoje dvije mape. Da biste otvorili projekt u Visual Studiju, unesite mapu RunnerGame_CSharp u Windows Explorer. Ovdje dvaput kliknite na.sln (rješenje) datoteku i VS će učitati projekt.

Postoji nekoliko različitih klasa koje sam stvorio za igru. Neću ulaziti u sve detalje o svakom razredu, ali ću dati pregled čemu služe glavne klase.

Klasa kutije

Kreirao sam box box kako bih vam omogućio kreiranje jednostavnih pravokutnih objekata koji se mogu crtati na ekranu u Windows obliku. Ideja je stvoriti klasu koja se može proširiti pomoću drugih klasa koje možda žele nacrtati neku vrstu grafike. Ključna riječ "virtual" koristi se tako da ih druge klase mogu nadjačati (koristeći ključnu riječ "override"). Na taj način možemo dobiti isto ponašanje za klasu Player i klasu Platform kada je to potrebno, a također i izmijeniti objekte kako god je potrebno.

Ne brinite previše o svim nekretninama i upućujte pozive. Napisao sam ovu klasu kako bih je mogao proširiti za bilo koju igru ili grafički program koji bih možda želio napraviti u budućnosti. Ako trebate jednostavno nacrtati pravokutnik u hodu, ne morate napisati veliku klasu poput ove. C# dokumentacija ima dobre primjere kako to učiniti.

Međutim, iznijet ću neke logike moje klase "Box":

javni virtualni bool IsCollidedX (Box otherObject) {…}

Ovdje provjeravamo sudare s objektima u X-smjeru, jer igrač treba samo provjeriti sudare u Y smjeru (gore i dolje) ako je s njim poredan na ekranu.

javni virtualni bool IsCollidedY (Box otherObject) {…}

Kad smo iznad ili ispod drugog objekta igre, provjeravamo ima li Y sudara.

javni virtualni bool IsCollided (Box otherObject) {…}

Ovo kombinira X i Y sudare, vraćajući je li sudar bilo kojeg objekta s ovim.

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

Koristeći gornju metodu, prosljeđujemo bilo koji grafički objekt i koristimo ga dok je program pokrenut. Stvaramo sve pravokutnike koje je potrebno nacrtati. Ovo bi se ipak moglo koristiti za razne animacije. U naše svrhe, pravokutnici će dobro poslužiti i za platforme i za player.

Klasa karaktera

Klasa Character proširuje moju Box klasu, tako da imamo određenu fiziku van okvira. Kreirao sam metodu "CheckForCollisions" kako bih brzo provjerio sve platforme koje smo stvorili radi sudara. Metoda "Jump" postavlja brzinu igrača nagore na varijablu JumpSpeed, koja se zatim mijenja okvir po kadar u klasi MainWindow.

Ovdje se sudari rješavaju nešto drugačije nego u klasi Box. Odlučio sam u ovoj igri da, ako skočimo prema gore, možemo skočiti kroz platformu, ali ona će uhvatiti našeg igrača na putu prema dolje ako se sudari s njom.

Klasa platforme

U ovoj igri koristim samo konstruktor ove klase koji uzima X-koordinatu kao ulaz, računajući sve X lokacije platformi u klasi MainWindow. Svaka platforma je postavljena na nasumičnoj Y-koordinati od 1/2 ekrana do 3/4 visine ekrana. Visina, širina i boja također se nasumično generiraju.

Klasa MainWindow

Ovdje stavljamo svu logiku koja će se koristiti tokom igre. Prvo, u konstruktoru ispisujemo sve COM portove dostupne programu.

foreach (string port u SerialPort. GetPortNames ())

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

Biramo na kojem ćemo prihvatiti komunikaciju, prema tome koji port vaš Arduino već koristi:

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

Obratite posebnu pažnju na naredbu: SerialPort. GetPortNames () [2]. [2] označava koji serijski port treba koristiti. Na primjer, ako bi program ispisao "COM1, COM2, COM3", slušali bismo na COM3 jer numeriranje počinje s 0 u nizu.

Također u konstruktoru stvaramo sve platforme sa polu-slučajnim razmakom i postavljanjem u smjeru Y na ekranu. Sve platforme dodane su objektu List, što je u C# jednostavno vrlo jednostavan i efikasan način upravljanja strukturom podataka nalik nizu. Zatim kreiramo Player, koji je naš Character objekt, postavljamo rezultat na 0 i GameOver postavljamo na false.

privatna statička praznina DataReceived (pošiljatelj objekta, SerialDataReceivedEventArgs e)

Ovo je metoda koja se poziva pri prijemu podataka na serijski port. Ovdje primjenjujemo svu svoju fiziku, odlučujemo hoćemo li igru prikazati, premjestiti platforme itd. Ako ste ikada napravili igru, općenito imate ono što se naziva "petlja igre", koja se poziva svaki put kadrom osvežava. U ovoj igri DataReceived metoda djeluje kao petlja igre, samo manipulira fizikom dok se podaci primaju od kontrolera. Možda bi bolje funkcioniralo postavljanje mjerača vremena u glavnom prozoru i osvježavanje objekata na temelju primljenih podataka, ali kako se radi o Arduino projektu, želio sam napraviti igru koja se zapravo izvodi na osnovu podataka koji dolaze iz njega.

Zaključno, ova postavka daje dobru osnovu za proširenje igre u nešto upotrebljivo. Iako fizika nije sasvim savršena, radi dovoljno dobro za naše potrebe, a to je korištenje Arduina za nešto što se svima sviđa: igranje igara!

Preporučuje se: