Mündəricat:

Joystick və IR Alıcı ilə Arduino İdarə olunan Platformer Oyunu: 3 Addım (Şəkillərlə)
Joystick və IR Alıcı ilə Arduino İdarə olunan Platformer Oyunu: 3 Addım (Şəkillərlə)

Video: Joystick və IR Alıcı ilə Arduino İdarə olunan Platformer Oyunu: 3 Addım (Şəkillərlə)

Video: Joystick və IR Alıcı ilə Arduino İdarə olunan Platformer Oyunu: 3 Addım (Şəkillərlə)
Video: Yeni metod ortaya çıxdı! Uzaqdan idarəetmə maşını necə istehsal olunur! Stirling mühərriki! RC 2024, Iyul
Anonim
Joystick və IR Alıcı ilə Arduino İdarə olunan Platformer Oyunu
Joystick və IR Alıcı ilə Arduino İdarə olunan Platformer Oyunu

Bu gün C#əsaslı sadə bir platformer oyununu idarə etmək üçün bir Arduino mikro nəzarətçisindən istifadə edəcəyik. Bir joystick modulundan giriş almaq və bu girişi Serial bağlantı üzərindən dinləyən və deşifr edən C# tətbiqinə göndərmək üçün Arduinodan istifadə edirəm. Layihəni başa çatdırmaq üçün video oyunlar qurmaqda əvvəlki təcrübəyə ehtiyacınız olmasa da, daha sonra müzakirə edəcəyimiz "oyun döngəsində" baş verən bəzi şeyləri mənimsəmək üçün bir az vaxt tələb oluna bilər.

Bu layihəni başa çatdırmaq üçün sizə lazım olacaq:

  • Visual Studio Birliyi
  • Bir Arduino Uno (və ya bənzəri)
  • Bir joystick nəzarətçi modulu
  • Səbir

Başlamağa hazırsınızsa, davam edin!

Addım 1: Joystick və IR LEDini bağlayın

Joystick və IR LEDini bağlayın
Joystick və IR LEDini bağlayın
Joystick və IR LEDini bağlayın
Joystick və IR LEDini bağlayın

Burada bağlama olduqca sadədir. Yalnız qoşulduğu joysticki göstərən diaqramları, eləcə də bir çox Arduino dəsti ilə gələn uzaqdan idarəetmə ilə oyunu idarə etmək üçün joystick və infraqırmızı LEDdən ibarət istifadə etdiyim quruluşu daxil etdim. Bu isteğe bağlıdır, ancaq simsiz oyun oynaya bilmək sərin bir fikir kimi görünürdü.

Quraşdırmada istifadə olunan pinlər bunlardır:

  • A0 (analoq) <- Üfüqi və ya X oxlu
  • A1 (analoq) <- Şaquli və ya Y oxu
  • Pin 2 <- Joystick Switch girişi
  • Pin 2 <- İnfraqırmızı LED girişi
  • VCC <- 5V
  • Zəmin
  • Zəmin #2

Addım 2: Yeni eskiz yaradın

Yeni eskiz yaradın
Yeni eskiz yaradın

Arduino eskiz faylımızı yaratmağa başlayacağıq. Bu dəyişikliklər üçün joysticki sorğu edir və bu dəyişiklikləri hər neçə milisaniyədə C# proqramına göndərir. Həqiqi bir video oyunda, giriş üçün bir oyun döngəsindəki serial portunu yoxlayırdıq, amma oyuna təcrübə olaraq başladım, buna görə də kadr tezliyi serial portundakı hadisələrin sayına əsaslanır. Layihəni həqiqətən Arduino bacısı layihəsi olan Processing -də başlamışdım, amma çox daha yavaş olduğu və ekrandakı qutuların sayını idarə edə bilmədiyi ortaya çıxdı.

Beləliklə, əvvəlcə Arduino kod redaktoru proqramında yeni bir Sketch yaradın. Kodumu göstərəcəyəm və sonra nə etdiyini izah edəcəyəm:

#"IRremote.h" daxil edin

// IR dəyişənləri int alıcı = 3; // IR qəbuledicisinin siqnal pimi IRrecv irrecv (alıcı); // 'irrecv' decode_results nəticələrinin nümunəsini yaratmaq; // 'decode_results' nümunəsi yaradın // Joystick/oyun dəyişənləri int xPos = 507; int yPos = 507; bayt joyXPin = A0; bayt sevincYPin = A1; bayt sevinciSwitch = 2; uçucu bayt clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // Varsayılan = orta sürət int speedIncrement = 25; // Y girişi ilə sürəti artırmaq/azaltmaq üçün məbləğ işarəsiz uzun cərəyan = 0; // Cari vaxt damğasını saxlayır int wait = 40; mesajlar arasında gözləmək üçün // ms [Qeyd: aşağı gözləmə = daha sürətli kadr] uçucu bool düyməsini basdı = yalan; // Düyməyə basıldığını ölçün void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, atlama, Yıxılma); cari = milis (); // Cari vaxtı qurun // İnfraqırmızı qəbuledicini qurun: irrecv.enableIRIn (); // Alıcını işə salın} // void loop qurun () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Vaxtından asılı olmayaraq Joystick X hərəkətini idarə edin: əgər (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Yalnız bir az hərəkət etsəniz…? currentSpeed //… yalnız cari sürəti qaytarın: getSpeed (yPos); // Yalnız joystick əhəmiyyətli dərəcədə hərəkət edərsə yPos dəyişdirin // int məsafə =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); cari = milis (); }} // loop int getSpeed (int yPos) {// Mənfi dəyərlər Joystick -in yuxarıya doğru irəlilədiyini göstərir (əgər yPos 1023? 1023: currentSpeed + speedIncrement;} if else (yPos> minMoveHigh) // "Aşağı" şərh olunur {// Qorumaq 0 -a qayıdır currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Göstər düyməsinə basıldı.} // jump // Bir düyməyə basıldığında uzaqdan, düzgün cavabı idarə et void translateIR (decode_results results) // alınan IR koduna əsasən hərəkət edir {switch (results.value) {case 0xFF18E7: //Serial.println("2 "); currentSpeed += speedIncrement * 2; fasilə; hal 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 (" digər düymə "); fasilə;} // Bitiş açarı} // SÖYÜDÜN tərcümə

Kodu əsasən özünü izah etmək üçün yaratmağa çalışdım, amma qeyd etməyə dəyər bir neçə şey var. Hesab etməyə çalışdığım bir şey aşağıdakı sətirlərdə idi:

int minYMoveUp = 520;

int minYMoveDown = 500;

Proqram işləyərkən, joystickin analoq girişi təxminən 507 ətrafında qalaraq ətrafa tullanmağa meyllidir. Bunu düzəltmək üçün minYMoveUp -dan böyük və ya minYMoveDown -dan kiçik olmadıqda giriş dəyişmir.

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, atlama, Yıxılma);

AttachInterrupt () metodu, istənilən vaxt normal döngəni kəsməyimizə imkan verir, belə ki, joystick düyməsinə basıldıqda düyməni basmaq kimi girişi götürə bilərik. Burada pinMode () metodundan istifadə edərək kəsilməni xəttin önünə bağladıq. Burada əhəmiyyətli bir qeyd, Arduino Uno -da bir kəsmə əlavə etmək üçün 2 və ya 3 pin istifadə etməlisiniz. Digər modellər fərqli kəsmə pinləri istifadə edir, buna görə də modelinizin Arduino saytında hansı pinlərdən istifadə etdiyini yoxlamalı ola bilərsiniz. İkinci parametr, burada ISR və ya "Interrupt Service Routine" adlanan geri çağırma metodu üçündür. Heç bir parametr almamalı və heç bir şey qaytarmamalıdır.

Serial.çap (…)

Bu, məlumatlarımızı C# oyununa göndərəcək xəttdir. Burada X oxu oxu, Y oxu oxu və sürət dəyişənini oyuna göndəririk. Bu oxunuşlar oyunu daha maraqlı etmək üçün digər girişləri və oxunuşları daxil etmək üçün genişləndirilə bilər, ancaq burada yalnız bir cüt istifadə edəcəyik.

Kodunuzu sınamağa hazırsınızsa, Arduinoya yükləyin və [Shift] + [Ctrl] + [M] düymələrini basaraq serial monitoru açın və hər hansı bir çıxış əldə edib -etmədiyinizi yoxlayın. Arduinodan məlumat alırsınızsa, kodun C# hissəsinə keçməyə hazırıq …

Addım 3: C# Layihəsi yaradın

Qrafiklərimizi göstərmək üçün əvvəlcə Qenerasiya sahəsində bir layihəyə başladım, amma sonra göstərməyimiz lazım olan bütün obyektləri göstərməyin çox yavaş olacağına qərar verdim. Beləliklə, girişimizi idarə edərkən daha hamar və daha həssas olduğu ortaya çıxan C#-dən istifadə etməyi seçdim.

Layihənin C# hissəsi üçün.zip faylını yükləmək və öz qovluğuna çıxarmaq, sonra dəyişdirmək ən yaxşısıdır. Zip faylında iki qovluq var. Layihəni Visual Studio'da açmaq üçün Windows Explorer -də RunnerGame_CSharp qovluğuna daxil olun. Burada.sln (həll) faylını iki dəfə vurun və VS layihəni yükləyəcək.

Oyun üçün yaratdığım bir neçə fərqli sinif var. Hər bir sinif haqqında bütün detallara girməyəcəyəm, amma əsas siniflərin nəyə görə hazırlandığına ümumi bir fikir verəcəyəm.

Qutu sinfi

Bir pəncərə şəklində ekranda çəkilə bilən sadə düzbucaqlı obyektlər yaratmağınıza imkan vermək üçün box sinifini yaratdım. Fikir, bir növ qrafik çəkmək istəyə biləcək digər siniflərdən istifadə edərək genişləndirilə bilən bir sinif yaratmaqdır. "Virtual" açar sözü digər siniflərin onları ləğv etməsi üçün istifadə olunur ("ləğv etmək" açar sözündən istifadə etməklə). Bu yolla, ehtiyac duyduğumuz zaman Oyunçu sinfi və Platform sinfi üçün eyni davranışı əldə edə bilərik və lazım olduğu kimi obyektləri də dəyişdirə bilərik.

Bütün mülklər haqqında çox narahat olmayın və zənglər çəkin. Gələcəkdə etmək istədiyim hər hansı bir oyun və ya qrafik proqramı üçün genişləndirə biləcəyim üçün bu sinfi yazdım. Bir anda düzbucaqlı çəkmək lazımdırsa, belə böyük bir sinif yazmaq lazım deyil. C# sənədlərində bunun necə ediləcəyinə dair yaxşı nümunələr var.

Ancaq "Box" sinifimin bəzi məntiqlərini açıqlayacağam:

ictimai virtual bool IsCollidedX (Box otherObject) {…}

Burada X istiqamətindəki cisimlərlə toqquşma olub olmadığını yoxlayırıq, çünki oyunçunun ekranda düzülmüş olması halında yalnız Y istiqamətində (yuxarı və aşağı) toqquşmaları yoxlaması lazımdır.

ictimai virtual bool IsCollidedY (Box otherObject) {…}

Başqa bir oyun obyektinin altında və ya altında olduğumuzda, Y toqquşmalarını yoxlayırıq.

ictimai virtual bool IsCollided (Box otherObject) {…}

Bu, X və Y toqquşmalarını birləşdirərək, hər hansı bir obyektin bu obyektlə toqquşub -vuruşmadığını qaytarır.

ictimai virtual boşluq OnPaint (Qrafik qrafika) {…}

Yuxarıdakı üsuldan istifadə edərək hər hansı bir qrafik obyektini içəri keçiririk və proqram işləyərkən istifadə edirik. Çəkmək lazım ola biləcək hər hansı bir düzbucaq yaradırıq. Bu müxtəlif animasiyalar üçün istifadə oluna bilər. Bizim məqsədlərimiz üçün, düzbucaqlılar həm platformalar, həm də oyunçu üçün yaxşı olacaq.

Xarakter sinfi

Character sinfi Box sinifimi uzadır, buna görə də müəyyən fizikamız var. Toqquşma üçün yaratdığımız bütün platformaları tez yoxlamaq üçün "CheckForCollisions" metodunu yaratdım. "Keç" metodu, oyunçunun yuxarı sürətini JumpSpeed dəyişəninə təyin edir, sonra MainWindow sinifində kadr-kadr dəyişdirilir.

Burada toqquşmalar Box sinifindən bir qədər fərqli şəkildə idarə olunur. Bu oyunda qərara gəldim ki, yuxarıya tullansaq, bir platformadan tullana bilərik, ancaq onunla toqquşarsa, oyunçumuzu aşağı yolda tutar.

Platform Sinifi

Bu oyunda, MainWindow sinifindəki platformaların X yerlərinin hamısını hesablayaraq, yalnız X-koordinatını giriş olaraq qəbul edən bu sinif qurucusundan istifadə edirəm. Hər platforma ekranın 1/2 hissəsindən ekranın hündürlüyünün 3/4 hissəsinə qədər təsadüfi bir Y koordinatında qurulur. Boy, en və rəng də təsadüfi olaraq yaradılır.

MainWindow Sinifi

Oyun işləyərkən istifadə ediləcək bütün məntiqləri burada qoyduq. Birincisi, konstruktorda, proqramda mövcud olan bütün COM portlarını çap edirik.

foreach (SerialPort. GetPortNames () -də simli port)

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

Arduinonun artıq hansı limana görə istifadə etdiyini, hansı ünsiyyəti qəbul edəcəyimizi seçirik:

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

Komandaya diqqət yetirin: SerialPort. GetPortNames () [2]. [2] hansı seriyalı portdan istifadə olunacağını bildirir. Məsələn, proqram "COM1, COM2, COM3" yazdırsaydı, COM3 -də dinləyərdik, çünki nömrələmə serialda 0 -dan başlayır.

Həm də konstruktorda, bütün platformaları yarı təsadüfi aralıqlarla və ekranda Y istiqamətində yerləşdirərək yaradırıq. Bütün platformalar, C# -də bir sıra bənzər bir məlumat quruluşunu idarə etmək üçün çox istifadəçi dostu və səmərəli bir yol olan bir List obyektinə əlavə olunur. Ardından, Xarakter obyektimiz olan Oyunçunu yaradırıq, hesabı 0 olaraq qoyuruq və GameOver -i yalana qoyuruq.

Şəxsi statik boşluq DataReceived (obyekt göndərən, SerialDataReceivedEventArgs e)

Serial portda məlumat alındıqda çağırılan bu üsuldur. Bura bütün fizikamızı tətbiq etdiyimiz, oyunu göstərib -göstərməyəcəyimizə, platformaları hərəkət etdirməyimizə və s. Qərar verdiyimiz yerdir. Əgər heç bir oyun qurmusunuzsa, ümumiyyətlə, hər dəfə çərçivədə adlandırılan "oyun döngəsi" adlanır. təzələyir. Bu oyunda, DataReceived metodu oyun döngəsi rolunu oynayır, yalnız məlumat nəzarətçidən alındıqca fizikanı manipulyasiya edir. Əsas pəncərədə bir Taymer qurmaq və alınan məlumatlara əsaslanaraq obyektləri yeniləmək daha yaxşı işləyə bilərdi, amma bu bir Arduino layihəsi olduğu üçün oradan daxil olan məlumatlara əsaslanaraq işləyən bir oyun hazırlamaq istədim..

Nəticə olaraq, bu qurğu oyunu genişləndirmək üçün yaxşı bir əsas verir. Fizika olduqca mükəmməl olmasa da, məqsədlərimiz üçün kifayət qədər yaxşı işləyir, yəni Arduino'yu hər kəsin bəyəndiyi bir şey üçün istifadə etmək: oyun oynamaq!

Tövsiyə: