Daftar Isi:

Game Platformer yang Dikendalikan Arduino Dengan Joystick dan Penerima IR: 3 Langkah (dengan Gambar)
Game Platformer yang Dikendalikan Arduino Dengan Joystick dan Penerima IR: 3 Langkah (dengan Gambar)

Video: Game Platformer yang Dikendalikan Arduino Dengan Joystick dan Penerima IR: 3 Langkah (dengan Gambar)

Video: Game Platformer yang Dikendalikan Arduino Dengan Joystick dan Penerima IR: 3 Langkah (dengan Gambar)
Video: MEMBUAT GAME SNAKE ARDUINO LED MATRIX 8X8 DIKENDALIKAN DENGAN JOYSTICK || PROGRAM PAKE HAPE ANDROID🐍 2024, Juli
Anonim
Game Platformer yang Dikendalikan Arduino Dengan Joystick dan Penerima IR
Game Platformer yang Dikendalikan Arduino Dengan Joystick dan Penerima IR

Hari ini, kita akan menggunakan mikrokontroler Arduino untuk mengontrol game platformer berbasis C# sederhana. Saya menggunakan Arduino untuk mengambil input dari modul joystick, dan mengirim input itu ke aplikasi C# yang mendengarkan dan mendekode input melalui koneksi Serial. Meskipun Anda tidak memerlukan pengalaman sebelumnya dalam membuat video game untuk menyelesaikan proyek, mungkin diperlukan beberapa waktu untuk menyerap beberapa hal yang terjadi di "game loop", yang akan kita bahas nanti.

Untuk menyelesaikan proyek ini, Anda akan membutuhkan:

  • Komunitas Visual Studio
  • Arduino Uno (atau yang serupa)
  • Modul pengontrol joystick
  • Kesabaran

Jika Anda siap untuk memulai, lanjutkan!

Langkah 1: Hubungkan Joystick dan IR LED

Hubungkan Joystick dan LED IR
Hubungkan Joystick dan LED IR
Hubungkan Joystick dan LED IR
Hubungkan Joystick dan LED IR

Di sini, hookup cukup sederhana. Saya telah menyertakan diagram yang hanya menunjukkan joystick yang terhubung, serta pengaturan yang saya gunakan, yang mencakup joystick ditambah LED inframerah untuk mengendalikan game dengan remote control, yang dilengkapi dengan banyak kit Arduino. Ini opsional, tetapi sepertinya ide yang keren untuk dapat melakukan game nirkabel.

Pin yang digunakan dalam pengaturan adalah:

  • A0 (analog) <- Horizontal atau sumbu X
  • A1 (analog) <- Vertikal atau sumbu Y
  • Pin 2 <- Masukan Joystick Switch
  • Pin 2 <- Masukan LED inframerah
  • VCC <- 5V
  • Tanah
  • Tanah #2

Langkah 2: Buat Sketsa Baru

Buat Sketsa Baru
Buat Sketsa Baru

Kita akan mulai dengan membuat file sketsa Arduino kita. Ini melakukan polling pada joystick untuk perubahan, dan mengirimkan perubahan tersebut ke program C# setiap beberapa milidetik. Dalam video game yang sebenarnya, kami akan memeriksa port serial di loop game untuk input, tetapi saya memulai game sebagai percobaan, jadi framerate sebenarnya didasarkan pada jumlah peristiwa pada port serial. Saya sebenarnya telah memulai proyek di proyek saudara Arduino, Pemrosesan, tetapi ternyata jauh, jauh lebih lambat dan tidak dapat menangani jumlah kotak di layar.

Jadi, pertama buat Sketsa baru di program editor kode Arduino. Saya akan menunjukkan kode saya dan kemudian menjelaskan fungsinya:

#sertakan "IRremote.h"

// Variabel IR int penerima = 3; // Pin Sinyal penerima IR IRrecv irrecv(penerima); // buat contoh hasil decode_results 'irrecv'; // buat instance 'decode_results' // Variabel joystick/game int xPos = 507; int yPos = 507; byte joyXPin = A0; byte joyYPin = A1; byte joySwitch = 2; byte clickCounter yang mudah menguap = -1; int minMoveTinggi = 530; int minMoveLow = 490; int kecepatan arus = 550; // Default = kecepatan rata-rata int speedIncrement = 25; // Jumlah untuk menambah/mengurangi kecepatan dengan input Y arus panjang tidak bertanda = 0; // Menyimpan stempel waktu saat ini int wait = 40; // ms untuk menunggu di antara pesan [Catatan: tunggu lebih rendah = framerate lebih cepat] volatil bool buttonPressed = false; // Mengukur apakah tombol ini ditekan void setup() { Serial.begin(9600); pinMode(joySwitch, INPUT_PULLUP); attachInterrupt(0, lompat, JATUH); saat ini = mili(); // Mengatur waktu saat ini // Mengatur penerima inframerah: irrecv.enableIRIn(); // Jalankan receiver } // setup void loop() { int xMovement = analogRead(joyXPin); int yPos = analogRead(joyYPin); // Tangani gerakan Joystick X terlepas dari waktunya: if (xMovement > minMoveHigh || xMovement current + wait) { currentSpeed = yPos > minMoveLow && yPos < minMoveHigh // Jika hanya digerakkan sedikit… ? currentSpeed // …kembalikan saja kecepatan saat ini: getSpeed(yPos); // Ubah yPos hanya jika joystick bergerak secara signifikan //int distance =; Serial.print((String) xPos + ", " + (String) yPos + ', ' + (String) currentSpeed + '\n'); saat ini = mili(); } } // loop int getSpeed(int yPos) { // Nilai negatif menunjukkan Joystick bergerak ke atas if(yPos 1023 ? 1023: currentSpeed + speedIncrement; } else if(yPos > minMoveHigh) // Diartikan "Turun" { // Lindungi dari berjalan di bawah 0 mengembalikan arusKecepatan - peningkatan kecepatan < 0 ? 0: kecepatan saat ini - peningkatan kecepatan; } } // getSpeed void jump() { buttonPressed = true; // Menunjukkan tombol ditekan. } // jump // Ketika tombol ditekan pada remote, tangani respon yang tepat void translateIR(decode_results results) // mengambil tindakan berdasarkan kode IR yang diterima { 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; default: //Serial.println(" tombol lain "); break; }// Saklar akhir } //END translateIR

Saya mencoba membuat kode agar sebagian besar cukup jelas, tetapi ada beberapa hal yang perlu disebutkan. Satu hal yang saya coba pertanggungjawabkan ada di baris berikut:

int minYMoveUp = 520;

int minYMoveDown = 500;

Saat program berjalan, input analog dari joystick cenderung melompat-lompat, biasanya berada di sekitar 507. Untuk memperbaikinya, input tidak berubah kecuali lebih besar dari minYMoveUp, atau lebih kecil dari minYMoveDown.

pinMode(joySwitch, INPUT_PULLUP);

attachInterrupt(0, lompat, JATUH);

Metode attachInterrupt() memungkinkan kita untuk menginterupsi loop normal kapan saja, sehingga kita dapat mengambil input, seperti tombol yang ditekan saat tombol joystick diklik. Di sini, kita telah memasang interupsi di baris sebelumnya, menggunakan metode pinMode(). Catatan penting di sini adalah bahwa untuk memasang interupsi pada Arduino Uno, Anda harus menggunakan pin 2 atau 3. Model lain menggunakan pin interupsi yang berbeda, jadi Anda mungkin harus memeriksa pin mana yang digunakan model Anda di situs web Arduino. Parameter kedua adalah untuk metode panggilan balik, di sini disebut ISR atau "Rutin Layanan Interupsi". Seharusnya tidak mengambil parameter apa pun atau mengembalikan apa pun.

Serial.print(…)

Ini adalah baris yang akan mengirimkan data kita ke game C#. Di sini, kami mengirim pembacaan sumbu X, pembacaan sumbu Y, dan variabel kecepatan ke game. Pembacaan ini dapat diperluas untuk memasukkan masukan dan bacaan lain untuk membuat permainan lebih menarik, tetapi di sini, kami hanya akan menggunakan beberapa.

Jika Anda siap untuk menguji kode Anda, unggah ke Arduino, dan tekan [Shift] + [Ctrl] + [M] untuk membuka monitor serial dan lihat apakah Anda mendapatkan output apa pun. Jika Anda menerima data dari Arduino, kami siap untuk melanjutkan ke bagian kode C#…

Langkah 3: Buat Proyek C#

Untuk menampilkan grafik kita, awalnya saya memulai sebuah proyek di Processing, tetapi kemudian memutuskan akan terlalu lambat untuk menampilkan semua objek yang perlu kita tampilkan. Jadi, saya memilih untuk menggunakan C#, yang ternyata jauh lebih halus dan lebih responsif saat menangani input kami.

Untuk bagian C# dari proyek, yang terbaik adalah mengunduh file.zip dan mengekstraknya ke foldernya sendiri, lalu memodifikasinya. Ada dua folder dalam file zip. Untuk membuka proyek di Visual Studio, masukkan folder RunnerGame_CSharp di Windows Explorer. Di sini, klik dua kali file.sln (solusi), dan VS akan memuat proyek.

Ada beberapa kelas berbeda yang saya buat untuk game. Saya tidak akan membahas semua detail tentang setiap kelas, tetapi saya akan memberikan gambaran tentang apa tujuan kelas utama.

Kelas Kotak

Saya membuat kelas kotak untuk memungkinkan Anda membuat objek persegi panjang sederhana yang dapat digambar di layar dalam bentuk windows. Idenya adalah untuk membuat kelas yang dapat diperluas menggunakan kelas lain yang mungkin ingin menggambar beberapa jenis grafik. Kata kunci "virtual" digunakan agar kelas lain dapat menimpanya (menggunakan kata kunci "menimpa"). Dengan begitu, kita bisa mendapatkan perilaku yang sama untuk kelas Player dan kelas Platform saat kita membutuhkannya, dan juga memodifikasi objek sesuka kita.

Jangan terlalu khawatir tentang semua properti dan panggilan telepon. Saya menulis kelas ini sehingga saya dapat memperluasnya untuk game atau program grafis apa pun yang mungkin ingin saya buat di masa mendatang. Jika Anda hanya perlu menggambar persegi panjang dengan cepat, Anda tidak perlu menulis kelas besar seperti ini. Dokumentasi C# memiliki contoh yang baik tentang bagaimana melakukan ini.

Namun, saya akan memaparkan beberapa logika kelas "Kotak" saya:

bool virtual publik IsCollidedX(Kotak objek lain) { … }

Di sini kita memeriksa tabrakan dengan objek di arah X, karena pemain hanya perlu memeriksa tabrakan di arah Y (atas dan bawah) jika dia berbaris di layar.

bool virtual publik IsCollidedY(Kotak objek lain) { … }

Saat kita berada di atas atau di bawah objek game lain, kita memeriksa tabrakan Y.

bool virtual publik IsCollided(Kotak objek lain) { … }

Ini menggabungkan tabrakan X dan Y, mengembalikan apakah ada objek yang bertabrakan dengan objek ini.

public virtual void OnPaint(Graphics graphics) { … }

Dengan menggunakan metode di atas, kami memasukkan objek grafik apa pun dan menggunakannya saat program sedang berjalan. Kami membuat persegi panjang yang mungkin perlu digambar. Ini dapat digunakan untuk berbagai animasi. Untuk tujuan kita, persegi panjang akan baik-baik saja untuk platform dan pemutar.

Kelas Karakter

Kelas Karakter memperluas kelas Kotak saya, jadi kami memiliki fisika tertentu di luar kotak. Saya membuat metode "CheckForCollisions" untuk memeriksa dengan cepat semua platform yang telah kami buat untuk tabrakan. Metode "Lompat" menetapkan kecepatan ke atas pemain ke variabel JumpSpeed, yang kemudian dimodifikasi frame-by-frame di kelas MainWindow.

Tabrakan ditangani sedikit berbeda di sini daripada di kelas Box. Saya memutuskan dalam game ini bahwa jika melompat ke atas, kita dapat melompat melalui platform, tetapi itu akan menangkap pemain kita saat turun jika bertabrakan dengannya.

Kelas Platform

Dalam game ini, saya hanya menggunakan konstruktor kelas ini yang mengambil koordinat X sebagai input, menghitung semua lokasi X platform di kelas MainWindow. Setiap platform diatur pada koordinat Y acak dari 1/2 layar hingga 3/4 tinggi layar. Tinggi, lebar, dan warna juga dihasilkan secara acak.

Kelas Jendela Utama

Di sinilah kami meletakkan semua logika untuk digunakan saat game sedang berjalan. Pertama, di konstruktor, kami mencetak semua port COM yang tersedia untuk program.

foreach(port string di SerialPort. GetPortNames())

Console. WriteLine("PORT YANG TERSEDIA: " + port);

Kami memilih yang mana kami akan menerima komunikasi, sesuai dengan port yang sudah digunakan Arduino Anda:

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

Perhatikan baik-baik perintah: SerialPort. GetPortNames()[2]. [2] menandakan port serial mana yang akan digunakan. Misalnya, jika program mencetak "COM1, COM2, COM3", kita akan mendengarkan pada COM3 karena penomoran dimulai dari 0 dalam array.

Juga di konstruktor, kami membuat semua platform dengan spasi semi-acak dan penempatan dalam arah Y di layar. Semua platform ditambahkan ke objek Daftar, yang dalam C# hanyalah cara yang sangat ramah pengguna dan efisien untuk mengelola struktur data seperti array. Kami kemudian membuat Player, yang merupakan objek Karakter kami, atur skor ke 0 dan atur GameOver ke false.

private static void DataReceived (pengirim objek, SerialDataReceivedEventArgs e)

Ini adalah metode yang dipanggil ketika data diterima di port Serial. Di sinilah kami menerapkan semua fisika kami, memutuskan apakah akan menampilkan game over, memindahkan platform, dll. Jika Anda pernah membuat game, biasanya Anda memiliki apa yang disebut "game loop", yang disebut setiap kali frame menyegarkan. Dalam game ini, metode DataReceived bertindak sebagai game loop, hanya memanipulasi fisika saat data diterima dari pengontrol. Mungkin bekerja lebih baik untuk mengatur Timer di jendela utama, dan menyegarkan objek berdasarkan data yang diterima, tetapi karena ini adalah proyek Arduino, saya ingin membuat game yang benar-benar berjalan berdasarkan data yang masuk darinya.

Kesimpulannya, pengaturan ini memberikan dasar yang baik untuk mengembangkan game menjadi sesuatu yang dapat digunakan. Meskipun fisikanya tidak cukup sempurna, ia bekerja cukup baik untuk tujuan kita, yaitu menggunakan Arduino untuk sesuatu yang disukai semua orang: bermain game!

Direkomendasikan: