Mundarija:

Joystik va IR qabul qilgichli Arduino boshqariladigan platforma o'yini: 3 qadam (rasmlar bilan)
Joystik va IR qabul qilgichli Arduino boshqariladigan platforma o'yini: 3 qadam (rasmlar bilan)

Video: Joystik va IR qabul qilgichli Arduino boshqariladigan platforma o'yini: 3 qadam (rasmlar bilan)

Video: Joystik va IR qabul qilgichli Arduino boshqariladigan platforma o'yini: 3 qadam (rasmlar bilan)
Video: КАК НАСТРОИТЬ L4D2 2024, Iyul
Anonim
Joystik va IR qabul qilgich bilan Arduino tomonidan boshqariladigan platforma o'yini
Joystik va IR qabul qilgich bilan Arduino tomonidan boshqariladigan platforma o'yini

Bugun biz C#asosidagi oddiy platformer o'yinini boshqarish uchun Arduino mikrokontrolleridan foydalanamiz. Men Arduino -dan joystik modulidan kirish uchun foydalanaman va kirishni ketma -ket ulanish orqali eshitadigan va dekodlaydigan C# ilovasiga yuboraman. Loyihani yakunlash uchun sizga video o'yinlar yaratish bo'yicha oldingi tajriba kerak bo'lmasa -da, "o'yin tsikli" da bo'layotgan ba'zi narsalarni o'zlashtirish uchun biroz vaqt kerak bo'lishi mumkin, biz bu haqda keyinroq gaplashamiz.

Ushbu loyihani bajarish uchun sizga kerak bo'ladi:

  • Visual Studio hamjamiyati
  • Arduino Uno (yoki shunga o'xshash)
  • Joystikni boshqarish moduli
  • Sabr

Agar siz boshlashga tayyor bo'lsangiz, davom eting!

1 -qadam: Datchik va IQ LEDni ulang

Joystik va IQ LEDni ulang
Joystik va IQ LEDni ulang
Joystik va IQ LEDni ulang
Joystik va IQ LEDni ulang

Bu erda ulanish juda oddiy. Men faqat ulangan joystikni ko'rsatadigan diagrammalarni, shuningdek men foydalanadigan sozlamalarni, shu jumladan joystikni va o'yinni masofadan boshqarish pulti bilan boshqariladigan infraqizil LEDni o'z ichiga olaman, u ko'plab Arduino to'plamlari bilan ta'minlangan. Bu ixtiyoriy, lekin simsiz o'yinlar bilan shug'ullanish ajoyib g'oya bo'lib tuyuldi.

Sozlamalarda quyidagilar ishlatiladi:

  • A0 (analog) <- Gorizontal yoki X o'qi
  • A1 (analog) <- Vertikal yoki Y o'qi
  • 2-pin <- Joystick Switch kirish
  • Pin 2 <- infraqizil LEDli kirish
  • VCC <- 5V
  • Zamin
  • Zamin #2

2 -qadam: Yangi eskiz yarating

Yangi eskiz yarating
Yangi eskiz yarating

Biz Arduino eskiz faylini yaratishni boshlaymiz. Bu joystikni o'zgartirish uchun so'rov o'tkazadi va bu o'zgarishlarni bir necha millisekundda C# dasturiga yuboradi. Haqiqiy video o'yinda biz ketma -ket portni o'yin tsiklida tekshiramiz, lekin men o'yinni tajriba sifatida boshladim, shuning uchun kadr tezligi ketma -ket portdagi voqealar soniga bog'liq. Men aslida loyihani Arduino opa -singil loyihasida boshlagan edim, lekin u ancha sekinroq va ekrandagi qutilar sonini boshqara olmasdi.

Shunday qilib, avval Arduino kod muharriri dasturida yangi eskiz yarating. Men kodimni ko'rsataman va keyin nima qilishini tushuntiraman:

#"IRremote.h" ni qo'shing

// IR o'zgaruvchilari int qabul qiluvchi = 3; // IQ qabul qiluvchining signal pimi IRrecv irrecv (qabul qiluvchi); // "irrecv" decode_results natijalarini yaratish; // "decode_results" misolini yaratish // Joystick/o'yin o'zgaruvchilari int xPos = 507; int yPos = 507; bayt joyXPin = A0; bayt joyYPin = A1; bayt joySwitch = 2; uchuvchi bayt clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // Standart = o'rtacha tezlik int speedIncrement = 25; // Y kirishi bilan tezlikni oshirish/pasaytirish miqdori imzosiz uzun oqim = 0; // joriy vaqt tamg'asini ushlab turadi int wait = 40; xabarlar o'rtasida kutish uchun // ms [Eslatma: past kutish = tezroq kadr tezligi] o'zgaruvchan bool tugmasi Pressed = false; // Agar tugma bosilsa o'lchash void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, sakrash, FALLING); joriy = millis (); // Joriy vaqtni sozlash // Infraqizil qabul qilgichni sozlash: irrecv.enableIRIn (); // Qabul qilgichni ishga tushiring} // void loop o'rnatish () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Joystick X harakatini vaqtidan qat'i nazar boshqaring: if (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Agar ozgina qimirlasangiz…? currentSpeed //… faqat joriy tezlikni qaytaring: getSpeed (yPos); // Faqat joystik sezilarli darajada harakatlansa yPos -ni o'zgartiring // int masofa =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); joriy = millis (); }} // loop int getSpeed (int yPos) {// Salbiy qiymatlar Joystick yuqoriga siljiganligini ko'rsatadi, agar (yPos 1023? 1023: currentSpeed + speedIncrement;} if else (yPos> minMoveHigh) // Interpreted "Down" {// Protect from 0 ga qaytish currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Ko'rsatish tugmasi bosildi.} // o'tish // Tugma bosilganda masofadan turib, to'g'ri javobni bekor qilish void translateIR (decode_results results) // olingan IR kodi asosida harakat qiladi {switch (results.value) {case 0xFF18E7: //Serial.println("2 "); currentSpeed += speedIncrement * 2; tanaffus; holat 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; default: //Serial.println (" boshqa tugma "); tanaffus;} // tugatish tugmasi} // tarjimani tugatishIR

Men kodni o'z-o'zidan tushunarli qilib yaratishga harakat qildim, lekin eslatib o'tishga arziydigan bir nechta narsa bor. Men hisoblamoqchi bo'lgan bir narsa quyidagi satrlarda edi:

int minYMoveUp = 520;

int minYMoveDown = 500;

Dastur ishlayotganda, joystikdan analog kirish odatda 507 atrofida qoladi. Buni to'g'rilash uchun minYMoveUp dan katta yoki minYMoveDowndan kichik bo'lmaguncha kirish o'zgarmaydi.

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, sakrash, FALLING);

AttachInterrupt () usuli har qanday vaqtda oddiy tsiklni to'xtatishga imkon beradi, shuning uchun biz joystick tugmasi bosilganda tugmani bosish kabi kirishni qabul qilishimiz mumkin. Bu erda biz pinMode () usuli yordamida uzilishni oldingi qatorga biriktirdik. Bu erda muhim eslatma shundaki, Arduino Uno -ga uzilish qo'shish uchun siz 2 yoki 3 -pinni ishlatishingiz kerak bo'ladi. Boshqa modellar har xil uzilish pinlarini ishlatadi, shuning uchun siz Arduino veb -saytida qaysi modelni ishlatishini tekshirishingiz kerak bo'ladi. Ikkinchi parametr, bu erda ISR yoki "Interrupt Service Routine" deb nomlangan qayta qo'ng'iroq qilish usuli uchun. U hech qanday parametrni olmasligi yoki hech narsani qaytarmasligi kerak.

Serial.print (…)

Bu bizning ma'lumotlarni C# o'yiniga yuboradigan chiziq. Bu erda biz o'yinga X o'qi o'qi, Y o'qi o'qishi va tezlik o'zgaruvchisini yuboramiz. Bu o'qishlar o'yinni yanada qiziqarli qilish uchun boshqa kirish va o'qishlarni kiritish uchun kengaytirilishi mumkin, lekin bu erda biz faqat juftlikdan foydalanamiz.

Agar siz o'z kodingizni sinab ko'rishga tayyor bo'lsangiz, uni Arduino -ga yuklang va ketma -ket monitorni ochish uchun [Shift] + [Ctrl] + [M] tugmalarini bosing va siz chiqayotganingizni tekshiring. Agar siz Arduino -dan ma'lumot olsangiz, biz kodning C# qismiga o'tishga tayyormiz …

3 -qadam: C# loyihasini yarating

Bizning grafikalarimizni ko'rsatish uchun men dastlab "Qayta ishlash" loyihasini boshladim, lekin keyinchalik biz ko'rsatishimiz kerak bo'lgan barcha ob'ektlarni ko'rsatish juda sekin bo'ladi deb qaror qildim. Shunday qilib, men C#-dan foydalanishni tanladim, bu bizning ma'lumotlarimiz bilan ishlashda ancha yumshoq va sezgir bo'lib chiqdi.

Loyihaning C# qismi uchun.zip faylini yuklab olish va uni o'z papkasiga ko'chirish, so'ng uni o'zgartirish yaxshidir. Zip faylida ikkita papka mavjud. Loyihani Visual Studio -da ochish uchun Windows Explorer -da RunnerGame_CSharp papkasini kiriting. Bu erda.sln (echim) faylini ikki marta bosing va VS loyihani yuklaydi.

O'yin uchun men yaratgan bir nechta sinflar mavjud. Men har bir sinf haqida tafsilotlarni aytmayman, lekin men asosiy sinflar nima uchun mo'ljallanganligi haqida umumiy ma'lumot beraman.

Box klassi

Men oyna shaklida ekranda chizilishi mumkin bo'lgan oddiy to'rtburchaklar ob'ektlarni yaratishga ruxsat berish uchun box sinfini yaratdim. G'oya, qandaydir grafik chizishni xohlaydigan boshqa sinflar yordamida kengaytiriladigan sinf yaratishdir. "Virtual" kalit so'zi boshqa sinflar ularni bekor qilishi uchun ishlatiladi ("bekor qilish" kalit so'zidan foydalaniladi). Shunday qilib, biz kerak bo'lganda Player va Platforma sinflari uchun xuddi shunday xatti -harakatlarga ega bo'lishimiz mumkin, shuningdek, biz xohlagan tarzda ob'ektlarni o'zgartirishimiz mumkin.

Hamma mulk haqida ko'p tashvishlanmang va qo'ng'iroq qiling. Men bu darsni kelajakda qilmoqchi bo'lgan har qanday o'yin yoki grafik dastur uchun kengaytirish uchun yozdim. Agar siz tezda to'rtburchaklar chizishingiz kerak bo'lsa, bunday katta sinfni yozishingiz shart emas. C# hujjatlarida buni qanday qilish haqida yaxshi misollar bor.

Biroq, men "Box" sinfining ba'zi mantiqlarini bayon qilaman:

umumiy virtual boC IsCollidedX (Box otherObject) {…}

Bu erda biz X yo'nalishidagi ob'ektlar bilan to'qnashuvni tekshiramiz, chunki o'yinchi faqat Y yo'nalishi bo'yicha (yuqoriga va pastga) to'qnashuvni tekshirishi kerak, agar u bilan ekranda tizilgan bo'lsa.

umumiy virtual boC IsCollidedY (Box otherObject) {…}

Biz boshqa o'yin ob'ektining ustida yoki ostida bo'lganimizda, biz Y to'qnashuvini tekshiramiz.

umumiy virtual bool IsCollided (Box otherObject) {…}

Bu X va Y to'qnashuvlarini birlashtiradi va har qanday ob'ekt bilan to'qnashganligini qaytaradi.

OnPaint umumiy ochiq virtual bo'sh joy (Grafika grafikasi) {…}

Yuqoridagi usuldan foydalanib, biz har qanday grafik ob'ektni o'tkazamiz va dastur ishlayotganda foydalanamiz. Biz chizishimiz mumkin bo'lgan har qanday to'rtburchaklar yaratamiz. Bu turli animatsiyalar uchun ishlatilishi mumkin. Bizning maqsadimiz uchun to'rtburchaklar platformalar uchun ham, o'yinchi uchun ham yaxshi bo'ladi.

Belgilar sinfi

Character klassi mening Box sinfimni kengaytiradi, shuning uchun bizda ma'lum fizika mavjud. Men to'qnashuv uchun biz yaratgan barcha platformalarni tezda tekshirish uchun "CheckForCollisions" usulini yaratdim. "O'tish" usuli o'yinchining yuqoriga ko'tarilish tezligini JumpSpeed o'zgaruvchisiga o'rnatadi, keyin MainWindow sinfida kadr-kadr o'zgartiriladi.

To'qnashuvlar bu erda Box sinfiga qaraganda biroz boshqacha tarzda boshqariladi. Men bu o'yinda shunday qaror qildimki, agar yuqoriga sakrasak, biz platformadan sakrashimiz mumkin, lekin u o'yinchini pastga tushganda ushlaydi.

Platforma klassi

Bu o'yinda men faqat X-koordinatasini kiritadigan ushbu sinf konstruktoridan foydalanaman, MainWindow sinfidagi barcha platformalarning X joylarini hisoblayman. Har bir platforma tasodifiy Y koordinatasida ekranning 1/2 qismidan ekran balandligining 3/4 qismigacha o'rnatiladi. Balandligi, kengligi va rangi ham tasodifiy hosil qilingan.

MainWindow klassi

Bu erda biz o'yin paytida hamma mantiqni ishlatamiz. Birinchidan, konstruktorda biz dasturda mavjud bo'lgan barcha COM portlarini chop etamiz.

foreach (SerialPort. GetPortNames () dagi portli port)

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

Biz qaysi birini qabul qilishni tanlaymiz, sizning Arduino qaysi portga mos keladi:

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

Buyruqqa katta e'tibor bering: SerialPort. GetPortNames () [2]. [2] qaysi ketma -ket portdan foydalanish kerakligini bildiradi. Masalan, agar dastur "COM1, COM2, COM3" ni chop etsa, biz COM3ni tinglagan bo'lardik, chunki raqamlash qatorda 0 dan boshlanadi.

Shuningdek, konstruktorda biz barcha platformalarni yarim tasodifiy intervalda va ekranda Y yo'nalishi bo'yicha joylashtiramiz. Barcha platformalar List ob'ektiga qo'shiladi, bu C# da juda qulay va massivga o'xshash ma'lumotlar tuzilmasini boshqarishning samarali usulidir. Keyin biz o'yinchi yaratamiz, bu bizning xarakterli ob'ektimiz, hisobni 0 ga o'rnatamiz va GameOver -ni noto'g'ri deb belgilaymiz.

Maxsus statik void DataReceived (ob'ektni yuboruvchi, SerialDataReceivedEventArgs e)

Bu ketma -ket portda ma'lumot olganda chaqiriladigan usul. Bu erda biz o'zimizning barcha fizikamizni qo'llaymiz, o'yinni ko'rsatishni, platformalarni ko'chirishni va hokazolarni hal qilamiz. Agar siz hech qachon o'yin qurmagan bo'lsangiz, odatda sizda "o'yin tsikli" deb nomlanadi. tetiklantiradi. Bu o'yinda DataReceived usuli o'yin tsikli vazifasini bajaradi, faqat ma'lumotni boshqaruvchidan olganda fizikani boshqaradi. Asosiy oynada taymerni o'rnatish va olingan ma'lumotlarga asoslangan ob'ektlarni yangilash yaxshiroq ishlagan bo'lishi mumkin edi, lekin bu Arduino loyihasi bo'lgani uchun men undan keladigan ma'lumotlarga asoslanib ishlaydigan o'yinni yaratmoqchi edim..

Xulosa qilib aytganda, ushbu sozlash o'yinni foydali narsaga kengaytirish uchun yaxshi asos yaratadi. Garchi fizika mukammal bo'lmasa -da, u bizning maqsadlarimiz uchun etarlicha yaxshi ishlaydi, ya'ni Arduino -ni hamma yoqtirgan narsaga ishlatish: o'yin o'ynash!

Tavsiya: