Arduboy adalah sistem permainan mini seukuran kartu kredit. Itu datang diinstal dengan game 8-bit klasik dan dapat diprogram ulang dari perpustakaan game open source yang tersedia online. Arduboy adalah open source sehingga Anda dapat belajar coding dan membuat game Anda sendiri. Versi aslinya didasarkan pada mikrokontroler ATmega32U4 dan layar OLED serial 128x64 Piksel.
Konsol yang konstruksinya ditunjukkan di bawah ini terdiri dari Arduino Nano dan layar OLED versi I2C yang bisa lebih mudah ditemukan dengan harga lebih murah. Anda dapat mengunduh pustaka dan kode yang diperlukan di:
Jika Anda memiliki printer 3D, Anda juga dapat mengunduh file .STL dari opsi kotak yang memungkinkan di mana konsol diinstal. Panduan instalasi terperinci tersedia di situs yang sama. Ini didukung oleh Arduino Nano dengan satu baterai lithium-ion 3,7v dan bekerja dengan cukup baik.
dan masih banyak lagi...
Skema ditunjukkan di bawah ini.
Sebagai contoh, saya menyajikan kode untuk game ArduBreakout, tetapi Anda dapat mengunduh game lain di situs Arduboy yang kompatibel dengan versi konsol ini.
Kode
Game ArduBreakoutArduino
/* Breakout Hak Cipta (C) 2011 Sebastian Goscik Hak cipta dilindungi undang-undang. Modifikasi oleh Scott Allen 2016 (setelah perubahan sebelumnya oleh ???) Perpustakaan ini adalah perangkat lunak gratis; Anda dapat mendistribusikan ulang dan/atau memodifikasinya di bawah ketentuan Lisensi Publik Umum GNU yang diterbitkan oleh Free Software Foundation; baik versi 2.1 dari Lisensi, atau (sesuai pilihan Anda) versi yang lebih baru. */#sertakan // blok di EEPROM untuk menyimpan skor tinggi#define EE_FILE 2Arduboy2 arduboy;BeepPin1 beep;const unsigned int FRAME_RATE =40; // Kecepatan bingkai dalam bingkai per detikconst unsigned int KOLOM =13; //Kolom dari bricksconst unsigned int ROWS =4; //Baris bricksint dx =-1; //Gerakan awal ballint dy =-1; //Gerakan awal ballint xb; //Posisi awal bola di yb; //Bola mulai posisi boolean dilepaskan; //Jika bola telah dilepaskan oleh playerboolean pause =false; //Jika game telah dijeda oleh xPaddle; //X posisi paddleboolean isHit[ROWS][COLUMNS]; //Array jika batu bata terkena atau notboolean terpental=false; //Digunakan untuk memperbaiki bouncing ganda glitchbyte hidup =3; //Jumlah level byte hidup =1; //level saat ini unsigned int score=0; //Skor untuk gameunsigned int brickCount; //Jumlah bata hitboolean pad, pad2, pad3; //Tombol tekan buffer digunakan untuk menghentikan jeda pengulangan boolean oldpad, oldpad2, oldpad3;char text_buffer[16]; //Umum string bufferboolean start=false; //Jika di menu atau di gameboolean initialDraw=false;//Jika inital draw sudah terjadichar initials[3]; //Inisial yang digunakan dalam skor tinggi//Ball Bounds digunakan dalam pendeteksian tabrakanbyte LeftBall;byte rightBall;byte topBall;byte bottomBall;//Brick Bounds digunakan dalam pendeteksian tabrakanbyte leftBrick;byte rightBrick;byte topBrick;byte bottomBrick;byte tick;void setup (){ arduboy.begin(); bip.mulai(); arduboy.setFrameRate(FRAME_RATE); arduboy.initRandomSeed();}void loop(){ // jeda render sampai waktunya untuk frame berikutnya if (!(arduboy.nextFrame())) return; // Menangani pengaturan waktu dan penghentian nada beep.timer(); //Loop layar judul beralih dari layar judul //dan skor tinggi hingga FIRE ditekan saat (!start) { start =titleScreen(); if (!start) { start =displayHighScores(EE_FILE); } } //Pengundian level awal if (!initialDraw) { //Mengosongkan layar arduboy.clear(); //Memilih Font //Menggambar level level baru =1; tingkat baru(); skor =0; initialDraw=benar; } if (hidup>
0) { drawPaddle(); //Jeda game jika FIRE menekan pad =arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON); if(pad ==true &&oldpad ==false &&dirilis) { oldpad2 =false; //Memaksa pad loop 2 untuk dijalankan sekali jeda(); } papan tua =bantalan; drawBall(); if(BrickCount ==BARIS * KOLOM) { level++; tingkat baru(); } } else { drawGameOver(); if (skor> 0) { enterHighScore(EE_FILE); } arduboy.clear(); initialDraw=salah; mulai =salah; hidup=3; tingkat baru(); } arduboy.display();}void movePaddle(){ //Pindah ke kanan if(xPaddle 0) { if (arduboy.pressed(LEFT_BUTTON)) { xPaddle-=2; } }}void moveBall(){ centang++; if(dirilis) { //Pindahkan bola if (abs(dx)==2) { xb +=dx/2; // Kecepatan 2x benar-benar kecepatan 1,5 if (centang%2==0) xb +=dx/2; } else { xb +=dx; } yb=yb + dy; //Menetapkan batas leftBall =xb; bola kanan =xb + 2; bola atas =yb; bola bawah =yb + 2; //Terpental dari tepi atas if (yb <=0) { yb =2; dy =-dy; playTone(523, 250); } //Kehilangan nyawa jika tepi bawah terkena if (yb>=64) { arduboy.drawRect(xPaddle, 63, 11, 1, 0); xDayung =54; yb=60; dilepaskan =salah; hidup--; playToneTimed(175, 500); if (acak(0, 2) ==0) { dx =1; } else { dx =-1; } } //Terpental ke kiri jika (xb <=0) { xb =2; dx =-dx; playTone(523, 250); } //Terpental ke kanan jika (xb>=LEBAR - 2) { xb =LEBAR - 4; dx =-dx; playTone(523, 250); } //Bounce off dayung if (xb+1>=xPaddle &&xb<=xPaddle+12 &&yb+2>=63 &&yb<=64) { dy =-dy; dx =((xb-(xPaddle+6))/3); //Menerapkan putaran pada bola // mencegah pantulan lurus if (dx ==0) { dx =(random(0,2) ==1) ? 1 :-1; } playTone(200, 250); } //Memantulkan Batu Bata untuk (baris byte =0; baris =topBrick &&leftBall <=rightBrick &&rightBall>=leftBrick) { Score(); jumlah bata++; isHit[baris][kolom] =true; arduboy.drawRect(10*kolom, 2+6*baris, 8, 4, 0); //Tabrakan vertikal if (Bola Bawah> Bata Bawah || Bola Atas Bata kanan) { //Hanya memantul sekali bata setiap bola bergerak if(!memantul) { dx =- dx; xb +=dx; terpental =benar; playTone(261, 250); } } } } } } //Reset Pantulan terpental =false; } else { //Bola mengikuti dayung xb=xPaddle + 5; //Lepaskan bola jika FIRE ditekan pad3 =arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON); if (pad3 ==true &&oldpad3 ==false) { dirilis =true; //Terapkan arah acak ke bola saat dilepaskan if (random(0, 2) ==0) { dx =1; } else { dx =-1; } //Pastikan bola mengarah ke atas dy =-1; } oldpad3 =pad3; }}void drawBall(){ // arduboy.setCursor(0,0); // arduboy.print(arduboy.cpuLoad()); // arduboy.print(" "); arduboy.drawPixel(xb, yb, 0); arduboy.drawPixel(xb+1, yb, 0); arduboy.drawPixel(xb, yb+1, 0); arduboy.drawPixel(xb+1, yb+1, 0); bergerakBola(); arduboy.drawPixel(xb, yb, 1); arduboy.drawPixel(xb+1, yb, 1); arduboy.drawPixel(xb, yb+1, 1); arduboy.drawPixel(xb+1, yb+1, 1);}void drawPaddle(){ arduboy.drawRect(xPaddle, 63, 11, 1, 0); pindahkan dayung(); arduboy.drawRect(xPaddle, 63, 11, 1, 1);}void drawGameOver(){ arduboy.drawPixel(xb, yb, 0); arduboy.drawPixel(xb+1, yb, 0); arduboy.drawPixel(xb, yb+1, 0); arduboy.drawPixel(xb+1, yb+1, 0); arduboy.setCursor(37, 42); arduboy.print("Permainan Selesai"); arduboy.setCursor(31, 56); arduboy.print("Nilai :"); arduboy.print(skor); arduboy.display(); arduboy.delayShort(4000);}void pause(){ pause =true; //Gambar jeda ke layar arduboy.setCursor(52, 45); arduboy.print("JEDA"); arduboy.display(); while (dijeda) { arduboy.delayShort(150); //Batalkan jeda jika FIRE ditekan pad2 =arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON); if (pad2 ==true &&oldpad2 ==false &&dirilis) { arduboy.fillRect(52, 45, 30, 11, 0); dijeda=salah; } oldpad2 =pad2; }}void Score(){ skor +=(level*10);}void newLevel(){ //Undraw paddle arduboy.drawRect(xPaddle, 63, 11, 1, 0); //Undraw bola arduboy.drawPixel(xb, yb, 0); arduboy.drawPixel(xb+1, yb, 0); arduboy.drawPixel(xb, yb+1, 0); arduboy.drawPixel(xb+1, yb+1, 0); //Ubah berbagai variabel untuk mereset game xPaddle =54; yb =60; jumlah bata =0; dilepaskan =salah; //Menggambar batu bata baru dan mengatur ulang nilainya untuk (baris byte =0; baris <4; baris++) { for (kolom byte =0; kolom <13; kolom++) { isHit[baris][kolom] =false; arduboy.drawRect(10*kolom, 2+6*baris, 8, 4, 1); } } arduboy.display();}//Digunakan untuk menunda gambar saat membaca tombol inputboolean pollFireButton(int n){ for(int i =0; i 0) { sprintf(text_buffer, "%c%c%c %u", inisial[0], inisial[1], inisial[2], skor); arduboy.setCursor(x + 24, y + (i*8)); arduboy.print(text_buffer); arduboy.display(); } } if (pollFireButton(300)) { mengembalikan true; } kembali salah; arduboy.display();}boolean titleScreen(){ //Mengosongkan layar arduboy.clear(); arduboy.setCursor(16,22); arduboy.setTextSize(2); arduboy.print("BREAKOUT"); arduboy.setTextSize(1); arduboy.display(); if (pollFireButton(25)) { mengembalikan nilai true; } //Flash "Tekan FIRE" 5 kali untuk(byte i =0; i <5; i++) { //Menggambar "Tekan FIRE" arduboy.setCursor(31, 53); arduboy.print("TEKAN KEBAKARAN!"); arduboy.display(); if (pollFireButton(50)) { mengembalikan nilai true; } //Menghapus "Tekan FIRE" arduboy.setCursor(31, 53); arduboy.print(" "); arduboy.display(); if (pollFireButton(25)) { mengembalikan nilai true; } } return false;}//Fungsi oleh desain nootropic untuk menambahkan skor tinggivoid enterInitials(){ byte index =0; arduboy.clear(); inisial[0] =' '; inisial[1] =' '; inisial [2] =' '; while (benar) { arduboy.display(); arduboy.clear(); arduboy.setCursor(16,0); arduboy.print("SKOR TINGGI"); sprintf(text_buffer, "%u", skor); arduboy.setCursor(88, 0); arduboy.print(text_buffer); arduboy.setCursor(56, 20); arduboy.print(inisial[0]); arduboy.setCursor(64, 20); arduboy.print(inisial[1]); arduboy.setCursor(72, 20); arduboy.print(inisial [2]); for(byte i =0; i <3; i++) { arduboy.drawLine(56 + (i*8), 27, 56 + (i*8) + 6, 27, 1); } arduboy.drawLine(56, 28, 88, 28, 0); arduboy.drawLine(56 + (indeks*8), 28, 56 + (indeks*8) + 6, 28, 1); arduboy.delayShort(70); if (arduboy.pressed(LEFT_BUTTON) || arduboy.pressed(B_BUTTON)) { if (index> 0) { index--; playToneTimed(1046, 80); } } if (arduboy.pressed(RIGHT_BUTTON)) { if (indeks <2) { indeks++; playToneTimed(1046, 80); } } if (arduboy.pressed(UP_BUTTON)) { inisial[indeks]++; playToneTimed(523, 80); // A-Z 0-9 :-? !-/ ' ' if (inisial[indeks] =='0') { inisial[indeks] =' '; } if (inisial[indeks] =='!') { inisial[indeks] ='A'; } if (inisial[indeks] =='[') { inisial[indeks] ='0'; } if (inisial[indeks] =='@') { inisial[indeks] ='!'; } } if (arduboy.pressed(DOWN_BUTTON)) { inisial[indeks]--; playToneTimed(523, 80); if (inisial[indeks] ==' ') { inisial[indeks] ='?'; } if (inisial[indeks] =='/') { inisial[indeks] ='Z'; } if (inisial[indeks] ==31) { inisial[indeks] ='/'; } if (inisial[indeks] =='@') { inisial[indeks] =' '; } } if (arduboy.pressed(A_BUTTON)) { playToneTimed(1046, 80); if (indeks <2) { indeks++; } lain { kembali; } } }}void enterHighScore(byte file){ // Setiap blok EEPROM memiliki 7 skor tinggi, dan setiap entri skor tinggi // panjangnya 5 byte:3 byte untuk inisial dan dua byte untuk skor. int alamat =file * 7 * 5 + EEPROM_STORAGE_SPACE_START; byte hai, lo; char tmpInitials[3]; unsigned int tmpScore =0; // Pemrosesan skor tinggi untuk(byte i =0; i <7; i++) { hi =EEPROM.read(alamat + (5*i)); lo =EEPROM.read(alamat + (5*i) + 1); if ((hi ==0xFF) &&(lo ==0xFF)) { // Nilai tidak diinisialisasi, jadi perlakukan entri ini // sebagai skor 0. tmpScore =0; } else { tmpScore =(hai <<8) | lihat; } if (skor> tmpScore) { enterInitials(); for(byte j =i; j <7; j++) { hi =EEPROM.read(alamat + (5*j)); lo =EEPROM.read(alamat + (5*j) + 1); if ((hai ==0xFF) &&(lo ==0xFF)) { tmpScore =0; } else { tmpScore =(hai <<8) | lihat; } tmpInitials[0] =(char)EEPROM.read(alamat + (5*j) + 2); tmpInitials[1] =(char)EEPROM.read(alamat + (5*j) + 3); tmpInitials[2] =(char)EEPROM.read(alamat + (5*j) + 4); // tulis skor dan inisial ke slot saat ini EEPROM.update(alamat + (5*j), ((skor>> 8) &0xFF)); EEPROM.update(alamat + (5*j) + 1, (skor &0xFF)); EEPROM.update(alamat + (5*j) + 2, inisial[0]); EEPROM.update(alamat + (5*j) + 3, inisial[1]); EEPROM.update(alamat + (5*j) + 4, inisial [2]); // tmpScore dan tmpInitials sekarang menyimpan apa yang ingin kita // tulis di slot berikutnya. skor =tmpSkor; inisial[0] =tmpInitials[0]; inisial[1] =tmpInitials[1]; inisial [2] =tmpInitials [2]; } skor =0; inisial[0] =' '; inisial[1] =' '; inisial [2] =' '; kembali; } }}// Memutar nada pada frekuensi yang ditentukan untuk durasi yang ditentukan.void playTone(frekuensi int tidak ditandatangani, durasi int tidak ditandatangani){ beep.tone(beep.freq(frekuensi), durasi / (1000 / FRAME_RATE));} // Memutar nada pada frekuensi yang ditentukan untuk durasi yang ditentukan menggunakan// penundaan waktu nada.// Digunakan saat beep.timer() tidak dipanggil.void playToneTimed(frekuensi int unsigned, durasi int unsigned){ beep.tone(beep.freq(frekuensi)); arduboy.delayShort(durasi); beep.noTone();}
Suku cadang dan penutup khusus
3d_parts_ThLGvJvWga.rar Skema