Turinys:

„Arduino“valdomas platformingo žaidimas su vairasvirte ir IR imtuvu: 3 žingsniai (su nuotraukomis)
„Arduino“valdomas platformingo žaidimas su vairasvirte ir IR imtuvu: 3 žingsniai (su nuotraukomis)

Video: „Arduino“valdomas platformingo žaidimas su vairasvirte ir IR imtuvu: 3 žingsniai (su nuotraukomis)

Video: „Arduino“valdomas platformingo žaidimas su vairasvirte ir IR imtuvu: 3 žingsniai (su nuotraukomis)
Video: Переработка энкодера колеса прокрутки мыши и его тестирование с помощью Arduino Nano 2024, Liepa
Anonim
„Arduino“valdomas platformingo žaidimas su vairasvirte ir IR imtuvu
„Arduino“valdomas platformingo žaidimas su vairasvirte ir IR imtuvu

Šiandien mes naudosime „Arduino“mikrovaldiklį, kad valdytume paprastą C#pagrindu sukurtą platformingo žaidimą. Aš naudoju „Arduino“norėdamas įvesti įvestį iš kreiptuko modulio ir nusiųsti tą įvestį į „C#“programą, kuri klausosi ir dekoduoja įvestį per nuoseklųjį ryšį. Nors jums nereikia jokios ankstesnės patirties kuriant vaizdo žaidimus, kad užbaigtumėte projektą, gali prireikti šiek tiek laiko įsisavinti kai kuriuos dalykus, vykstančius „žaidimų cikle“, kurį aptarsime vėliau.

Norėdami užbaigti šį projektą, jums reikės:

  • „Visual Studio“bendruomenė
  • „Arduino Uno“(ar panašus)
  • Joystick valdiklio modulis
  • Kantrybės

Jei esate pasirengęs pradėti, tęskite!

1 veiksmas: prijunkite vairasvirtę ir IR šviesos diodą

Prijunkite vairasvirtę ir IR šviesos diodą
Prijunkite vairasvirtę ir IR šviesos diodą
Prijunkite vairasvirtę ir IR šviesos diodą
Prijunkite vairasvirtę ir IR šviesos diodą

Čia prijungimas yra gana paprastas. Aš įtraukiau diagramas, kuriose parodyta tik prijungta vairasvirtė, taip pat mano naudojama sąranka, apimanti vairasvirtę ir infraraudonųjų spindulių šviesos diodą, skirtą žaidimui valdyti nuotolinio valdymo pultu, kuris pateikiamas kartu su daugeliu „Arduino“rinkinių. Tai neprivaloma, tačiau atrodė šauni idėja žaisti belaidžius žaidimus.

Sąrankoje naudojami kaiščiai:

  • A0 (analoginis) <- horizontali arba X ašis
  • A1 (analoginis) <- vertikali arba Y ašis
  • 2 kaištis <- vairasvirtės jungiklio įvestis
  • 2 kaištis <- infraraudonųjų spindulių LED įėjimas
  • VCC <- 5V
  • Gruntas
  • Žemė #2

2 žingsnis: sukurkite naują eskizą

Sukurkite naują eskizą
Sukurkite naują eskizą

Pradėsime nuo „Arduino“eskizo failo kūrimo. Tai apklausia kreiptuką dėl pakeitimų ir siunčia tuos pakeitimus į C# programą kas kelias milisekundes. Tikrame vaizdo žaidime mes patikrintume serijos prievadą žaidimo kilpoje, ar nėra įvesties, bet aš pradėjau žaidimą kaip eksperimentą, todėl kadrų dažnis iš tikrųjų pagrįstas įvykių skaičiumi nuosekliajame prievade. Aš iš tikrųjų pradėjau projektą „Arduino“sesers projekte „Processing“, tačiau paaiškėjo, kad jis buvo daug, daug lėtesnis ir negalėjau susidoroti su langelių skaičiumi ekrane.

Taigi, pirmiausia sukurkite naują eskizą „Arduino“kodų rengyklės programoje. Aš parodysiu savo kodą ir tada paaiškinsiu, ką jis daro:

#įtraukti „IRremote.h“

// IR kintamieji int imtuvas = 3; // IR imtuvo signalinis kaištis IRrecv irrecv (imtuvas); // sukurti „irrecv“dekodavimo_rezultatų rezultatų egzempliorių; // sukurti egzempliorių 'decode_results' // Joystick/game kintamieji int xPos = 507; int yPos = 507; baitas džiaugsmasXPin = A0; baitas joyYPin = A1; baitų džiaugsmasSijungimas = 2; nepastovus baitas clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // Numatytasis = vidutinis greitis int speedIncrement = 25; // Suma greičiui padidinti/sumažinti su Y įvesties nepasirašyta ilga srove = 0; // Laikoma dabartinė laiko žyma int wait = 40; // ms laukti tarp pranešimų [Pastaba: mažesnis laukimas = greitesnis kadrų dažnis] nepastovus bool mygtukasPaspaustas = false; // Matuoklis, jei paspaudžiamas mygtukas void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, šuolis, kritimas); srovė = milis (); // Nustatyti esamą laiką // Nustatyti infraraudonųjų spindulių imtuvą: irrecv.enableIRIn (); // Paleisti imtuvą} // setup void loop () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Valdykite vairasvirtės X judesį nepriklausomai nuo laiko: if (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Jei tik šiek tiek pajudėtų…? currentSpeed // … tiesiog grąžinkite dabartinį greitį: getSpeed (yPos); // „YPos“keiskite tik tuo atveju, jei vairasvirtė gerokai pasislinko // int distance =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); srovė = milis (); }} // kilpa int getSpeed (int yPos) {// Neigiamos vertės rodo, kad vairasvirtė perkelta aukštyn, jei (yPos 1023? 1023: currentSpeed + speedIncrement;} else if (yPos> minMoveHigh) // aiškinama „žemyn“{// Apsaugoti nuo eina po 0 grąžinti srovęSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Nurodyti mygtuką.} // šokti // Kai paspaudžiamas mygtukas nuotolinio valdymo pultas, tvarkykite tinkamą atsakymą void translateIR (decode_results results) // imasi veiksmų pagal gautą IR kodą {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; numatytasis: //Serial.println (" kitas mygtukas "); break;} // Pabaigos jungiklis} // END translateIR

Bandžiau sukurti kodą, kuris dažniausiai būtų savaime suprantamas, tačiau verta paminėti keletą dalykų. Vienas dalykas, kurį bandžiau apskaityti, buvo šiose eilutėse:

int minYMoveUp = 520;

int minYMoveDown = 500;

Kai programa veikia, analoginė įvestis iš vairasvirtės linkusi šokinėti, paprastai lieka apie 507. Norėdami tai ištaisyti, įvestis nesikeičia, nebent ji yra didesnė nei minYMoveUp arba mažesnė nei minYMoveDown.

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, šuolis, kritimas);

Metodas attachInterrupt () leidžia bet kuriuo metu nutraukti įprastą ciklą, kad galėtume įvesti informaciją, pvz., Mygtuko paspaudimą, kai paspaudžiamas vairasvirtės mygtukas. Čia mes pridėjome pertrauką eilutėje prieš ją, naudodamiesi „pinMode ()“metodu. Svarbi pastaba yra tai, kad norėdami prijungti pertrauką prie „Arduino Uno“, turite naudoti 2 arba 3 kaištį. Kituose modeliuose naudojami skirtingi pertraukimo kaiščiai, todėl gali tekti patikrinti, kuriuos smeigtukus naudoja jūsų modelis „Arduino“svetainėje. Antrasis parametras skirtas atšaukimo metodui, čia vadinamas ISR arba „Nutraukti paslaugų teikimo tvarką“. Ji neturėtų imti jokių parametrų ar nieko grąžinti.

Serial.print (…)

Tai eilutė, kuri nusiųs mūsų duomenis į „C#“žaidimą. Čia žaidimui siunčiame X ašies, Y ašies rodmenis ir greičio kintamąjį. Šiuos rodmenis galima išplėsti, įtraukiant kitus įvestis ir rodmenis, kad žaidimas būtų įdomesnis, tačiau čia naudosime tik porą.

Jei esate pasirengęs išbandyti savo kodą, įkelkite jį į „Arduino“ir paspauskite [Shift] + [Ctrl] + [M], kad atidarytumėte nuoseklųjį monitorių ir pamatytumėte, ar gaunate išvestį. Jei gaunate duomenis iš „Arduino“, esame pasirengę pereiti prie kodo C# dalies …

3 žingsnis: sukurkite C# projektą

Norėdami parodyti mūsų grafiką, iš pradžių pradėjau apdorojimo projektą, bet vėliau nusprendžiau, kad bus per lėta rodyti visus objektus, kuriuos turime parodyti. Taigi, aš nusprendžiau naudoti C#, kuris pasirodė esąs daug sklandesnis ir jautresnis tvarkant mūsų įvestį.

Projekto C# daliai geriausia tiesiog atsisiųsti.zip failą ir išskleisti jį į savo aplanką, tada jį modifikuoti. ZIP faile yra du aplankai. Norėdami atidaryti projektą „Visual Studio“, „Windows Explorer“įveskite aplanką „RunnerGame_CSharp“. Čia dukart spustelėkite failą.sln (sprendimas) ir VS įkelia projektą.

Žaidimui sukūriau keletą skirtingų klasių. Nesileisiu į visas detales apie kiekvieną klasę, bet apžvelgsiu, kam skirtos pagrindinės klasės.

Dėžutės klasė

Aš sukūriau langelių klasę, kad galėčiau sukurti paprastus stačiakampius objektus, kuriuos galima piešti ekrane naudojant „Windows“formą. Idėja yra sukurti klasę, kurią būtų galima išplėsti naudojant kitas klases, kurios galbūt norėtų piešti tam tikrą grafiką. „Virtualus“raktinis žodis naudojamas tam, kad kitos klasės galėtų jas nepaisyti (naudojant raktinį žodį „nepaisyti“). Tokiu būdu mes galime pasiekti tą patį elgesį „Player“ir „Platform“klasėms, kai mums to reikia, ir taip pat keisti objektus, kaip mums reikia.

Per daug nesirūpinkite visomis savybėmis ir skambinkite. Aš parašiau šią klasę, kad galėčiau ją pratęsti bet kokiam žaidimui ar grafikos programai, kurią galbūt norėčiau sukurti ateityje. Jei jums reikia tiesiog nubrėžti stačiakampį, jums nereikia išrašyti tokios didelės klasės. C# dokumentacijoje yra gerų pavyzdžių, kaip tai padaryti.

Tačiau išdėstysiu dalį savo „Box“klasės logikos:

viešas virtualus bool IsCollidedX (Box otherObject) {…}

Čia mes patikriname, ar nėra susidūrimų su X krypties objektais, nes žaidėjui tereikia patikrinti, ar nėra susidūrimų Y kryptimi (aukštyn ir žemyn), jei jis yra su juo eilėje.

viešas virtualus bool IsCollidedY (Box otherObject) {…}

Kai esame virš kito žaidimo objekto ar po juo, patikriname, ar nėra Y susidūrimų.

viešas virtualus bool IsCollided (Box otherObject) {…}

Tai sujungia X ir Y susidūrimus ir grąžina, ar su šiuo objektu nesusidūrė koks nors objektas.

viešas virtualus void OnPaint (grafinė grafika) {…}

Naudodami aukščiau pateiktą metodą, mes perduodame bet kurį grafikos objektą ir naudojame jį, kai programa veikia. Mes kuriame bet kokius stačiakampius, kuriuos gali tekti piešti. Tačiau tai gali būti naudojama įvairioms animacijoms. Mūsų tikslais stačiakampiai puikiai tiks tiek platformoms, tiek grotuvui.

Simbolių klasė

Simbolių klasė pratęsia mano „Box“klasę, todėl turime tam tikrą fiziką. Sukūriau „CheckForCollisions“metodą, kad galėčiau greitai patikrinti visas mūsų sukurtas platformas, ar nėra susidūrimo. „Šuolio“metodas nustato žaidėjo greitį aukštyn iki kintamojo „JumpSpeed“, kuris vėliau keičiamas „MainWindow“klasėje.

Susidūrimai čia tvarkomi šiek tiek kitaip nei „Box“klasėje. Šiame žaidime nusprendžiau, kad šokinėdami aukštyn galime peršokti per platformą, tačiau ji sugriebs mūsų žaidėją pakeliui, jei susidurs su ja.

Platformų klasė

Šiame žaidime aš naudoju tik šios klasės konstruktorių, kuris kaip įvestį naudoja X koordinatę, apskaičiuodamas visas platformų X vietas MainWindow klasėje. Kiekviena platforma nustatyta atsitiktine Y koordinate nuo 1/2 ekrano iki 3/4 ekrano aukščio. Aukštis, plotis ir spalva taip pat sugeneruojami atsitiktinai.

„MainWindow“klasė

Čia mes įdedame visą logiką, kurią reikia naudoti žaidimo metu. Pirma, konstruktoriuje išspausdiname visus programai prieinamus COM prievadus.

foreach (eilutės prievadas SerialPort. GetPortNames ())

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

Mes pasirenkame, kuriame iš jų priimsime ryšius, atsižvelgiant į tai, kurį prievadą jūsų „Arduino“jau naudoja:

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

Atidžiai stebėkite komandą: SerialPort. GetPortNames () [2]. [2] nurodo, kurį nuoseklųjį prievadą naudoti. Pavyzdžiui, jei programa išspausdintų „COM1, COM2, COM3“, mes klausytumės COM3, nes masyvo numeracija prasideda nuo 0.

Taip pat konstruktoriuje mes sukuriame visas platformas su pusiau atsitiktiniais atstumais ir išdėstymu ekrane Y kryptimi. Visos platformos pridedamos prie sąrašo objekto, kuris C# yra tiesiog labai patogus ir efektyvus būdas valdyti į masyvą panašią duomenų struktūrą. Tada sukuriame grotuvą, kuris yra mūsų simbolių objektas, nustatome balą į 0 ir nustatome „GameOver“į klaidingą.

privati statinė negaliojanti „DataReceived“(objekto siuntėjas, „SerialDataReceivedEventArgs e“)

Šis metodas vadinamas, kai duomenys gaunami nuosekliajame prievade. Čia mes pritaikome visą savo fiziką, nusprendžiame, ar rodyti žaidimą, perkelti platformas ir pan. Jei kada nors sukūrėte žaidimą, paprastai turite tai, kas vadinama „žaidimo kilpa“, kuri vadinama kiekvieną kartą gaivina. Šiame žaidime „DataReceived“metodas veikia kaip žaidimo kilpa, tik manipuliuoja fizika, nes duomenys gaunami iš valdiklio. Galbūt būtų buvę geriau nustatyti laikmatį pagrindiniame lange ir atnaujinti objektus pagal gautus duomenis, tačiau kadangi tai yra „Arduino“projektas, norėjau sukurti žaidimą, kuris iš tikrųjų veikė pagal iš jo gaunamus duomenis..

Apibendrinant, ši sąranka suteikia gerą pagrindą išplėsti žaidimą į kažką naudingo. Nors fizika nėra visiškai tobula, ji pakankamai gerai veikia mūsų tikslams, tai yra naudoti „Arduino“tam, kas patinka visiems: žaisti žaidimus!

Rekomenduojamas: