สารบัญ:
2025 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2025-01-23 15:12
ในบทช่วยสอนนี้ เราจะมาดูวิธีใช้บิตแมปโดยใช้ไลบรารี Adafruit_GFX.c ในรูปแบบสไปรต์ในเกม เกมที่ง่ายที่สุดที่เราคิดได้คือเกมรถเลื่อนเลนด้านข้าง ในที่สุดผู้ทดสอบเบต้าและผู้ช่วย coder ของเราก็ตัดสินใจตั้งชื่อว่า "Reckless Racer" เนื่องจากมันค่อนข้างประมาทที่จะขับในทางที่ผิดบนทางด่วน!!
การออกแบบวงจรของเราอยู่ในรูปภาพด้านบนและมีรายละเอียดในโครงการ/บทแนะนำล่าสุดของเราที่นี่ Snake Instructables ซึ่งอธิบายวิธีการทำงานของวงจร
เราจะต้องการ
Adafruit_GFX
Paint.net
Arduino IDE windowslinux
และโปรดดูบทช่วยสอนงูสำหรับอุปกรณ์ที่เหลือ
เสบียง
เกมงู
ขั้นตอนที่ 1: ติดตั้ง 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
ตอนนี้เราต้องแปลงภาพของเราให้อยู่ในรูปแบบที่ 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
ตอนนี้เราโหลด 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
ตามคำแนะนำก่อนหน้านี้ใช้ 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: สร้างเกมขับรถ
ขั้นแรก เราเริ่มต้นด้วยการวาดรถหรือสิ่งกีดขวางต่าง ๆ เช่นในขั้นตอนก่อนหน้าของบทช่วยสอนที่ทำให้เป็นพิกเซลขนาด 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(); } //---------------------------------------------------------- ----- ลูป ---------------------------------------------------- ----------
วงเป็นโมฆะ ()
{ อัปเดตเกม (); }
และนั่นคือทั้งหมด การปรับเปลี่ยนและข้อเสนอแนะใด ๆ ยินดีต้อนรับ ปัญหาที่เราจำเป็นต้องแก้ไขการสั่นของหน้าจอเราต้องดูว่าจะลดมันอย่างไรและรถศัตรูก็ยังสามารถครอบครองพื้นที่เดิมได้
แนะนำ:
เกม "Space Impact" พร้อม Gyro Sensor และ Nokia 5110 LCD: 3 ขั้นตอน
เกม "Space Impact" พร้อม Gyro Sensor และ Nokia 5110 LCD: หลังจากที่ Tamagotchi ของฉันเสียชีวิต (โครงการสุดท้าย) ฉันเริ่มค้นหาวิธีใหม่ในการเสียเวลา ฉันตัดสินใจตั้งโปรแกรมเกมคลาสสิก "Space Impact" บน Arduino เพื่อทำให้เกมน่าสนใจและสนุกขึ้นอีกเล็กน้อย ฉันใช้เซ็นเซอร์ไจโรสโคปที่ฉันมี
เกม Buzz Wire ใช้ Makey Makey และ Scratch: 3 ขั้นตอน
เกม Buzz Wire ที่ใช้ Makey Makey และ Scratch: นี่คือเกมโดยเด็กอายุ 11 ปีของฉัน เขาสร้างและตั้งโปรแกรมเกมนี้กับน้องชายของเขาเพื่อให้ไขว้เขวในช่วงที่ COVID19 ปิดตัวลง และเขาต้องการเข้าร่วมงานแสดง Online Coolest Projects "ฉันเอาแนวคิดหลักสำหรับ
ตัวควบคุม Arduino MIDI พื้นฐาน: 5 ขั้นตอน
Basic Arduino MIDI Controller: Intro:ฉันยังใหม่กับการทำงานร่วมกับ Arduino แต่ฉันหวังว่าจะเพิ่มพูนความรู้ของฉันโดยการสอนผู้อื่นและรับข้อเสนอแนะ นี่คือตัวควบคุม MIDI ขั้นพื้นฐานที่มี 4 ปุ่มและโพเทนชิออมิเตอร์ โครงร่างสำหรับโครงการนี้มีลักษณะดังนี้:1. สร้างออกท
เกม Makey Makey และ Scratch Operation: 6 ขั้นตอน (พร้อมรูปภาพ)
Makey Makey and Scratch Operation Game: สร้างเกมปฏิบัติการขนาดเท่าตัวจริงของตัวละครของคุณเอง! โครงการสุดง่ายสำหรับทุกเพศทุกวัย
[พื้นฐาน] Medir Una Resistencia Con Arduino: 3 ขั้นตอน
[พื้นฐาน] Medir Una Resistencia Con Arduino: En Arduino มีอยู่ únicamente dos formas de captar datos del mundo ภายนอก:- ดิจิตอล: sus valores pueden ser 0 o 1, การพึ่งพาอาศัยกันของ si se aplica o no un voltaje al conector que se está leyendo como entrada.- Analógica: sus valor