เกม Reckless Racer Arduino OLED, AdafruitGFX และ Bitmaps พื้นฐาน: 6 ขั้นตอน
เกม Reckless Racer Arduino OLED, AdafruitGFX และ Bitmaps พื้นฐาน: 6 ขั้นตอน
Anonim
เกม Reckless Racer Arduino OLED, AdafruitGFX และ Bitmaps พื้นฐาน
เกม Reckless Racer Arduino OLED, AdafruitGFX และ Bitmaps พื้นฐาน
เกม Reckless Racer Arduino OLED, AdafruitGFX และ Bitmaps พื้นฐาน
เกม Reckless Racer Arduino OLED, AdafruitGFX และ Bitmaps พื้นฐาน

ในบทช่วยสอนนี้ เราจะมาดูวิธีใช้บิตแมปโดยใช้ไลบรารี Adafruit_GFX.c ในรูปแบบสไปรต์ในเกม เกมที่ง่ายที่สุดที่เราคิดได้คือเกมรถเลื่อนเลนด้านข้าง ในที่สุดผู้ทดสอบเบต้าและผู้ช่วย coder ของเราก็ตัดสินใจตั้งชื่อว่า "Reckless Racer" เนื่องจากมันค่อนข้างประมาทที่จะขับในทางที่ผิดบนทางด่วน!!

การออกแบบวงจรของเราอยู่ในรูปภาพด้านบนและมีรายละเอียดในโครงการ/บทแนะนำล่าสุดของเราที่นี่ Snake Instructables ซึ่งอธิบายวิธีการทำงานของวงจร

เราจะต้องการ

Adafruit_GFX

Paint.net

Arduino IDE windowslinux

และโปรดดูบทช่วยสอนงูสำหรับอุปกรณ์ที่เหลือ

เสบียง

เกมงู

ขั้นตอนที่ 1: ติดตั้ง Paint.net

การติดตั้ง Paint.net
การติดตั้ง Paint.net
การติดตั้ง Paint.net
การติดตั้ง Paint.net
การติดตั้ง Paint.net
การติดตั้ง Paint.net

เรากำลังใช้ paint.net เนื่องจากซอฟต์แวร์นี้ใช้งานได้ฟรี ดังนั้นคุณจึงดาวน์โหลด Paint. Net ได้ที่นี่

ในการติดตั้ง paint.net ให้ดับเบิ้ลคลิกที่โปรแกรมที่ดาวน์โหลดมาและตอบในเชิงบวกต่อไป ใช่ ตกลง ฉันเห็นด้วย และรูปภาพด้านบนจะให้คำแนะนำแก่คุณ

ขั้นตอนที่ 2: การวาดหน้าจอเริ่มต้นอย่างง่าย

การวาดหน้าจอเริ่มต้นอย่างง่าย
การวาดหน้าจอเริ่มต้นอย่างง่าย
การวาดหน้าจอเริ่มต้นอย่างง่าย
การวาดหน้าจอเริ่มต้นอย่างง่าย
การวาดหน้าจอเริ่มต้นอย่างง่าย
การวาดหน้าจอเริ่มต้นอย่างง่าย

เมื่อคุณอยู่ใน paint.net ให้สร้างภาพใหม่โดยคลิก File จากนั้น New กำหนดขนาดภาพเป็น 1260x620 (ดูรูปแรก) คลิก ok เมื่อคุณมีหน้าใหม่ วาด splash screen โดยใช้เพียง 2 สี ขาวดำ โดยใช้ดินสอ เครื่องมือ (รูปที่ 2), เมื่อคุณวาด (หรือวางใน) ภาพหน้าจอเริ่มต้น ให้คลิกที่ภาพแล้วปรับขนาด (image4) ในป๊อปอัปให้เปลี่ยนขนาดจาก 1260x620 เป็น 126x62 (เล็กกว่าจอแสดงผลของคุณ 2 พิกเซล) (รูปที่ 5) คลิกตกลง

คลิกถัดไป เมนูไฟล์ จากนั้นบันทึกเป็น (รูปที่ 6)

เมื่อป๊อปอัปปรากฏขึ้นในเมนูแบบเลื่อนลงประเภทไฟล์ให้เลือก BMP (บิตแมป) (pic7) พิมพ์ชื่อไฟล์แล้วคลิกบันทึก เมื่อป๊อปอัปปรากฏขึ้นตั้งค่า dithering เป็น 0 และตั้งค่าเป็น 8 บิต คลิกตกลง (รูปที่ 8)).

ขั้นตอนที่ 3: การแปลง BMP เป็นไฟล์บิตแมป C

การแปลง BMP เป็นไฟล์บิตแมป C
การแปลง BMP เป็นไฟล์บิตแมป C
การแปลง BMP เป็นไฟล์บิตแมป C
การแปลง BMP เป็นไฟล์บิตแมป C
การแปลง BMP เป็นไฟล์บิตแมป C
การแปลง BMP เป็นไฟล์บิตแมป C
การแปลง BMP เป็นไฟล์บิตแมป C
การแปลง BMP เป็นไฟล์บิตแมป C

ตอนนี้เราต้องแปลงภาพของเราให้อยู่ในรูปแบบที่ Arduino สามารถเข้าใจได้ว่ามีเครื่องมือมากมายให้ทำ แต่ "ไปที่" ของฉันคือเครื่องมือแปลงบิตแมปเว็บไซต์ marlin webs …

marlinfw.org/tools/u8glib/converter.html

ดังนั้นเราจึงเริ่มส่วนนี้โดยใช้ลิงก์ด้านบนเพื่อเปิดเว็บไซต์ที่แสดงในรูปที่ 1

คลิกที่เลือกไฟล์และเลือกบิตแมปที่คุณสร้างไว้ก่อนหน้านี้ (รูปที่ 2)

ตัวแปลงบิตแมป marlin จะแปลงรูปภาพของคุณเป็นโค้ด c โดยอัตโนมัติ ดับเบิลคลิกที่โค้ดซึ่งควรไฮไลต์โค้ด จากนั้นคลิกขวาแล้วคลิกคัดลอก (รูปที่ 3)

ต่อไป เราสร้างคลิกขวาและสร้างเอกสารข้อความใหม่ (รูปที่ 4)

ดับเบิ้ลคลิกที่เอกสารใหม่ เมื่อเปิดขึ้นมา ให้คลิกขวาและวางโค้ด (pic5)

ต่อไปเราต้องเพิ่มบรรทัดใกล้กับด้านบนของโค้ด #include ซึ่งช่วยให้เราสามารถบันทึกข้อมูลบิตแมปลงในหน่วยความจำแฟลชบน Arduino จากนั้นเราเปลี่ยนชื่อ #define ความกว้างความสูงและชื่อเป็นสิ่งที่ง่ายต่อการใช้งานเหล่านี้จะถูกเน้น ในรูปที่ 6

เราเปลี่ยนชื่อจากอักขระที่สร้างแบบสุ่ม เราเปลี่ยนชื่อให้เป็นตัวอย่างที่ขีดเส้นใต้ด้านล่าง

#define LOGOWIDTH

#กำหนด LOGOHEIGHT

const unsigned char LOGOPIC PROGMEM

คลิกไฟล์ถัดไป จากนั้นบันทึกเป็น บันทึกไฟล์เป็น logo.c ปิด notepad คลิกขวาที่ logo.c แล้วคลิกคัดลอก

ขั้นตอนที่ 4: การแสดงโลโก้โดยใช้ DrawBitmap

การแสดงโลโก้โดยใช้ DrawBitmap
การแสดงโลโก้โดยใช้ DrawBitmap
การแสดงโลโก้โดยใช้ DrawBitmap
การแสดงโลโก้โดยใช้ DrawBitmap
การแสดงโลโก้โดยใช้ DrawBitmap
การแสดงโลโก้โดยใช้ DrawBitmap

ตอนนี้เราโหลด Arduino IDE และสร้างภาพร่างใหม่และบันทึกชื่อเป็น logoexample.ino ถัดไปเป็นการโกงใน Arduino IDE คลิกที่เมนูไฟล์จากนั้นบันทึกเป็นกลับไปที่โฟลเดอร์โครงการคลิกขวาแล้ววางในไฟล์.c (รูปที่ 2) จากนั้นคลิกยกเลิก ซึ่งจะช่วยให้คุณไม่ต้องเรียกดูโฟลเดอร์เพื่อวางในไฟล์

พิมพ์รหัสต่อไปนี้ลงใน arduino IDE หรือดาวน์โหลดใน ino

(เราแนะนำให้พิมพ์แทนที่จะคัดลอกและวาง หรือใช้ไฟล์ด้านล่างเป็นวิธีการเรียนรู้ที่ดีที่สุด)

#include /* ซึ่งจะแตกต่างกันไปตามที่คุณจัดเก็บ

โดยปกติ ino จะอยู่ในโฟลเดอร์ C:\Users\~username\Documents\Arduino\project~name

และนี่คือวิธีที่เราเชื่อมโยงไปยังบิตแมปของเรา */

#รวม

#รวม

uint8_t bmpX, bmpY=0; /* หน่วยความจำสำรองสำหรับจำนวนเต็ม 2 X 8 บิตเราต้องการเพียง 8 บิตเท่านั้น

เนื่องจากค่าไม่เคยสูงกว่า 128 (พิกเซล) ดังนั้นเราจึงสามารถประหยัดพื้นที่โดยใช้ 8 บิต ints (ซึ่งมีค่าสูงสุด 255) */

การตั้งค่าเป็นโมฆะ ()

{ ล่าช้า (100); // ให้เวลาในการแสดงผล ฯลฯ เพื่อเปิด display.begin (SSD1306_SWITCHCAPVCC, 0x3C); // นี่คือการเริ่มต้น display.clearDisplay(); // เริ่มต้นด้วยหน้าจอว่าง }

/* โปรดทราบว่าคุณไม่จำเป็นต้องพิมพ์ความคิดเห็นเหล่านี้เพื่อใช้อ้างอิง…………..

คำสั่งที่เราจะเน้นคือ display.drawBitmap นี่คือสิ่งที่ดึงหน้าจอเริ่มต้นของเรา (bmpX คือค่าแกน X บนหน้าจอโดยที่จุดยึด X ของบิตแมปจะเป็น และ bmpX และ bmpY คือค่าที่เราสนใจในการสร้างการเคลื่อนไหว (bmpY คือค่าแกน Y บนหน้าจอโดยที่จุดยึด Y จุดที่บิตแมปจะเป็น เราได้รับชื่ออ้างอิงตามที่เรากำหนดไว้ใน logo.c (LOGOPIC คือชื่อของบิตแมปใน #included file logo.c (LOGOWIDTH คือจำนวนพิกเซลที่ตัดกัน (X)) บิตแมปจากจุดยึด (LOGOHEIGHT คือจำนวนพิกเซลที่ลดลง (Y) เพื่อวาดบิตแมปจากจุดยึดที่พิกเซล X และ Y รวมกันสามารถป้อนได้ด้วยตนเอง แต่ง่ายกว่าที่จะใช้ที่กำหนดไว้ล่วงหน้ามากกว่าที่จะจำทั้งหมด (1, ค่าสุดท้ายคือสีเนื่องจากหน้าจอเป็นขาวดำ 0 สีดำ 1 สีขาว โอเค เริ่มพิมพ์จากบรรทัดถัดไป:¬D lol*/ void loop() { display.clearDisplay(); // ทำให้หน้าจอว่าง // บิตแมปดึงมาจาก ซ้ายบน, x, y, ชื่อของบิตแมป, ความกว้าง X, ความสูง Y, สี display.drawBitmap(bmpX, bmpY, LOGOPIC, LOGOWIDTH, LOGOHEIGHT, 1); display.display(); // นี่เป็นการดึงบัฟเฟอร์ไปที่จอแสดงผลเลยทีเดียว }

อัปโหลดรหัสของคุณ Arduino และยืนยันว่าใช้งานได้ (รูปที่ 3)

ขั้นตอนที่ 5: การย้าย Bitmap Sprite

Image
Image
การย้าย Bitmap Sprite
การย้าย Bitmap Sprite
การย้าย Bitmap Sprite
การย้าย Bitmap Sprite

ตามคำแนะนำก่อนหน้านี้ใช้ paint.net และสร้างไฟล์ใหม่ให้มีขนาด 30x15 พิกเซล (รูปที่ 1) และวาดรถหยาบที่นักออกแบบรุ่นใหม่ของเราเริ่มต้นด้วยกระจกบังลมก่อน (รูปที่ 2 และ 3)

บันทึกอีกครั้งเป็นไฟล์ windows bmp (เช่นในขั้นตอนที่ 2) แปลงเป็นบิตแมป C (ขั้นตอนที่ 3) และวางไฟล์ car.c (หรือสิ่งที่คุณตัดสินใจ) ในโฟลเดอร์เดียวกันกับ arduino ino ที่สร้างขึ้นใหม่ (ร่าง) ไฟล์.

(ปล.อย่าลืมเติม #include line ใน car.c นี่เคยโดนเราบ่อยนะ)

ก่อนอื่นให้เชื่อมโยง car.c. ที่เทียบเท่าของคุณ

#รวม

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

Adafruit_SSD1306 จอแสดงผล (128, 64); // ตั้งค่าความละเอียดของการแสดงผล

/* bmpX/bmpY เราต้องการสิ่งเหล่านี้เพื่อเป็นตัวแปรในการเปลี่ยนค่าเหล่านี้และวาดใหม่

หน้าจอเป็นวิธีที่เราสร้างเอฟเฟกต์แอนิเมชั่นการเคลื่อนไหว hitSide และ hitTop คือวิธีที่เราเก็บสไปรท์ในหน้าจอ */ uint8_t bmpX, bmpY=0; // หน่วยความจำสำรองสำหรับ 2 8 บิต ints (0-255) เราไม่ต้องการขนาดใหญ่กว่า 128 จะเป็นจำนวนที่ใหญ่ที่สุดที่ใช้ bool hitSide=0; บูล hitTop=0;

การตั้งค่าเป็นโมฆะ ()

{ ล่าช้า (100); // ให้เวลาในการแสดงผล ฯลฯ เพื่อเปิด display.begin (SSD1306_SWITCHCAPVCC, 0x3C); // นี่คือการเริ่มต้น display.clearDisplay(); // เริ่มต้นด้วยหน้าจอว่างเปล่า

}

วงเป็นโมฆะ ()

{ display.clearDisplay(); // ทำให้หน้าจอว่างเปล่า // บิตแมปที่ดึงมาจากด้านบนซ้าย, x, y, ชื่อของบิตแมป, ความกว้าง X, ความสูง Y, สี display.drawBitmap(bmpX, bmpY, CARSPRITE, CARWIDTH, CARHEIGHT, 1); // display.display(); // นี่ดึงบัฟเฟอร์ไปที่จอแสดงผลจริง ๆ /* นี่คือวิธีที่เราติดตามขอบของหน้าจอและตัดสินใจว่าจะเพิ่มพิกเซลเลื่อนจากบนลงล่าง) หรือลบพิกเซล (เลื่อนจากล่างขึ้นบน) */ สวิตช์ (hitSide) // นี่เลือกทิศทางของรถตามบูล { กรณี 0: bmpX++; หยุดพัก;

กรณีที่ 1:

bmpX--; หยุดพัก; } // 2 if คำสั่ง if ตั้งค่าบูลเป็นจริงหรือเท็จ if(bmpX==0) { hitSide=0; } if(bmpX==96) // ความกว้างของหน้าจอลบด้วยรถ { hitSide=1; } // เหมือนข้างบนสำหรับแกน Y if(bmpY==0) { hitTop=0; } if(bmpY==49) // ความสูงของหน้าจอลบด้วยความสูงของรถ { hitTop=1; } สวิตช์ (hitTop) { กรณี 0: bmpY++; หยุดพัก; กรณีที่ 1: bmpY--; หยุดพัก; }

}

คุณสามารถดูโปรแกรมทำงานในวิดีโอที่แนบมา

ขั้นตอนที่ 6: สร้างเกมขับรถ

Image
Image

ขั้นแรก เราเริ่มต้นด้วยการวาดรถหรือสิ่งกีดขวางต่าง ๆ เช่นในขั้นตอนก่อนหน้าของบทช่วยสอนที่ทำให้เป็นพิกเซลขนาด 30x15 จากนั้นเราแปลงเป็นบิตแมป c และเชื่อมโยงในโค้ด

#include // เส้นทางเหล่านี้จะต้องเปลี่ยนตาม

// ที่คุณเก็บไฟล์ // แก้ไข: ฉันเพิ่งพบว่าคุณแทนที่ // ด้วย " " คุณไม่ต้องการเส้นทางแบบเต็ม // ด้วยไลบรารีของคุณเอง #include

#รวม

#รวม #รวม

#รวม

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

Adafruit_SSD1306 จอแสดงผล (128, 64); // กำหนดพารามิเตอร์การแสดงผล

กำหนดตัวแปรและค่าคงที่

// กำหนดพินอินพุต นี่คือพินบน Arduino ที่พวกเขาไม่เคยเปลี่ยน ดังนั้น #define#define INTPIN 3 // เฉพาะพิน 2 และ 3 เท่านั้นที่สามารถเป็นพินอินเทอร์อัปบน UNO #define UPPIN 4 // สิ่งเหล่านี้คือพินที่เชื่อมต่อ tp สวิตช์ที่เกี่ยวข้อง #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // กำหนดทิศทาง

#define DIRUP 1 // ค่าเหล่านี้คือสิ่งที่ "งู" มองเพื่อตัดสินใจ-

#define DIRDOWN 2 // ทิศทางที่งูจะเดินทาง #define DIRLEFT 3 #define DIRRIGHT 4

uint8_t dirPressed =0; // ค่าลงทะเบียนทิศทางที่จะย้ายไปที่พินสูง

// บูลีนเก็บพินที่พินสูง

บูล BUTUP =0; บูล BUDWN=0; บูล BUTLFT=0; บูล BUTRHT=0; // vars สำหรับตำแหน่งของรถ uint8_t carPosX=1; uint8_t carPosY ={0, 16, 32, 48}; // ต้องการค่า cahning อาร์เรย์

uint8_t เลนPosArr={0, 16, 32, 48}; // อาร์เรย์เพื่อจัดเก็บว่าแต่ละเลนอยู่ที่ใด

uint8_t carPosYCnt =0; uint8_t carYTmp=0; // ตัวแปรสำหรับเส้นในถนน uint8_t roadLineX1=51; // สิ่งเหล่านี้ถูกกำหนดไว้ล่วงหน้าที่จุดเริ่มต้น จากนั้นเส้นจะปรากฏอย่างไร้รอยต่อ uint8_t roadLineX2=102; uint8_t roadLineX3=153; uint8_t roadLineX4=254; uint8_t roadLineX5=200;

// นี่คือจำนวนพิกเซลที่พื้นที่เล่นเคลื่อนที่ในแต่ละครั้ง

uint8_t drawSpeed = 4;

// vars สำหรับศัตรู0

uint8_tศัตรู0PosX=255; uint8_tศัตรู0PosY=0; uint8_tศัตรู1PosX=255; uint8_t ศัตรู1PosY=0; uint8_tศัตรู2PosX=255; uint8_tศัตรู2PosY=0;

// ตัวแปรสุ่มกำหนดหมายเลขเลนให้กับสิ่งกีดขวาง

uint8_t เลนGen=0;

uint8_t เลนGen0=0; uint8_t เลนGen1=0; uint8_t เลนGen2=0;

// ตัวนับคะแนน

คะแนนยาว=0; // นี่คือคะแนน:/ lol long comparison=0; // เก็บคะแนนไว้ที่ระดับสุดท้ายขึ้นไปเพื่อเปรียบเทียบกลับไปเป็น long highScore=25; uint8_t metreCnt=0;

นี่คือจุดเริ่มต้นของฟังก์ชั่น

// นี่คือชุดของคำสั่งหากอินเตอร์รัปต์ถูกเปิดใช้งาน void interruptressed() { ดีเลย์ (150); updateDirection(); } // อัปเดตค่าที่อยู่ในทิศทาง var โดยตรวจสอบบูล DIR //-------------------------- UPDATE DIRECTION (ผู้เล่น) - ------------------------- ถือเป็นโมฆะ updateDirection () { //Serial.println ("updateDirection Called"); BUTUP = digitalRead (อัพพิน); BUDWN=digitalRead(DWNPIN); BUTLFT=digitalRead(LFTPIN); BUTRHT=digitalRead(RHTPIN); ถ้า(BUTUP==จริง) { dirPressed=DIRUP; } ถ้า (BUTDWN==true) { dirPressed=DIRDOWN; } ถ้า (BUTLFT==true) { dirPressed=DIRLEFT; } ถ้า (BUTRHT==true) { dirPressed=DIRRIGHT; }

}

//------------------------------------- ย้ายรถ --------------- --------------------------------------

// นี่จะอัปเดตหน้าจอผู้เสนอญัตติของรถสไปรท์

โมฆะ moveCar()

{ สวิตช์ (dirPressed) { กรณี DIRUP: carPosYCnt--; carPosY[carPosYCnt]; โทน (SND, 100, 100); ถ้า (carPosYCnt ==255) { carPosYCnt=0; } carYTmp=carPosY[carPosYCnt]; dirPressed=0; // Serial.println("carPosY ขึ้น"); // Serial.println (carPosYCnt); หยุดพัก; กรณี DIRDOWN: carPosYCnt++; โทน (SND, 100, 100); ถ้า (carPosYCnt==4) { carPosYCnt=3; } // Serial.println("carPosY"); // Serial.println (carPosYCnt); carYTmp=carPosY[carPosYCnt]; dirPressed=0; หยุดพัก; // แสดงความคิดเห็นว่ารถเคลื่อนที่ได้ การตรวจจับการชนกันทางซ้ายและขวายังไม่ค่อยดีนัก /* case DIRLEFT: carPosX--; ถ้า (carPosX==0) { carPosX=1; } // Serial.println("carPosX"); // Serial.println (carPosX); dirPressed=0; หยุดพัก; */ case DIRRIGHT: // เพื่อความสนุก ถ้าคุณกดขวา เกมจะมีเสียง (SND, 100, 50); // carPosX++; // if (carPosX==128) // { // carPosX=127; // } // Serial.println("carPosX"); // Serial.println (carPosX); // dirPressed=0; หยุดพัก; } updateDisplay(); }

//-------------------------- สุ่ม POS X -------------------- -----

uint8_t randomPosX() // 2 รูทีนนี้สร้างตำแหน่งสุ่มสำหรับสิ่งกีดขวาง

{ uint8_t posValTmp=0; posValTmp= สุ่ม (129, 230); //Serial.println("สุ่ม x"); // Serial.println (posValTmp); ผลตอบแทน (posValTmp); }

//--------------------------------- สุ่ม POS Y----------------- ------------------

uint8_t สุ่มPosY()

{ uint8_t เลนVal =0; laneVal= สุ่ม(0, 4); // เพิ่มช่องทางพิเศษสำหรับการสุ่ม นั่นคือไม่มีวัตถุบนหน้าจอในขณะที่อยู่ในเลนนั้น //Serial.println("RandomY"); //Serial.println(เลนPosArr[laneVal]); กลับ (lanePosArr [laneVal]); }//------------------------------------- ตั้งความเร็วเกม --------------- -------------- เป็นโมฆะ setGameSpeed () // สิ่งนี้จะหยุดระดับที่สูงกว่า 20 ทำให้เกมไม่สามารถเล่นได้ {ถ้า(drawSpeed<21) { drawSpeed=drawSpeed+2; } }// ------------------------------------ ตรวจพบความผิดพลาด ---------- ----------------------- ถือเป็นโมฆะ detectCrash () {

ถ้า(ศัตรู0PosX=0&&ศัตรู0PosY==carYTmp)

{ // Serial.println ("เกมโอเวอร์ CRAASSSSHHHHHHHEEEEDDD เข้าสู่ Traffic 0"); จบเกม(); } if(enemy1PosX=0&&enemy1PosY==carYTmp) { //Serial.println("Game Over CRAASSSSHHHHHHHEEEEDDD เข้าสู่ทราฟฟิก 1"); จบเกม(); } if(enemy2PosX=0&&enemy2PosY==carYTmp) { //Serial.println("เกมโอเวอร์ CRAASSSSHHHHHHHEEEEDDD เข้าสู่ทราฟฟิก 2"); จบเกม(); } }

เหล่านี้เป็นกิจวัตรที่วาดการแสดงผล

//------------------------------------- วาดถนน --------------- --------------------- เป็นโมฆะ drawRoad () // X, Y, ความยาว, ความกว้าง { display.fillRect (roadLineX1, 15, 30, 4, WHITE); display.fillRect(roadLineX1, 30, 30, 4, สีขาว); display.fillRect(roadLineX1, 45, 30, 4, สีขาว); display.fillRect(roadLineX2, 15, 30, 4, สีขาว); display.fillRect(roadLineX2, 30, 30, 4, สีขาว); display.fillRect(roadLineX2, 45, 30, 4, สีขาว); display.fillRect(roadLineX3, 15, 30, 4, สีขาว); display.fillRect(roadLineX3, 30, 30, 4, สีขาว); display.fillRect(roadLineX3, 45, 30, 4, สีขาว); display.fillRect(roadLineX4, 15, 30, 4, สีขาว); display.fillRect(roadLineX4, 30, 30, 4, สีขาว); display.fillRect(roadLineX4, 45, 30, 4, สีขาว); display.fillRect(roadLineX5, 15, 30, 4, สีขาว); display.fillRect(roadLineX5, 30, 30, 4, WHITE); display.fillRect(roadLineX5, 45, 30, 4, สีขาว);

roadLineX1=roadLineX1-drawSpeed;

roadLineX2=roadLineX2-drawSpeed; roadLineX3=roadLineX3-drawSpeed; roadLineX4=roadLineX4-drawSpeed; roadLineX5=roadLineX5-drawSpeed; display.display(); } //--------------------------------------------------- ดึงศัตรู ---- ---------------------------------------- voidศัตรูDraw() { // X, Y, ชื่อ bmp, ความกว้าง, ความสูง, สี display.drawBitmap(enemy0PosX,ศัตรู0PosY, ENEMY0, ENEMY0_WIDTH, ENEMY0_HEIGHT, 1); ศัตรู0PosX=ศัตรู0PosX-drawSpeed; display.drawBitmap(ศัตรู1PosX,ศัตรู1PosY, ENEMY1, ENEMY1_WIDTH, ENEMY1_HEIGHT, 1); ศัตรู1PosX=ศัตรู1PosX-drawSpeed; display.drawBitmap (ศัตรู2PosX, ศัตรู2PosY, ENEMY2, ENEMY2_WIDTH, ENEMY2_HEIGHT, 1); ศัตรู2PosX=ศัตรู2PosX-drawSpeed; display.display(); ถ้า (enemy0PosX>231&&enemy0PosX231&&enemy1PosX<255) {ศัตรู1PosX=randomPosX(); ศัตรู1PosY=สุ่มPosY(); ตรวจสอบซ้ำ (); }

ถ้า (enemy2PosX>231&&enemy2PosX<255) {ศัตรู2PosX=randomPosX(); ศัตรู2PosY=สุ่มPosY(); } } //------------------------------------------ UPDATE DISPLAY -------- ---------------------------------------- โมฆะ updateDisplay () { display.clearDisplay (); display.drawBitmap(carPosX, carPosY[carPosYCnt], CARSPRITE, 30, 15, 1); display.fillRect(100, 0, 28, 10, สีดำ); display.setCursor(100, 0); display.setTextColor (ขาว, ดำ); display.println (คะแนน); display.display();

}

//----------------------------------- รอกดลูป -------------------- ------

// นี่คือรหัสหน้าจอหลักเป็นโมฆะ waitForPress() { splashScreen(); บูลรอ=0; // วนรอบจะสิ้นสุดลงเมื่อนี่คือ display.clearDisplay(); ในขณะที่(รอ==0) {

display.fillRect (19, 20, 90, 32, สีดำ); // พื้นหลังว่างเปล่าสำหรับข้อความ

display.setTextColor(สีขาว); display.setCursor (23, 24); display.setTextSize(0); display.println("ประมาท"); display.setCursor (36, 34); display.println("นักแข่ง"); display.drawBitmap(74, 24, CARSPRITE, CARWIDTH, CARHEIGHT, 1); // x y w hr col display.drawRoundRect(21, 21, 86, 23, 4, WHITE); // เส้นขอบงู display.drawRect (19, 20, 90, 33, WHITE); // กล่องเส้นขอบ - 3 display.setCursor(25, 43); display.setTextSize(0); // แบบอักษรกลับไปที่ display.println ปกติ ("กดปุ่มใดก็ได้"); display.fillRect(0, 0, 127, 8, สีดำ); display.setCursor(10, 0); display.print("คะแนนสูง:"); // แสดงคะแนนสูง display.print (คะแนนสูง); display.display(); รอ = digitalRead (INTPIN); // ตรวจดูว่าการกดแป้นรอจะเปลี่ยนเป็น 1 ตอนจบในขณะที่ dirPressed=0; // ปุ่มรีเซ็ตกดไปที่ไม่มีทิศทาง } } //-------------------------------------- ----- อัปเดตเกม ------------------------------------- เป็นโมฆะ updateGame () { moveCar(); drawRoad(); ศัตรูวาด(); // ศัตรู1Draw(); // ศัตรู2Draw(); เมตรCnt++; ตรวจจับความผิดพลาด (); if(metreCnt==5)// เพิ่มคะแนนทุกๆ 10 รอบเพื่อตอกย้ำคะแนน { metreCnt=0; คะแนน++; } if(score==compare+5) // เร่งความเร็วเกมทุก ๆ 5 คะแนนเป็นสูงสุด 20 ความเร็ว { Compare=score; setGameSpeed(); } noTone(SND); อัปเดตดิสเพลย์ ();

}

// ------------------------------ จบเกม---------------- ------------------------------

// รูทีนนี้วาดเส้นรอบ ๆ รถฮีโร่ที่ตายแล้วแสดงเกมผ่านหน้าจอ

เป็นโมฆะ gameOver()

{ โทน (SND, 200, 200); // เล่นเสียง uint8_t linePosX, linePosY, pixwidth, pixheight=0; // ตั้งค่า vars ให้วาดกล่องรอบๆ รถ linePosX=carPosY; linePosY=carYTmp; pixwidth=30; พิกเซลสูง=15; display.drawRect(linePosX, linePosY, pixwidth, pixheight, WHITE); display.display(); for(int i=0;i<=26;i++) // คันนี้ล้อมรอบรถเป็นรูปสี่เหลี่ยมผืนผ้าจำลองการระเบิด { 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(); โทน (SND, i*20, 50); ล่าช้า(10); } display.setTextSize(2); display.setTextColor (ขาว, ดำ); display.setCursor(10, 23); โทน (SND, 50, 500); display.print("เกม"); display.display(); ล่าช้า (500); โทน (SND, 40, 500); display.print("OVER"); display.setTextSize(0); display.display(); ล่าช้า (3000); เริ่มเกมใหม่ (); waitForPress(); }

// ------------------------------------------ เริ่มเกมใหม่ ----- -------------------------------------------------- -----

เป็นโมฆะ restartGame() // คัดลอกคะแนนสูงและรีเซ็ตสถิติทั้งหมดและสร้างตำแหน่งแบบสุ่ม

{ if(score>=highScore) //ตรวจสอบว่าคะแนนสูงกว่าคะแนนสูงหรือไม่ { highScore=score; // single if statment เพื่ออัปเดตคะแนนสูง }

คะแนน=0;

drawSpeed=4; เมตรCnt=0; รถPosYCnt=0; ศัตรู0PosX=สุ่มPosX(); ศัตรู0PosY=สุ่มPosY(); ศัตรู1PosX=สุ่มPosX(); ศัตรู1PosY=สุ่มPosY(); ศัตรู2PosX=สุ่มPosX(); ศัตรู2PosY=สุ่มPosY(); ไม่มีโทน (SND);

ตรวจสอบซ้ำ ();

}

//------------------------------------------------ - ตรวจสอบซ้ำ -------------------------------------------- ------ ถือเป็นโมฆะ checkDuplicate () // การตรวจสอบเหล่านี้เพื่อดูว่ามีสิ่งกีดขวางอยู่ในพื้นที่เกมเดียวกันหรือไม่ { // Serial.println ("ตรวจสอบซ้ำกัน"); if(enemy2PosX>230&&enemy2PosX<255) { while(enemy2PosY==enemy1PosY||enemy2PosY==enemy0PosY) {ศัตรู2PosY=randomPosY(); } }

if(ศัตรู0PosX>230&&ศัตรู0PosX230&&ศัตรู2PosXenemy1PosX&&ศัตรู2PosX230&&ศัตรู0PosXenemy1PosX&&ศัตรู0PosX

//------------------------------------------- หน้าจอ --- --------------------------------

เป็นโมฆะ splashScreen()

{ display.clearDisplay(); display.drawBitmap(0, 0, CRASH, CRASHWIDTH, CRASHHEIGHT, 1); display.display(); ล่าช้า (2000); } //---------------------------------------------------------- ติดตั้ง ------------------------------------------------- ----------- การตั้งค่าเป็นโมฆะ () { ล่าช้า (100); // ปล่อยให้สิ่งต่าง ๆ เริ่มต้นขึ้น // Serial.begin(9600); // uncomment นี้และ Serial ทั้งหมด คำสั่งสำหรับการวินิจฉัยข้อบกพร่อง display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextColor (ขาว, ดำ); display.setTextWrap (เท็จ); display.dim(0); โหมดพิน (INTPIN, อินพุต); โหมดพิน (UPPIN, INPUT); โหมดพิน (DWNPIN, อินพุต); โหมดพิน (LFTPIN, INPUT); โหมดพิน (RHTPIN, อินพุต);

AttachInterrupt(digitalPinToInterrupt(INTPIN), ขัดจังหวะ, RISING);

// วางสิ่งกีดขวางแบบสุ่มศัตรู0PosX=randomPosX(); ศัตรู0PosY=สุ่มPosY(); ศัตรู1PosX=สุ่มPosX(); ศัตรู1PosY=สุ่มPosY(); ศัตรู2PosX=สุ่มPosX(); ศัตรู2PosY=สุ่มPosY(); ตรวจสอบซ้ำ (); // ตรวจสอบตำแหน่งที่ซ้ำกัน // Serial.println("การติดตั้งเสร็จสมบูรณ์"); หน้าจอ(); waitForPress(); } //---------------------------------------------------------- ----- ลูป ---------------------------------------------------- ----------

วงเป็นโมฆะ ()

{ อัปเดตเกม (); }

และนั่นคือทั้งหมด การปรับเปลี่ยนและข้อเสนอแนะใด ๆ ยินดีต้อนรับ ปัญหาที่เราจำเป็นต้องแก้ไขการสั่นของหน้าจอเราต้องดูว่าจะลดมันอย่างไรและรถศัตรูก็ยังสามารถครอบครองพื้นที่เดิมได้

แนะนำ: