Trò chơi Arduino OLED Reckless Racer, AdafruitGFX và Bitmaps Kiến thức cơ bản: 6 bước
Trò chơi Arduino OLED Reckless Racer, AdafruitGFX và Bitmaps Kiến thức cơ bản: 6 bước
Anonim
Trò chơi Arduino OLED Reckless Racer, AdafruitGFX và Bitmaps Kiến thức cơ bản
Trò chơi Arduino OLED Reckless Racer, AdafruitGFX và Bitmaps Kiến thức cơ bản
Trò chơi Arduino OLED Reckless Racer, AdafruitGFX và Bitmaps
Trò chơi Arduino OLED Reckless Racer, AdafruitGFX và Bitmaps

Trong hướng dẫn này, chúng ta sẽ xem xét cách sử dụng bitmap bằng cách sử dụng thư viện Adafruit_GFX.c như một loại sprite trong một trò chơi. Trò chơi đơn giản nhất mà chúng tôi có thể nghĩ đến là trò chơi ô tô chuyển làn di chuyển bên, cuối cùng, người thử nghiệm beta và người lập trình trợ lý của chúng tôi đã quyết định đặt tên "Reckless Racer", vì nó khá liều lĩnh khi lái xe sai đường xuống đường cao tốc !!.

Thiết kế của mạch của chúng tôi có trong các hình ảnh bao gồm ở trên và được trình bày chi tiết trong dự án / hướng dẫn cuối cùng của chúng tôi tại đây Snake Guiductables mô tả cách hoạt động của mạch.

chúng tôi sẽ yêu cầu

Adafruit_GFX

Paint.net

Arduino IDE windowslinux

và các bạn hãy xem qua bài hướng dẫn về Snake cho các trang bị còn lại.

Quân nhu

Trò chơi rắn

Bước 1: Cài đặt Paint.net

Cài đặt Paint.net
Cài đặt Paint.net
Cài đặt Paint.net
Cài đặt Paint.net
Cài đặt Paint.net
Cài đặt Paint.net

Chúng tôi đang sử dụng paint.net vì phần mềm này hoàn toàn miễn phí để sử dụng hoàn toàn miễn phí, bạn có thể tải Paint. Net tại đây.

Để cài đặt paint.net, hãy nhấp đúp vào chương trình đã tải xuống và trả lời tích cực như vậy tiếp theo, vâng, ok, tôi đồng ý và những hình ảnh trên sẽ cung cấp cho bạn hướng đi.

Bước 2: Vẽ một màn hình giật gân đơn giản

Vẽ một màn hình giật gân đơn giản
Vẽ một màn hình giật gân đơn giản
Vẽ một màn hình giật gân đơn giản
Vẽ một màn hình giật gân đơn giản
Vẽ một màn hình giật gân đơn giản
Vẽ một màn hình giật gân đơn giản

Khi bạn đang ở trong paint.net, hãy tạo một hình ảnh mới bằng cách nhấp vào Tệp rồi mới, đặt kích thước hình ảnh thành 1260x620 (xem hình đầu tiên) nhấp vào ok khi bạn có trang mới vẽ màn hình giật gân chỉ sử dụng 2 màu đen và trắng bằng bút chì công cụ (pic2), khi bạn vẽ (hoặc dán) hình ảnh trên màn hình giật gân của mình, hãy nhấp vào hình ảnh rồi thay đổi kích thước (image4), trong cửa sổ bật lên thay đổi kích thước từ 1260x620 thành 126x62 (nhỏ hơn 2 pixel so với màn hình của bạn) (pic5) Nhấp vào OK.

tiếp theo bấm vào menu Tệp rồi lưu dưới dạng (pic6).

khi cửa sổ bật lên xuất hiện trong menu thả xuống loại tệp, chọn BMP (bitmap). (pic7), nhập tên tệp và nhấp vào lưu, khi cửa sổ bật lên xuất hiện, hãy đặt phối màu thành 0 và đặt thành 8 bit, nhấp vào ok (pic8).

Bước 3: Chuyển đổi tệp bitmap BMP sang C

Chuyển đổi tệp bitmap BMP sang C
Chuyển đổi tệp bitmap BMP sang C
Chuyển đổi tệp bitmap BMP sang C
Chuyển đổi tệp bitmap BMP sang C
Chuyển đổi tệp bitmap BMP sang C
Chuyển đổi tệp bitmap BMP sang C
Chuyển đổi tệp bitmap BMP sang C
Chuyển đổi tệp bitmap BMP sang C

Bây giờ chúng ta cần chuyển đổi hình ảnh của mình sang một định dạng mà arduino có thể hiểu là có rất nhiều công cụ có sẵn để thực hiện việc này nhưng nơi "đến" của tôi là công cụ chuyển đổi bitmap trang web marlin…

marlinfw.org/tools/u8glib/converter.html

Vì vậy, chúng tôi bắt đầu phần này bằng cách sử dụng liên kết trên để mở trang web được hiển thị trong pic1

nhấp vào chọn tệp và chọn ảnh bitmap bạn đã tạo trước đó (pic2)

Công cụ chuyển đổi bitmap marlin sẽ tự động chuyển đổi hình ảnh của bạn thành mã c nhấp đúp chuột trái vào mã sẽ đánh dấu mã, sau đó nhấp chuột phải và nhấp vào sao chép (pic3)

tiếp theo Chúng tôi tạo nhấp chuột phải và tạo một tài liệu văn bản mới (pic4)

nhấp đúp vào tài liệu mới, khi mở ra, hãy nhấp chuột phải và dán mã (pic5)

tiếp theo, chúng ta phải thêm dòng gần đầu đoạn mã #include, điều này cho phép chúng ta lưu dữ liệu bitmap vào bộ nhớ flash trên arduino, sau đó chúng ta đổi tên #define width, height và name thành thứ gì đó dễ sử dụng hơn, chúng được đánh dấu trong hình 6, chúng tôi đổi tên chúng từ các ký tự được tạo ngẫu nhiên, chúng tôi đổi tên chúng thành ví dụ được gạch chân bên dưới

#define LOGOWIDTH

#define LOGOHEIGHT

const unsigned char LOGOPIC PROGMEM

tiếp theo nhấp vào tệp sau đó lưu dưới dạng, lưu tệp dưới dạng logo.c đóng notepad, nhấp chuột phải vào logo.c và nhấp vào sao chép.

Bước 4: Hiển thị LOGO bằng DrawBitmap

Hiển thị LOGO bằng DrawBitmap
Hiển thị LOGO bằng DrawBitmap
Hiển thị LOGO bằng DrawBitmap
Hiển thị LOGO bằng DrawBitmap
Hiển thị LOGO bằng DrawBitmap
Hiển thị LOGO bằng DrawBitmap

Bây giờ chúng ta tải arduino IDE và tạo bản phác thảo mới và lưu nó có tên là logoexample.ino, tiếp theo là một cheat trong arduino Ide, hãy nhấp vào menu tệp sau đó lưu dưới dạng, quay lại thư mục dự án nhấp chuột phải và dán vào tệp.c (pic2) sau đó nhấp vào hủy bỏ, điều này giúp bạn không phải duyệt đến thư mục để dán vào tệp.

gõ mã sau vào arduino IDE hoặc tải xuống trong ino.

(chúng tôi khuyên bạn nên nhập thay vì sao chép và dán hoặc sử dụng các tệp bên dưới là cách tốt nhất để học)

#include / * điều này sẽ khác nhau tùy thuộc vào nơi bạn lưu trữ

ino thường nằm trong thư mục C: / Users / ~ tên người dùng / Documents / Arduino / project ~ tên

và đây là cách chúng tôi liên kết với bitmap của mình * /

#bao gồm

#bao gồm

uint8_t bmpX, bmpY = 0; / * dự trữ bộ nhớ cho 2 số nguyên X 8 bit, chúng tôi chỉ cần số nguyên 8 bit

vì giá trị không bao giờ cao hơn 128 (pixel) nên chúng tôi có thể tiết kiệm dung lượng bằng cách sử dụng các int 8 bit (có giá trị tối đa là 255) * /

void setup ()

{trễ (100); // cho hiển thị vv thời gian để bật nguồn display.begin (SSD1306_SWITCHCAPVCC, 0x3C); // đây là để khởi tạo hiển thị display.clearDisplay (); // bắt đầu với màn hình trống}

/ * xin lưu ý rằng bạn không cần phải nhập những nhận xét này vì chúng để tham khảo …………..

lệnh mà chúng ta sẽ tập trung vào là display.drawBitmap, đây là những gì vẽ màn hình giật gân của chúng ta. (bmpX, là giá trị trục X trên màn hình nơi điểm neo X của bitmap sẽ là và bmpX và bmpY là các giá trị chúng ta quan tâm để tạo chuyển động (bmpY, là giá trị trục Y trên màn hình nơi neo Y điểm của bitmap sẽ là chúng tôi nhận được các tên tham chiếu như chúng tôi đã xác định chúng trong logo.c (LOGOPIC, là tên của bitmap trong tệp #included logo.c (LOGOWIDTH, là bao nhiêu pixel chéo (X) để vẽ bitmap từ điểm neo (LOGOHEIGHT, là bao nhiêu pixel xuống (Y) để vẽ bitmap từ điểm neo mà các pixel X và Y xen kẽ có thể được nhập theo cách thủ công nhưng chỉ dễ sử dụng các pixel được xác định trước hơn là nhớ tất cả (1, giá trị cuối cùng là màu vì màn hình là đơn sắc 0 đen 1 trắng. Được rồi, bắt đầu nhập từ dòng tiếp theo: ¬D lol * / void loop () {display.clearDisplay (); // làm trống màn hình // bitmap được vẽ từ trên cùng bên trái, x, y, bitmap tên, chiều rộng X, chiều cao Y, color display.drawBitmap (bmpX, bmpY, LOGOPIC, LOGOWIDTH, LOGOHEIGHT, 1); display.display (); // điều này thực sự kéo bộ đệm vào màn hình bao giờ}

tải lên cho bạn mã bạn arduino và xác nhận rằng nó đang hoạt động (pic3).

Bước 5: Di chuyển một Sprite Bitmap

Image
Image
Di chuyển một Sprite Bitmap
Di chuyển một Sprite Bitmap
Di chuyển một Sprite Bitmap
Di chuyển một Sprite Bitmap

Sử dụng các hướng dẫn trước đó, hãy sử dụng paint.net và tạo một tệp mới có kích thước 30x15 pixel (pic1) và vẽ một chiếc xe thô sơ, nhà thiết kế trẻ của chúng tôi bắt đầu với kính chắn gió trước (ảnh 2 & 3).

lại lưu nó dưới dạng tệp windows bmp (như trong bước 2), chuyển đổi thành bitmap C (bước 3) và đặt tệp car.c (hoặc những gì bạn quyết định) trong cùng một thư mục với arduino ino mới được tạo (bản phác thảo) tập tin.

(p.s. hãy nhớ thêm dòng #include trong car.c, dòng này thường được sử dụng để bắt chúng tôi ra ngoài)

Đầu tiên liên kết tương đương của bạn với car.c

#bao gồm

#include #include Adafruit_GFX.h> // https://github.com/adafruit/Adafruit-GFX-Library #include Adafruit_SSD1306 //

Màn hình Adafruit_SSD1306 (128, 64); // đặt độ phân giải của màn hình

/ * bmpX / bmpY chúng ta cần chúng là các biến khi thay đổi các giá trị này và vẽ lại

màn hình là cách chúng ta tạo hiệu ứng chuyển động. hitSide và hitTop là cách chúng tôi giữ sprite trong màn hình * / uint8_t bmpX, bmpY = 0; // dự trữ bộ nhớ cho 2 int 8 bit (0-255) chúng ta không cần lớn hơn 128 sẽ là số lớn nhất được sử dụng bool hitSide = 0; bool hitTop = 0;

void setup ()

{trễ (100); // cho hiển thị thời gian để bật nguồn display.begin (SSD1306_SWITCHCAPVCC, 0x3C); // đây là để khởi tạo hiển thị display.clearDisplay (); // bắt đầu với màn hình trống

}

void loop ()

{display.clearDisplay (); // làm trống màn hình // bitmap được vẽ từ trên cùng bên trái, x, y, tên của bitmap, chiều rộng X, chiều cao Y, color display.drawBitmap (bmpX, bmpY, CARSPRITE, CARWIDTH, CARHEIGHT, 1); // display.display (); // điều này thực sự kéo bộ đệm vào màn hình / * đây là cách chúng tôi theo dõi cạnh của màn hình và quyết định xem có nên thêm pixel di chuyển từ trên xuống dưới hay không) hay xóa một pixel (di chuyển từ dưới lên trên) * / switch (hitSide) // điều này chọn hướng của xe dựa trên boole {case 0: bmpX ++; nghỉ;

trường hợp 1:

bmpX--; nghỉ; } // 2 câu lệnh if này đặt bool thành true hoặc false if (bmpX == 0) {hitSide = 0; } if (bmpX == 96) // chiều rộng của màn hình trừ đi ô tô {hitSide = 1; } // tương tự như trên đối với trục Y if (bmpY == 0) {hitTop = 0; } if (bmpY == 49) // chiều cao màn hình trừ chiều cao ô tô {hitTop = 1; } switch (hitTop) {case 0: bmpY ++; nghỉ; trường hợp 1: bmpY--; nghỉ; }

}

bạn có thể thấy chương trình hoạt động trong video đính kèm

Bước 6: Làm trò chơi lái xe

Image
Image

Đầu tiên Chúng ta bắt đầu bằng cách vẽ một vài chiếc ô tô hoặc chướng ngại vật khác nhau như trong các giai đoạn trước của hướng dẫn làm cho chúng có kích thước 30x15 pixel. Sau đó, chúng tôi chuyển đổi chúng thành bitmap c và liên kết trong mã.

#include // các đường dẫn này sẽ phải thay đổi phụ thuộc

// về nơi bạn lưu trữ các tệp // chỉnh sửa: tôi vừa phát hiện ra nếu bạn thay thế // bằng "" bạn không yêu cầu đường dẫn đầy đủ // với các thư viện của riêng bạn #include

#bao gồm

#include #include

#bao gồm

#include // https://github.com/adafruit/Adafruit-GFX-Library #include <Adafruit_SSD1306 //

Màn hình Adafruit_SSD1306 (128, 64); // xác định các tham số hiển thị

xác định các biến và giá trị cố định

// 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 # xác định # định nghĩa 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

#define DIRUP 1 // các giá trị này là giá trị mà "con rắn" xem xét để quyết định-

#define DIRDOWN 2 // hướng con rắn sẽ di chuyển #define DIRLEFT 3 #define DIRRIGHT 4

uint8_t dirPressed = 0; // giá trị để đăng ký hướng di chuyển trên chân nào đã tăng cao

// cửa hàng booleans mà pin đã tăng cao

bool BUTUP = 0; bool BUTDWN = 0; bool BUTLFT = 0; bool BUTRHT = 0; // vars cho vị trí của ô tô uint8_t carPosX = 1; uint8_t carPosY = {0, 16, 32, 48}; // cần lưu trữ giá trị trong mảng

uint8_t lanePosArr = {0, 16, 32, 48}; // mảng để lưu trữ vị trí của mỗi làn đường

uint8_t carPosYCnt = 0; uint8_t carYTmp = 0; // biến cho các đường trong đường uint8_t roadLineX1 = 51; // những cái này được xác định trước lúc đầu thì các dòng xuất hiện liền mạch uint8_t roadLineX2 = 102; uint8_t roadLineX3 = 153; uint8_t roadLineX4 = 254; uint8_t roadLineX5 = 200;

// đây là số lượng pixel mà vùng vui chơi di chuyển tại một thời điểm

uint8_t drawSpeed = 4;

// vars cho kẻ thù0

uint8_t Địch0PosX = 255; uint8_t Địch0PosY = 0; uint8_t Địch1PosX = 255; uint8_t Địch1PosY = 0; uint8_t Địch2PosX = 255; uint8_t Địch2PosY = 0;

// có thể thay đổi để chỉ định ngẫu nhiên một số làn đường cho các chướng ngại vật

uint8_t laneGen = 0;

uint8_t laneGen0 = 0; uint8_t laneGen1 = 0; uint8_t laneGen2 = 0;

// bộ đếm điểm

điểm dài = 0; // đây là điểm: / lol long so sánh = 0; // mục này lưu trữ điểm ở cấp cuối cùng để so sánh trở lại với long highScore = 25; uint8_t metreCnt = 0;

đây là nơi chúng tôi bắt đầu các chức năng

// đây là tập hợp các lệnh nếu ngắt được kích hoạt voidruptressed () {delay (150); updateDirection (); } // cập nhật giá trị nào theo hướng var bằng cách kiểm tra các bools DIR // -------------------------- CẬP NHẬT HƯỚNG (trình phát) - ------------------------- void updateDirection () {//Serial.println("updateDirection Called "); BUTUP = digitalRead (UPPIN); BUTDWN = digitalRead (DWNPIN); BUTLFT = digitalRead (LFTPIN); BUTRHT = digitalRead (RHTPIN); if (BUTUP == true) {dirPressed = DIRUP; } if (BUTDWN == true) {dirPressed = DIRDOWN; } if (BUTLFT == true) {dirPressed = DIRLEFT; } if (BUTRHT == true) {dirPressed = DIRRIGHT; }

}

// ------------------------------- CHUYỂN XE --------------- -------------------------

// cái này sẽ cập nhật màn hình mover the car sprite

void moveCar ()

{switch (dirPressed) {case DIRUP: carPosYCnt--; carPosY [carPosYCnt]; giai điệu (SND, 100, 100); if (carPosYCnt == 255) {carPosYCnt = 0; } carYTmp = carPosY [carPosYCnt]; dirPressed = 0; // Serial.println ("carPosY up"); // Serial.println (carPosYCnt); nghỉ; case DIRDOWN: carPosYCnt ++; giai điệu (SND, 100, 100); if (carPosYCnt == 4) {carPosYCnt = 3; } // Serial.println ("carPosY"); // Serial.println (carPosYCnt); carYTmp = carPosY [carPosYCnt]; dirPressed = 0; nghỉ; // nhận xét ra xe có khả năng di chuyển trái phải phát hiện va chạm chưa tốt / * case DIRLEFT: carPosX--; if (carPosX == 0) {carPosX = 1; } // Serial.println ("carPosX"); // Serial.println (carPosX); dirPressed = 0; nghỉ; * / case DIRRIGHT: // chỉ để giải trí nếu bạn nhấn phải trò chơi sẽ phát ra âm thanh ồn ào (SND, 100, 50); // carPosX ++; // if (carPosX == 128) // {// carPosX = 127; //} // Serial.println ("carPosX"); // Serial.println (carPosX); // dirPressed = 0; nghỉ; } updateDisplay (); }

// -------------------------- NGẪU NHIÊN POS X ------------------- -----------

uint8_t randomPosX () // 2 quy trình này chỉ tạo vị trí ngẫu nhiên cho các chướng ngại vật

{uint8_t posValTmp = 0; posValTmp = ngẫu nhiên (129, 230); //Serial.println("random x "); //Serial.println(posValTmp); return (posValTmp); }

// --------------------------- NGẪU NHIÊN POS Y ------------------ ------------------

uint8_t randomPosY ()

{uint8_t laneVal = 0; laneVal = random (0, 4); // thêm một làn đường bổ sung cho sự ngẫu nhiên, tức là không có đối tượng nào trên màn hình khi ở trong làn đường đó //Serial.println("RandomY "); //Serial.println(lanePosArr[laneVal]); return (lanePosArr [laneVal]); }// ------------------------------- ĐẶT TỐC ĐỘ TRÒ CHƠI -------------- -------------- void setGameSpeed () // điều này dừng cấp độ cao hơn 20 khiến trò chơi không thể chơi được {if (drawSpeed <21) {drawSpeed = drawSpeed + 2; }}// ------------------------------------ PHÁT HIỆN CRASH ---------- ----------------------- void exploreCrash () {

nếu (địch0PosX = 0 && địch0PosY == carYTmp)

{// Serial.println ("Game Over CRAASSSSHHHHHHHEEEEDDD sang Traffic 0"); gameOver (); } if (Địch1PosX = 0 && Địch1PosY == carYTmp) {//Serial.println("Game Over CRAASSSSHHHHHHHEEEEDDD vào lưu lượng truy cập 1 "); gameOver (); } if (Địch2PosX = 0 && Địch2PosY == carYTmp) {//Serial.println("Game Over CRAASSSSHHHHHHHEEEEDDD thành lưu lượng 2 "); gameOver (); }}

đây là những thói quen vẽ màn hình.

// ------------------------------- VẼ ĐƯỜNG --------------- --------------------- void drawRoad () // X, Y, length, width {display.fillRect (roadLineX1, 15, 30, 4, WHITE); display.fillRect (roadLineX1, 30, 30, 4, WHITE); display.fillRect (roadLineX1, 45, 30, 4, WHITE); display.fillRect (roadLineX2, 15, 30, 4, WHITE); display.fillRect (roadLineX2, 30, 30, 4, WHITE); display.fillRect (roadLineX2, 45, 30, 4, WHITE); display.fillRect (roadLineX3, 15, 30, 4, WHITE); display.fillRect (roadLineX3, 30, 30, 4, WHITE); display.fillRect (roadLineX3, 45, 30, 4, WHITE); display.fillRect (roadLineX4, 15, 30, 4, WHITE); display.fillRect (roadLineX4, 30, 30, 4, WHITE); display.fillRect (roadLineX4, 45, 30, 4, WHITE); display.fillRect (roadLineX5, 15, 30, 4, WHITE); display.fillRect (roadLineX5, 30, 30, 4, WHITE); display.fillRect (roadLineX5, 45, 30, 4, WHITE);

roadLineX1 = roadLineX1-drawSpeed;

roadLineX2 = roadLineX2-drawSpeed; roadLineX3 = roadLineX3-drawSpeed; roadLineX4 = roadLineX4-drawSpeed; roadLineX5 = roadLineX5-drawSpeed; display.display (); } // ----------------------------------------- VẼ thụt ---- --------------------------------------- void xổmysDraw () {// X, Y, bmp name, width, height, color display.drawBitmap (Địch0PosX, Địch công0PosY, ENEMY0, ENEMY0_WIDTH, ENEMY0_HEIGHT, 1); địch0PosX = địch0PosX-drawSpeed; display.drawBitmap (địch1PosX, địch1PosY, ENEMY1, ENEMY1_WIDTH, ENEMY1_HEIGHT, 1); địch1PosX = địch1PosX-drawSpeed; display.drawBitmap (Địch2PosX, Địch2PosY, ENEMY2, ENEMY2_WIDTH, ENEMY2_HEIGHT, 1); địch2PosX = Địch2PosX-drawSpeed; display.display (); if (địch0PosX> 231 && địch0PosX231 && địch1PosX <255) {địch1PosX = ngẫu nhiênPosX (); địch1PosY = randomPosY (); checkDuplicate (); }

if (Địch2PosX> 231 && Địch2PosX <255) {Địch2PosX = randomPosX (); địch2PosY = randomPosY (); }} // ------------------------------------ CẬP NHẬT MÀN HÌNH -------- ---------------------------------------- void updateDisplay () {display.clearDisplay (); display.drawBitmap (carPosX, carPosY [carPosYCnt], CARSPRITE, 30, 15, 1); display.fillRect (100, 0, 28, 10, BLACK); display.setCursor (100, 0); display.setTextColor (TRẮNG, ĐEN); display.println (điểm số); display.display ();

}

// ------------------------- đợi vòng lặp báo chí ------------------- ------

// đây là mã màn hình chính void waitForPress () {splashScreen (); bool chờ đợi = 0; // vòng lặp kết thúc khi đây là true display.clearDisplay (); trong khi (chờ đợi == 0) {

display.fillRect (19, 20, 90, 32, BLACK); // nền trống cho văn bản

display.setTextColor (TRẮNG); display.setCursor (23, 24); display.setTextSize (0); display.println ("Liều lĩnh"); display.setCursor (36, 34); display.println ("Tay đua"); display.drawBitmap (74, 24, CARSPRITE, CARWIDTH, CARHEIGHT, 1); // x y w h r col display.drawRoundRect (21, 21, 86, 23, 4, WHITE); // border Snake display.drawRect (19, 20, 90, 33, WHITE); // hộp viền - 3 display.setCursor (25, 43); display.setTextSize (0); // phông chữ trở lại bình thường display.println ("nhấn phím bất kỳ"); display.fillRect (0, 0, 127, 8, BLACK); display.setCursor (10, 0); display.print ("Điểm cao:"); // hiển thị điểm cao display.print (highScore); 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 dirPressed = 0; // nhấn nút reset không có hướng}} // -------------------------------------- ----- CẬP NHẬT TRÒ CHƠI ----------------------------------------- void updateGame () {moveCar (); drawRoad (); thụt vào trong (); // Địch1Draw (); // Địch2Draw (); metreCnt ++; phát hiệnCrash (); if (metreCnt == 5) // thêm một điểm cho mỗi 10 chu kỳ để tăng điểm {metreCnt = 0; điểm ++; } if (score == so sánh + 5) // tăng tốc trò chơi sau mỗi 5 điểm lên tối đa 20 speed {so sánh = điểm; setGameSpeed (); } noTone (SND); updateDisplay ();

}

// ------------------------------ HẾT TRÒ CHƠI ---------------- ------------------------------

// quy trình này vẽ các đường xung quanh chiếc xe anh hùng đã chết sau đó hiển thị trò chơi trên màn hình

void gameOver ()

{tone (SND, 200, 200); // phát âm thanh uint8_t linePosX, linePosY, pixwidth, pixheight = 0; // thiết lập các vars để vẽ các hộp xung quanh car linePosX = carPosY; linePosY = carYTmp; pixwidth = 30; pixheight = 15; display.drawRect (linePosX, linePosY, pixwidth, pixheight, WHITE); display.display (); for (int i = 0; i <= 26; i ++) // điều này bao quanh ô tô trong các hình chữ nhật mô phỏng vụ nổ {linePosX = linePosX-2; linePosY = linePosY-2; pixwidth = pixwidth + 4; pixheight = pixheight + 4; display.drawRect (linePosX, linePosY, pixwidth, pixheight, BLACK); display.drawRect (linePosX, linePosY, pixwidth, pixheight, WHITE); display.display (); giai điệu (SND, i * 20, 50); chậm trễ (10); } display.setTextSize (2); display.setTextColor (TRẮNG, ĐEN); display.setCursor (10, 23); giai điệu (SND, 50, 500); display.print ("TRÒ CHƠI"); display.display (); chậm trễ (500); giai điệu (SND, 40, 500); display.print ("HẾT"); display.setTextSize (0); display.display (); chậm trễ (3000); restartGame (); waitForPress (); }

// ----------------------------------------- KHỞI ĐỘNG TRÒ CHƠI ---------- -------------------------------------------------- -----

void restartGame () // cái này sao chép điểm cao và đặt lại tất cả số liệu thống kê và tạo vị trí ngẫu nhiên

{if (score> = highScore) // kiểm tra xem điểm có cao hơn điểm cao không {highScore = score; // trạng thái đơn if để cập nhật điểm cao}

điểm = 0;

drawSpeed = 4; metreCnt = 0; carPosYCnt = 0; địch0PosX = randomPosX (); địch0PosY = randomPosY (); địch1PosX = randomPosX (); địch1PosY = randomPosY (); địch2PosX = randomPosX (); địch2PosY = randomPosY (); noTone (SND);

checkDuplicate ();

}

// ------------------------------------------------ - KIỂM TRA DUPLICATE ----------------------------------------------- ------ void checkDuplicate () // những kiểm tra này để xem các chướng ngại vật có chiếm cùng một không gian trò chơi hay không {// Serial.println ("đã kiểm tra trùng lặp"); if (Địch2PosX> 230 && Địch2PosX <255) {while (Địch2PosY == Địch1PosY || địch2PosY == Địch0PosY) {Địch2PosY = randomPosY (); }}

nếu (kẻ thù0PosX> 230 && kẻ thù0PosX230 && kẻ thù2PosXenemy1PosX && kẻ thù2PosX230 && kẻ thù0PosXenemy1PosX && kẻ thù0PosX

// ------------------------------------------- MÀN HÌNH SPLASH --- --------------------------------

void splashScreen ()

{display.clearDisplay (); display.drawBitmap (0, 0, CRASH, CRASHWIDTH, CRASHHEIGHT, 1); display.display (); chậm trễ (2000); } // ----------------------------------------------- CÀI ĐẶT ------------------------------------------------- ----------- void setup () {delay (100); // để mọi thứ khởi động // Serial.begin (9600); // bỏ ghi chú này và tất cả Serial. lệnh cho hiển thị sơ đồ lỗi display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); display.setTextColor (TRẮNG, ĐEN); display.setTextWrap (false); display.dim (0); pinMode (INTPIN, INPUT); pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT);

mountInterrupt (digitalPinToInterrupt (INTPIN), ngắt, RISING);

// đặt ngẫu nhiên vật cản địch0PosX = randomPosX (); địch0PosY = randomPosY (); địch1PosX = randomPosX (); địch1PosY = randomPosY (); địch2PosX = randomPosX (); địch2PosY = randomPosY (); checkDuplicate (); // kiểm tra các vị trí trùng lặp // Serial.println ("setup Complete"); splashScreen (); waitForPress (); } // ----------------------------------------------- ----- VÒNG -------------------------------------------- ----------

void loop ()

{updateGame (); }

và đó là khá nhiều, bất kỳ sửa đổi và phản hồi sẽ được hoan nghênh. Các vấn đề chúng ta cần giải quyết hiện tượng nhấp nháy màn hình, chúng ta cần xem xét làm thế nào để giảm bớt nó và xe đối phương vẫn có thể chiếm cùng một không gian.

Đề xuất: