Mục lục:

Trò chơi Arduino OLED Snake: 3 bước
Trò chơi Arduino OLED Snake: 3 bước

Video: Trò chơi Arduino OLED Snake: 3 bước

Video: Trò chơi Arduino OLED Snake: 3 bước
Video: Super mario Game | OLED Displays with Arduino - I2C & SPI OLEDs | OLED with Arduino to display 2024, Tháng bảy
Anonim
Trò chơi rắn Arduino OLED
Trò chơi rắn Arduino OLED

Xin chào và chào mừng bạn đến với tài liệu hướng dẫn của chúng tôi về cách tạo và trò chơi arduino OLED, dự án này được thực hiện khi chúng tôi đang cố gắng tạo ra trò chơi đầu tiên của mình với arduino, soooo, chúng tôi nghĩ nên bắt đầu từ đâu tốt hơn là Snake cổ điển của nokia (cũng tại ít nhất là nhân bản rắn:)).

Những gì bạn sẽ cần

Quân nhu

Arduino UNO hoặc sao chép

Màn hình OLED

4 điốt

Điện trở 500-1k

4 nút điều khiển

Bộ rung Piezo thụ động

không bắt buộc

Bánh mì không hàn

Xin lưu ý rằng những liên kết này chỉ là ví dụ

Bước 1: Mạch

Mạch
Mạch

Trong hình trên bạn có thể thấy mạch của chúng tôi, chúng tôi sử dụng chân d3 trên arduino làm chân yêu cầu ngắt để arduino sẽ ưu tiên đọc các đầu vào của bộ điều khiển là d4 d5 d6 d7. Cơ bản của mạch là một nút hướng được nhấn lên cao 5v, điều này sẽ kích hoạt chân yêu cầu ngắt (dây màu tím d3) và một chân hướng tương ứng, chức năng ngắt gọi chức năng cập nhật hướng và mã đó di chuyển con rắn tương ứng. Chân 9 được sử dụng làm chân âm thanh vì nó là một PWM (~ điều chế độ rộng xung) được kết nối trực tiếp với piezo 5v trên chân + và - quay trở lại 0v / mặt đất.

(FYI trên arduino una và clone chỉ có d2 và d3 có thể hoạt động như các chân yêu cầu ngắt).

Chốt hướng:

d4 Lên ORANGE

d5 Xuống HỒNG

d6 MÀU XANH LÁ bên trái

d7 MÀU NÂU phải

d9 âm thanh XÁM

Mỗi nút có một đầu vào kết nối 5v và một đầu ra được kết nối đầu tiên với đầu vào kỹ thuật số tương ứng của chúng trên arduino, đầu ra tương tự này của mỗi nút sau đó được kết nối với điốt riêng của nó, chúng tôi sử dụng các điốt để ngừng cấp điện trở lại cho các nút khác và kích hoạt chúng. Ở đầu cực âm (-) của cả 4 điốt chúng ta nối chúng lại với nhau để tạo ra một điểm nối đầu ra nối với d3 rồi thông qua điện trở 0v / đất để kéo các chân arduino xuống thấp để không để lại các chân nổi khi không được. đã được kích hoạt.

(FYI một chân nổi có thể nhận điện áp ảo và gây ra hành vi bất thường)

2 chân analog được sử dụng để điều khiển màn hình, đây là các chân i2c phần cứng của arduino.

A5 được kết nối với SCL VÀNG

A4 được kết nối với SDA GREEN

Đầu ra + 5v và 0v (đất) từ arduino được dùng làm nguồn cấp cho toàn mạch có thể cấp nguồn bằng usb hoặc sạc điện thoại.

Bước 2: Mã

// ------------------------ ANJAWARE SNAKE Games Với sự giúp đỡ từ các dân mạng --------------- -------

#bao gồm

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // bộ hiển thị (chiều rộng, chiều cao) Màn hình Adafruit_SSD1306 (128, 64); // xác định các chân đầu vào, đây là các chân trên arduino, chúng không bao giờ thay đổi nên #define #define INTPIN 3 // chỉ các chân 2 và 3 có thể là các chân xen kẽ trên UNO #define UPPIN 4 // đây là các chân kết nối tp chuyển đổi liên quan #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // xác định hướng đi #define DIRUP 1 // các giá trị này là những gì "con rắn" nhìn để quyết định- #define DIRDOWN 2 // hướng con rắn sẽ di chuyển # xác định DIRLEFT 3 # xác định DIRRIGHT 4

// đặt các biến nút

// volitile cos chúng ta cần nó cập nhật với interupt để có thể là bất kỳ bit nào của giá trị chu kỳ

// không bao giờ cao hơn 4 nên chỉ cần int 8bit để tiết kiệm tài nguyên dễ bay hơi uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // chúng tôi sử dụng điều này để đặt true để "phát hiện" hướng nào được nhấn bool butleft = 0; bool butright = 0;

// số nguyên con rắn

byte solidPosX [30]; // mảng tạo phần thân của byte rắn solidPosY [30];

int solidX = 30; // vị trí đầu rắn

int rắnY = 30; int solidSize = 1; // số lượng kích thước con rắn được giới hạn ở kích thước của mảng

// ints thế giới

uint8_t worldMinX = 0; // những điều này thiết lập giới hạn của khu vực vui chơi

uint8_t worldMaxX = 128; uint8_t worldMinY = 10; uint8_t worldMaxY = 63;

// thu thập scran (thức ăn) và vị trí của scran

bool scranAte = 0; uint8_t scranPosX = 0; uint8_t scranPosY = 0;

// biến số điểm

lượt chơi dài = 0; điểm cao dài = 30; // đặt điểm cao thành 3 lấy làm điểm bắt đầu

// --------------------------- đây là những gì interupt thực hiện khi tăng điện áp ------------ -------------

void interfepressed () {delay (150); // độ trễ nhẹ để bổ sung bảo vệ "trả lại" updatedirection (); } // ------------------ cập nhật giá trị hướng từ lần nhấn nút ----------------- void updatedirection () { // Serial.println ("updatedirection"); butup = digitalRead (UPPIN); // kiểm tra xem đầu vào nào cao hơn và đặt bool có liên quan true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // các trạng thái if này xem đầu vào nào cao hơn và nhập giá trị có liên quan vào // biến "buttonpressed", biến này chỉ định hướng di chuyển if (butup == true) {buttonpressed = DIRUP; // Serial.println ("Đã nhấn UP"); // Serial.println (buttonpressed); butup = false; giai điệu (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("Đã ấn XUỐNG"); // Serial.println (buttonpressed); butdown = sai; giai điệu (SND, 1500, 10); }

nếu (butleft == true)

{buttonpressed = DIRLEFT; // Serial.println ("Nhấn TRÁI"); // Serial.println (buttonpressed); butleft = sai; giai điệu (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("RIGHT ép"); // Serial.println (buttonpressed); butright = false; giai điệu (SND, 1500, 10); }}

// -------------------------- vẽ các quy trình hiển thị ------------------ -----------------

void updateDisplay () // vẽ điểm và phác thảo

{// Serial.println ("Cập nhật Hiển thị");

display.fillRect (0, 0, display.width () - 1, 8, BLACK);

display.setTextSize (0); display.setTextColor (TRẮNG); // vẽ điểm display.setCursor (2, 1); display.print ("Điểm:"); display.print (Chuỗi (điểm số, DEC)); display.setCursor (66, 1); display.print ("Cao:"); display.print (Chuỗi (điểm cao, DEC)); // vẽ vùng chơi // pos 1x, 1y, 2x, 2y, color display.drawLine (0, 0, 127, 0, WHITE); // viền rất trên cùng display.drawLine (63, 0, 63, 9, WHITE); // điểm seperator display.drawLine (0, 9, 127, 9, WHITE); // bên dưới đường viền văn bản display.drawLine (0, 63, 127, 63, WHITE); // đường viền dưới cùng display.drawLine (0, 0, 0, 63, WHITE); // viền trái display.drawLine (127, 0, 127, 63, WHITE); // đường viền bên phải

}

// ----------------------------------- cập nhật khu vui chơi ---------- --------------------

void updateGame () // điều này cập nhật hiển thị khu vực trò chơi

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// kiểm tra các quy trình của con rắn

if (outOfArea () || selfCollision ())

{gameOver (); }

// hiển thị con rắn

for (int i = 0; i0; i--) {solidPosX = solidPosX [i-1]; solidPosY = solidPosY [i-1]; } // thêm một pixel phụ vào con rắn if (scranAte) {solidSize + = 1; solidPosX [solidSize-1] = solidX; solidPosY [solidSize-1] = rắnY; }

switch (buttonpressed) // was solidDirection

{case DIRUP: solidY- = 1; nghỉ; case DIRDOWN: solidY + = 1; nghỉ; trường hợp DIRLEFT: solidX- = 1; nghỉ; case DIRRIGHT: solidX + = 1; nghỉ; } solidPosX [0] = solidX; solidPosY [0] = rắnY; updateDisplay (); display.display (); // --------------------- đặt scran -------------------

void placeScran ()

{scranPosX = random (worldMinX + 1, worldMaxX-1); scranPosY = ngẫu nhiên (worldMinY + 1, worldMaxY-1); } // ------------------------ QUÉT ĐIỂM ATE LÊN ---------------- bool scranFood () {if (solidX == scranPosX && solidY == scranPosY) {Playingcore = Playingcore + 10; giọng điệu (SND, 2000, 10); updateDisplay (); placeScran (); trả về 1; } else {return 0; } } //--------------------- ra khỏi khu vực---------------------- bool outOfArea () {return solidX = worldMaxX || SnakeY = worldMaxY; } // ---------------------- trò chơi kết thúc ----------------------- --- void gameOver () {uint8_t trực tràngX1, trực tràngY1, trực tràngX2, trực tràngY2; trực tràngX1 = 38; trực tràngY1 = 28; trực tràngX2 = 58; trực tràngY2 = 12; display.clearDisplay (); display.setCursor (40, 30); display.setTextSize (1); giọng điệu (SND, 2000, 50); display.print ("TRÒ CHƠI"); giai điệu (SND, 1000, 50); display.print ("HẾT"); if (Playingcore> = highscore) // kiểm tra xem điểm có cao hơn điểm cao không {highscore = Playingcore; // trạng thái đơn if để cập nhật điểm số cao} for (int i = 0; i <= 16; i ++) // đây là để vẽ các hình chữ nhật xung quanh trò chơi qua {display.drawRect (directX1, directY1, directX2, directY2, WHITE); Serial.println ("vòng lặp if"); display.display (); trực tràngX1- = 2; // dịch chuyển qua 2 pixel directY1- = 2; trực tràngX2 + = 4; // dịch chuyển trên 2 pixel từ điểm cuối cùng trực tiếpY2 + = 4; giai điệu (SND, i * 200, 3); } display.display (); // Xóa màn hình sau khi nổi tiếng qua directX1 = 0; // thiết lập vị trí bắt đầu của dòng directY1 = 0; trực tràngX2 = 0; trực tràngY2 = 63; for (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (trực tràngX1, trực tràngY1, trực tràngX2, trực tràngY2, ĐEN); trực tràngX1 ++; trực tràngX2 ++; display.display (); } display.clearDisplay (); điểm số lượt chơi = 0; // đặt lại chi tiết về con rắn và người chơi solidSize = 1; solidX = display.width () / 2; solidY = display.height () / 2; waitForPress (); // đợi người chơi bắt đầu trò chơi} // ------------------------- đợi vòng lặp nhấn ---------- --------------- void waitForPress () {bool wait = 0; // vòng lặp kết thúc whjen đây là true display.clearDisplay (); while (đang đợi == 0) {drawALineForMe (WHITE); // vẽ một đường màu trắng ngẫu nhiên drawALineForMe (BLACK); // vẽ một đường màu đen ngẫu nhiên để màn hình không hoàn toàn tô màu trắng display.fillRect (19, 20, 90, 32, BLACK); // nền trống cho văn bản display.setTextColor (WHITE); display.setCursor (35, 25); display.setTextSize (2); // phông chữ lớn hơn display.println ("SNAKE"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, WHITE); // border Snake display.drawRect (19, 20, 90, 32, WHITE); // hộp viền - 3 display.setCursor (28, 42); display.setTextSize (0); // phông chữ trở lại bình thường display.println ("nhấn phím bất kỳ"); display.display (); chờ đợi = digitalRead (INTPIN); // kiểm tra xem phím được nhấn chờ có chuyển thành 1 kết thúc không trong khi buttonpressed = 0; // nhấn nút đặt lại}} // -------------------- VẼ màu đầu vào dòng ngẫu nhiên uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // thiết lập tọa độ ngẫu nhiên cho một dòng rồi vẽ nó // biến không hơn không kém line1X = random (worldMinX + 1, worldMaxX-1); line1Y = ngẫu nhiên (worldMinY + 1, worldMaxY-1); line2X = random (worldMinX + 1, worldMaxX-1); line2Y = random (worldMinY + 1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- phát hiện va chạm -------- -----------------------

for (byte i = 4; i <solidSize; i ++) {if (solidX == solidPosX && solidY == solidPosy ) {return 1; giọng điệu (SND, 2000, 20); giai điệu (SND, 1000, 20); } trả về 0; }

//-------------------------------- CÀI ĐẶT--------------- -------------------------------

void setup () {delay (100); // chỉ cho mọi thứ một cơ hội để "khởi động" // Serial.begin (9600); // bỏ chọn mục này nếu bạn muốn xem các đầu ra nối tiếp display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // bắt đầu với một màn hình hiển thị sạch sẽ display.setTextColor (WHITE); // thiết lập kích thước xoay màu văn bản vv display.setRotation (0); display.setTextWrap (false); display.dim (0); // thiết lập độ sáng hiển thị pinMode (INTPIN, INPUT); // thiết lập các cổng chính xác cho đầu vào pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // đây là lệnh interupt, lệnh này "tạm dừng" arduino đọc các đầu vào // command- function- pin-function để thực thi-điều kiện trên chân đính kèmInterrupt (digitalPinToInterrupt (INTPIN), ngắt nén, RISING); // Serial.println ("Đã thiết lập xong"); waitForPress (); // hiển thị màn hình khởi động con rắn placeScran (); // đặt chút thức ăn đầu tiên} // --------------------- MAIN LOOP ----------------- ---------------------- void loop () {updateGame (); // hàm này là hàm mang mã chính}

Bước 3:

Đề xuất: