Sisukord:

Arduino juhitav platvormimäng juhtkangi ja IR-vastuvõtjaga: 3 sammu (piltidega)
Arduino juhitav platvormimäng juhtkangi ja IR-vastuvõtjaga: 3 sammu (piltidega)

Video: Arduino juhitav platvormimäng juhtkangi ja IR-vastuvõtjaga: 3 sammu (piltidega)

Video: Arduino juhitav platvormimäng juhtkangi ja IR-vastuvõtjaga: 3 sammu (piltidega)
Video: Nutitelefoni teel juhitav auto 2024, Juuli
Anonim
Arduino juhitav platvormimäng juhtkangi ja IR-vastuvõtjaga
Arduino juhitav platvormimäng juhtkangi ja IR-vastuvõtjaga

Täna kasutame lihtsa C#-põhise platvormmängu juhtimiseks Arduino mikrokontrollerit. Kasutan Arduinot juhtkangi moodulist sisendi saamiseks ja selle sisendi saatmiseks rakendusele C#, mis kuulab ja dekodeerib sisendit jadaühenduse kaudu. Kuigi te ei vaja projekti lõpuleviimiseks eelnevat kogemust videomängude ehitamisel, võib mõne „mänguahelas” toimuva imendumiseks kuluda veidi aega, millest me hiljem räägime.

Selle projekti lõpuleviimiseks vajate:

  • Visual Studio kogukond
  • Arduino Uno (või sarnane)
  • Juhtkangi juhtimismoodul
  • Kannatlikkus

Kui olete alustamiseks valmis, jätkake!

Samm: ühendage juhtkangi ja IR -LED

Ühendage juhtkangi ja IR -LED
Ühendage juhtkangi ja IR -LED
Ühendage juhtkangi ja IR -LED
Ühendage juhtkangi ja IR -LED

Siin on ühendamine üsna lihtne. Olen lisanud skeemid, mis näitavad ainult ühendatud juhtkangi, samuti minu kasutatavat seadistust, mis sisaldab juhtkangi ja infrapuna LED -i mängu juhtimiseks kaugjuhtimispuldiga, mis on kaasas paljude Arduino komplektidega. See on vabatahtlik, kuid tundus lahe mõte, et saaks juhtmevabalt mängida.

Seadistuses kasutatavad tihvtid on järgmised:

  • A0 (analoog) <- horisontaalne või X-telg
  • A1 (analoog) <- vertikaalne või Y-telg
  • Pin 2 <- juhtkangi lüliti sisend
  • Pin 2 <- infrapuna LED sisend
  • VCC <- 5V
  • Maa
  • Maa #2

Samm: looge uus visand

Loo uus visand
Loo uus visand

Alustame oma Arduino visandifaili loomisega. See küsitleb muudatuste tegemiseks juhtkangi ja saadab need muudatused programmi C# iga mitme millisekundi järel. Tegelikus videomängus kontrolliksime sisendiks mängusahela jadapordi, kuid alustasin mängu eksperimendina, nii et kaadrisagedus põhineb tegelikult jadaportis toimuvate sündmuste arvul. Olin projektiga tegelikult alustanud Arduino sõsarprojektis Processing, kuid selgub, et see oli palju -palju aeglasem ega suutnud ekraanil olevate kastide arvuga hakkama saada.

Niisiis, looge kõigepealt Arduino koodiredaktori programmis uus visand. Näitan oma koodi ja seejärel selgitan, mida see teeb:

#include "IRremote.h"

// IR muutujad int vastuvõtja = 3; // IR vastuvõtja signaalipulk IRrecv irrecv (vastuvõtja); // luua eksemplar 'irrecv' decode_results tulemused; // luua eksemplar 'decode_results' // Juhtkang/mängu muutujad int xPos = 507; int yPos = 507; bait joyXPin = A0; bait joyYPin = A1; bait joySwitch = 2; lenduv bait clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int praegune kiirus = 550; // Vaikimisi = keskmine kiirus int speedIncrement = 25; // Summa kiiruse suurendamiseks/vähendamiseks Y sisendiga allkirjastamata pika voolu korral = 0; // Hoiab praegust ajatemplit int wait = 40; // ms ootama sõnumite vahel [Märkus: madalam ootamine = kiirem kaadrisagedus] lenduv bool -nuppPressitud = vale; // Mõõtur nupule vajutamisel void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, hüppama, kukkuma); vool = millis (); // Praeguse aja seadistamine // Infrapuna vastuvõtja seadistamine: irrecv.enableIRIn (); // Käivitage vastuvõtja} // setup void loop () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Juhtige juhtkangi X liikumist olenemata ajastusest: if (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Kui ainult natuke liigutada…? currentSpeed //… lihtsalt tagasta praegune kiirus: getSpeed (yPos); // Muutke yPosid ainult siis, kui juhtnupp on oluliselt liikunud // int distance =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); vool = millis (); }} // loop int getSpeed (int yPos) {// Negatiivsed väärtused näitavad, et juhtkang liigub üles, kui (yPos 1023? 1023: currentSpeed + speedIncrement;} else if (yPos> minMoveHigh) // tõlgendatakse "alla" {// Kaitsta läheb alla 0 return currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Näita, et nuppu on vajutatud.} // hüpata // Kui nupule vajutatakse kaugjuhtimispult, käsitse õiget vastust void translateIR (decode_results results) // võtab meetmeid saadud IR -koodi alusel {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; vaikimisi: //Serial.println (" muu nupp "); break;} // Lõpplüliti} // LÕPP translateIR

Proovisin luua koodi, mis oleks enamasti iseenesestmõistetav, kuid mainimist väärivad mõned asjad. Üks asi, mida ma üritasin arvestada, oli järgmistes ridades:

int minYMoveUp = 520;

int minYMoveDown = 500;

Programmi töötamise ajal kipub juhtkangi analoogsisend ümber hüppama, jäädes tavaliselt 507 ümber. Selle parandamiseks ei muutu sisend, kui see ei ole suurem kui minYMoveUp või väiksem kui minYMoveDown.

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, hüppama, kukkuma);

Meetod attachInterrupt () võimaldab meil igal ajal tavalise tsükli katkestada, et saaksime sisestada teavet, näiteks nupuvajutust juhtkangi nupu klõpsamisel. Siin oleme katkestuse kinnitanud sellele eelnevale reale, kasutades meetodit pinMode (). Siinkohal on oluline märkus, et katkestuse lisamiseks Arduino Unole peate kasutama kas tihvti 2 või 3. Teised mudelid kasutavad erinevaid katkestusnõelu, seega peate võib -olla kontrollima, milliseid tihvte teie mudel Arduino veebisaidil kasutab. Teine parameeter on tagasihelistamismeetodi jaoks, mida siin nimetatakse ISR -iks või "Katkestusteenuseks". See ei tohiks võtta mingeid parameetreid ega tagasta midagi.

Serial.print (…)

See on rida, mis saadab meie andmed mängule C#. Siin saadame mängu X-telje näidu, Y-telje näidu ja kiiruse muutuja. Neid näiteid saab mängu huvitavamaks muutmiseks laiendada ka teistele sisenditele ja näitudele, kuid siin kasutame ainult paari.

Kui olete valmis oma koodi testima, laadige see Arduinosse üles ja vajutage seeriamonitori avamiseks [Shift] + [Ctrl] + [M], et näha, kas saate väljundit. Kui saate andmeid Arduino'st, oleme valmis liikuma koodi C# osasse …

Samm: looge C# projekt

Meie graafika kuvamiseks alustasin esialgu projektiga Processing, kuid hiljem otsustasin, et kõigi kuvatavate objektide kuvamine oleks liiga aeglane. Niisiis, valisin C#kasutamise, mis osutus meie sisendi käsitlemisel palju sujuvamaks ja tundlikumaks.

Projekti C# osa jaoks on kõige parem lihtsalt alla laadida.zip -fail ja ekstraktida see oma kausta ning seejärel seda muuta. Zip -failis on kaks kausta. Projekti avamiseks Visual Studio'is sisestage Windows Exploreris kaust RunnerGame_CSharp. Siin topeltklõpsake faili.sln (lahendus) ja VS laadib projekti.

Mängu jaoks olen loonud mõned erinevad klassid. Ma ei süvene iga klassi üksikasjadesse, kuid annan ülevaate põhitundidest.

Kastide klass

Lõin kastiklassi, et saaksite luua lihtsaid ristkülikukujulisi objekte, mida saab akna kujul ekraanile joonistada. Idee on luua klass, mida saab laiendada, kasutades teisi klasse, mis võivad soovida mingisugust graafikat joonistada. Märksõna "virtuaalne" kasutatakse selleks, et teised klassid saaksid need alistada (kasutades märksõna "alistamine"). Nii saame vajadusel sama klassi käitumise nii mängijaklassi kui ka platvormiklassi osas ning samuti muuta objekte vastavalt vajadusele.

Ärge muretsege kõigi kinnisvarade pärast liiga palju ja helistage. Kirjutasin selle klassi, et saaksin seda laiendada mis tahes mängu või graafikaprogrammi jaoks, mida võiksin tulevikus teha. Kui teil on vaja lihtsalt lennata ristkülik joonistada, ei pea te sellist suurt klassi välja kirjutama. C# dokumentatsioonis on häid näiteid selle kohta, kuidas seda teha.

Siiski toon välja mõned oma "Box" klassi loogikast:

avalik virtuaalne bool IsCollidedX (Box otherObject) {…}

Siin kontrollime kokkupõrkeid X-suuna objektidega, sest mängijal on vaja Y-suunas (üles ja alla) kokkupõrkeid kontrollida ainult siis, kui ta on sellega ekraanil rivis.

avalik virtuaalne bool IsCollidedY (Box otherObject) {…}

Kui oleme teise mänguobjekti kohal või all, kontrollime Y kokkupõrkeid.

avalik virtuaalne bool IsCollided (Box otherObject) {…}

See ühendab X ja Y kokkupõrke, andes teada, kas mõni objekt on sellega kokku põrganud.

avalik virtuaalne tühjus OnPaint (graafiline graafika) {…}

Ülaltoodud meetodit kasutades edastame mis tahes graafikaobjekti ja kasutame seda programmi töötamise ajal. Loome ristkülikud, mis võivad vajada joonistamist. Seda saab aga kasutada mitmesuguste animatsioonide jaoks. Meie jaoks sobivad ristkülikud hästi nii platvormide kui ka mängija jaoks.

Märkide klass

Märkide klass laiendab minu Boxi klassi, nii et meil on teatud füüsika kastist väljas. Lõin meetodi "CheckForCollisions", et kiiresti kontrollida kõiki meie loodud platvorme kokkupõrke suhtes. "Jump" meetod seab mängija ülespoole liikumise kiiruseks muutuja JumpSpeed, mida seejärel MainWindow klassis kaaderhaaval muudetakse.

Kokkupõrkeid käsitletakse siin pisut teisiti kui Box -klassis. Otsustasin selles mängus, et ülespoole hüpates võime hüpata läbi platvormi, kuid see tabab meie mängija allapoole sõites, kui sellega kokku põrkub.

Platvormiklass

Selles mängus kasutan ainult selle klassi konstruktorit, mis võtab sisendiks X-koordinaadi, arvutades kõik platvormide X asukohad MainWindow klassis. Iga platvorm on seadistatud juhusliku Y-koordinaadi järgi 1/2 ekraanist kuni 3/4 ekraani kõrgusest. Kõrgus, laius ja värv genereeritakse ka juhuslikult.

Põhiakna klass

See on koht, kus mängu loomisel kasutame kogu loogikat. Esiteks prindime konstruktoris kõik programmi jaoks saadaolevad COM -pordid.

foreach (stringiport SerialPort. GetPortNames ())

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

Me valime, millises neist suhtlust aktsepteerime, vastavalt sellele, millist porti teie Arduino juba kasutab:

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

Pöörake suurt tähelepanu käsule: SerialPort. GetPortNames () [2]. [2] tähistab, millist jadaporti kasutada. Näiteks kui programm trükiks välja "COM1, COM2, COM3", siis me kuulaksime COM3 -d, sest numeratsioon algab massiivist nulliga.

Ka konstruktoris loome kõik platvormid, millel on pooljuhuslikud vahekaugused ja paigutus ekraanil Y-suunas. Kõik platvormid lisatakse loendi objektile, mis C# -is on lihtsalt väga kasutajasõbralik ja tõhus viis massiivitaolise andmestruktuuri haldamiseks. Seejärel loome mängija, mis on meie tegelaskuju objekt, seame tulemuseks 0 ja seame GameOver väärtuseks Väär.

privaatne staatiline tühine DataReceived (objekti saatja, SerialDataReceivedEventArgs e)

Seda meetodit kutsutakse välja, kui jadaporti andmed vastu võetakse. Siin rakendame kogu oma füüsikat, otsustame, kas kuvada mäng üle, teisaldada platvorme jne. Kui olete kunagi mängu loonud, on teil tavaliselt nn mänguahel, mida nimetatakse iga kord kaadri jaoks värskendab. Selles mängus toimib DataReceived meetod mänguahelana, manipuleerides füüsikaga ainult siis, kui andmed saadakse kontrollerilt. Oleks võinud paremini toimida, kui seadistada peaaknasse taimer ja värskendada objekte saadud andmete põhjal, kuid kuna tegemist on Arduino projektiga, tahtsin teha mängu, mis tegelikult jooksis selle andmete põhjal.

Kokkuvõtteks võib öelda, et see seadistus annab hea aluse mängu laiendamiseks millekski kasutatavaks. Kuigi füüsika pole päris täiuslik, töötab see meie eesmärkide jaoks piisavalt hästi, st kasutada Arduinot millekski, mis kõigile meeldib: mängude mängimiseks!

Soovitan: