สารบัญ:
วีดีโอ: เกมงู Arduino OLED: 3 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:04
สวัสดีและยินดีต้อนรับสู่คำแนะนำของเราเกี่ยวกับวิธีการสร้างและเกม Arduino OLED โปรเจ็กต์นี้เกิดขึ้นเมื่อเรากำลังพยายามสร้างเกมแรกของเราด้วย Arduino ดีมาก เราคิดว่าจะเริ่มต้นที่ไหนดีกว่างูคลาสสิกของ Nokia (ดีที่ อย่างน้อยโคลนงู:))
สิ่งที่คุณต้องการ
เสบียง
Arduino UNO หรือโคลน
จอแสดงผล OLED
4 ไดโอด
ตัวต้านทาน 500-1k
4 ปุ่มควบคุม
ออด Piezo แบบพาสซีฟ
ไม่จำเป็น
เขียงหั่นขนมไร้บัดกรี
โปรดทราบว่าลิงก์เหล่านี้เป็นเพียงตัวอย่างเท่านั้น
ขั้นตอนที่ 1: วงจร
ในภาพด้านบนคุณจะเห็นวงจรของเรา เราใช้พิน d3 บน Arduino เป็นพินคำขอขัดจังหวะ เพื่อให้ Arduino ให้ความสำคัญกับการอ่านอินพุตคอนโทรลเลอร์ซึ่งก็คือ d4 d5 d6 d7 พื้นฐานของวงจรคือการกดปุ่มทิศทางซึ่งสูง 5v ซึ่งจะเปิดใช้งานพินคำขอขัดจังหวะ (d3 สายสีม่วง) และพินทิศทางที่สอดคล้องกัน ฟังก์ชันขัดจังหวะจะเรียกใช้ฟังก์ชันทิศทางการอัปเดตและรหัสนั้นจะย้ายงูตามลำดับ พิน 9 ใช้เป็นพินเสียงเนื่องจากเป็น PWM (~ การมอดูเลตความกว้างพัลส์) ซึ่งเชื่อมต่อโดยตรงกับ 5v piezo บนพิน + และ - จะกลับไปที่ 0v/กราวด์
(FYI บน Arduino uno และโคลนเฉพาะ d2 และ d3 เท่านั้นที่สามารถทำหน้าที่เป็นหมุดคำขอขัดจังหวะ)
หมุดทิศทาง:
d4 ขึ้น สีส้ม
d5 ลงสีชมพู
d6 ซ้าย BLUE
d7 ขวา BROWN
d9 เสียงสีเทา
แต่ละปุ่มมีอินพุตการเชื่อมต่อ 5v และเอาต์พุตที่เชื่อมต่อกับอินพุตดิจิตอลตามลำดับบน Arduino ก่อน จากนั้นเอาต์พุตเดียวกันของแต่ละปุ่มจะเชื่อมต่อกับไดโอดของมันเอง เราใช้ไดโอดเพื่อหยุดการป้อนแรงดันไฟฟ้ากลับไปยัง ปุ่มอื่นๆ และเปิดใช้งาน ที่ปลายแคโทด (-) ของไดโอดทั้ง 4 ตัว เรารวมพวกมันเข้าด้วยกันเพื่อสร้างทางแยกเอาต์พุตที่เชื่อมต่อกับ d3 จากนั้นผ่านตัวต้านทานไปที่ 0v/earth เพื่อดึงพิน Arduino ให้ต่ำเพื่อไม่ให้พินลอยเมื่อไม่ได้อยู่ เปิดใช้งาน
(FYI พินลอยสามารถรับแรงดันไฟหลอกและทำให้เกิดพฤติกรรมผิดปกติได้)
ใช้พินอะนาล็อก 2 อันเพื่อขับเคลื่อนจอแสดงผล นี่คือพินฮาร์ดแวร์ Arduino i2c
A5 เชื่อมต่อกับ SCL YELLOW
A4 เชื่อมต่อกับ SDA GREEN
เอาต์พุต +5v และ 0v (สายดิน) จาก Arduino ถูกใช้เป็นแหล่งพลังงานสำหรับวงจรทั้งหมด ซึ่งสามารถจ่ายไฟด้วย USB หรือเครื่องชาร์จโทรศัพท์
ขั้นตอนที่ 2: รหัส
//----------------------- ANJAWARE SNAKE Games ด้วยความช่วยเหลือจากชาวเน็ต --------------- --------
#รวม
#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // ชุดแสดงผล (ความกว้าง, ความสูง) Adafruit_SSD1306 display(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 // ทิศทางที่งูจะเดินทาง # นิยาม DIRLEFT 3 #define DIRRIGHT 4
// ตั้งค่าตัวแปรปุ่ม
// ระเหยเพราะเราต้องการให้มันอัปเดตด้วยการขัดจังหวะเพื่อให้สามารถเป็นค่ารอบได้
// ไม่เคยสูงกว่า 4 ดังนั้นต้องการเพียง 8 บิต int เพื่อประหยัดทรัพยากร uint8_t buttonpressed = 0; บูลบัตอัพ=0; ปุ่มบูลดาวน์=0; // เราใช้สิ่งนี้เพื่อตั้งค่าจริงเป็น "ตรวจจับ" ว่าทิศทางใดที่กด bool butleft=0; บูล แต่ไรท์=0;
// งู ints
ไบต์ snakePosX[30]; // อาร์เรย์เพื่อสร้างเนื้อความของงูไบต์ snakePosY[30];
int งูX=30; // ตำแหน่งหัวงู
int งูY=30; int งูขนาด=1; // ขนาดงู จำกัด อยู่ที่ขนาดของอาร์เรย์
// โลกทั้งใบ
uint8_t worldMinX=0; // สิ่งเหล่านี้กำหนดขอบเขตของพื้นที่เล่น
uint8_t worldMaxX=128; uint8_t worldMinY=10; uint8_t worldMaxY=63;
// เก็บ scran(อาหาร) และตำแหน่งของ scran
บูล scranAte =0; uint8_t scranPosX=0; uint8_t scranPosY=0;
// คะแนนตัวแปร
playcore แบบยาว=0; คะแนนสูงสุดยาว = 30; // ตั้งคะแนนสูงเป็น 3 รวบรวมเป็นจุดเริ่มต้น
//--------------------------- นี่คือสิ่งที่อินเตอร์รัปต์ทำงานเมื่อแรงดันไฟฟ้าเพิ่มขึ้น ------------ --------------
โมฆะถูกขัดจังหวะ () { ล่าช้า (150); // หน่วงเวลาเล็กน้อยสำหรับการป้องกัน "ตีกลับ" ที่เพิ่มเข้ามา updatedirection(); } // ------------------ อัปเดตค่าทิศทางจากการกดปุ่ม ----------------- void updatedirection() { // Serial.println("updatingdirection"); butup=digitalRead(UPPIN); // ตรวจสอบว่าอินพุตใดสูงและตั้งค่าบูลที่เกี่ยวข้อง true butdown=digitalRead(DWNPIN); butleft=digitalRead(LFTPIN); butright=digitalRead(RHTPIN); // สิ่งเหล่านี้หาก statemeents ดูว่าอินพุตใดสูงและป้อนค่าที่เกี่ยวข้องในตัวแปร "buttonpressed" // ตัวแปรนี้กำหนดทิศทางของการเคลื่อนไหว if(butup==true) { buttonpressed=DIRUP; // Serial.println("กดขึ้น"); // Serial.println (ปุ่มกด); butup=เท็จ; โทน (SND, 1500, 10); } if(butdown==true) { buttonpressed=DIRDOWN; // Serial.println("กดลง"); // Serial.println (ปุ่มกด); ปุ่มลัด=เท็จ; โทน (SND, 1500, 10); }
ถ้า(butleft==จริง)
{ กดปุ่ม = DIRLEFT; // Serial.println("กดซ้าย"); // Serial.println (ปุ่มกด); butleft=false; โทน (SND, 1500, 10); } if(butright==true) { กดปุ่ม = DIRRIGHT; // Serial.println("กดขวา"); // Serial.println (ปุ่มกด); butright=false; โทน (SND, 1500, 10); } }
//-------------------------- วาดขั้นตอนการแสดงผล ------------------ -----------------
ถือเป็นโมฆะ updateDisplay() // วาดคะแนนและโครงร่าง
{ // Serial.println ("อัปเดตการแสดงผล");
display.fillRect(0, 0, display.width()-1, 8, BLACK);
display.setTextSize(0); display.setTextColor(สีขาว); // วาดคะแนน display.setCursor(2, 1); display.print("คะแนน:"); display.print(สตริง(playscore, ธ.ค.)); display.setCursor(66, 1); display.print("สูง:"); display.print(สตริง(คะแนนสูงสุด ธ.ค.)); // วาดพื้นที่เล่น // pos 1x, 1y, 2x, 2y, color display.drawLine(0, 0, 127, 0, WHITE); // ขอบบนสุด display.drawLine (63, 0, 63, 9, WHITE); // ตัวคั่นคะแนน display.drawLine(0, 9, 127, 9, WHITE); // ด้านล่างเส้นขอบข้อความ display.drawLine(0, 63, 127, 63, WHITE); // ขอบล่าง display.drawLine(0, 0, 0, 63, WHITE); // ขอบซ้าย display.drawLine(127, 0, 127, 63, WHITE); //ขอบขวา
}
//----------------------------------- อัปเดตพื้นที่เล่น ---------- --------------------
ถือเป็นโมฆะ updateGame() // อัปเดตพื้นที่เกม display
{ display.clearDisplay();
display.drawPixel (scranPosX, scranPosY, สีขาว);
scranAte = scranFood();
// ตรวจสอบกิจวัตรงู
ถ้า (outOfArea()||selfCollision())
{ จบเกม(); }
//แสดงงู
สำหรับ (int i=0;i0;i--) { snakePosX = snakePosX[i-1]; งูPosY = งูPosY[i-1]; } // เพิ่มพิกเซลพิเศษให้กับงูถ้า (scranAte) { snakeSize+=1; snakePosX[snakeSize-1]=snakeX; snakePosY[snakeSize-1]=snakeY; }
switch(buttonpressed) // เป็น snakeDirection
{ กรณี DIRUP: งูY-=1; หยุดพัก; กรณี DIRDOWN: งูY+=1; หยุดพัก; กรณี DIRLEFT: snakeX-=1; หยุดพัก; กรณี DIRRIGHT: งูX+=1; หยุดพัก; } งูPosX[0] = งูX; งูPosY[0] = งูY; อัปเดตดิสเพลย์ (); display.display(); // --------------------- วาง scran --------------------
เป็นโมฆะ placeScran()
{ scranPosX=random(worldMinX+1, worldMaxX-1); scranPosY=random(worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood() { if(snakeX==scranPosX&&snakeY==scranPosY) {playscore=playscore+10; โทน (SND, 2000, 10); อัปเดตดิสเพลย์ (); placeScran(); ส่งคืน 1; } อื่น ๆ { กลับ 0; } } //--------------------- นอกพื้นที่---------------------- bool outOfArea () { กลับ snakeX = worldMaxX ||snakeY = worldMaxY; } //---------------------- จบเกม----------------------- --- โมฆะ gameOver () { uint8_t rectX1, rectY1, rectX2, rectY2; rectX1=38; rectY1=28; rectX2=58; rectY2=12; display.clearDisplay(); display.setCursor(40, 30); display.setTextSize(1); โทน (SND, 2000, 50); display.print("เกม"); โทน (SND, 1000, 50); display.print("OVER"); if(playscore>=highscore) //ตรวจสอบว่าคะแนนสูงกว่าคะแนนสูงหรือไม่ { highscore=playscore; // single if statment เพื่ออัปเดตคะแนนสูง } สำหรับ (int i=0;i<=16;i++) // นี่คือการวาดสี่เหลี่ยมรอบเกมเหนือ { display.drawRect(rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println("ถ้าวนซ้ำ"); display.display(); rectX1-=2; // เลื่อนไป 2 พิกเซล rectY1-=2; rectX2+=4; // เลื่อนมากกว่า 2 พิกเซลจากจุดสุดท้าย rectY2+=4; โทน(SND, i*200, 3); } display.display(); //Screen Wipe หลังจากชื่อเสียงเหนือ rectX1=0; // กำหนดตำแหน่งเริ่มต้นของเส้น rectY1=0; rectX2=0; rectY2=63; สำหรับ (int i =0;i<=127;i++) { uint8_t cnt=0; display.drawLine(rectX1, rectY1, rectX2, rectY2, สีดำ); rectX1++; rectX2++; display.display(); } display.clearDisplay(); เพลย์สกอร์=0; // รีเซ็ตรายละเอียดงูและผู้เล่น snakeSize=1; snakeX=display.width()/2; งูY=display.height()/2; waitForPress(); // รอให้ผู้เล่นเริ่มเกม } //----------------------------------- รอการกดวน ---------- --------------- เป็นโมฆะ waitForPress () { บูลรอ = 0; // วนรอบสิ้นสุดลงเมื่อนี่คือ display.clearDisplay(); ในขณะที่ (รอ == 0) { drawAlineForMe (สีขาว); // วาดเส้นสีขาวแบบสุ่ม drawAlineForMe(BLACK); // วาดเส้นสีดำแบบสุ่มเพื่อไม่ให้หน้าจอเต็ม display.fillRect(19, 20, 90, 32, BLACK); // พื้นหลังว่างสำหรับ text display.setTextColor(WHITE); display.setCursor (35, 25); display.setTextSize(2); // แบบอักษรที่ใหญ่กว่า display.println("SNAKE"); // x y w hr col display.drawRoundRect(33, 22, 62, 20, 4, WHITE); // เส้นขอบงู display.drawRect (19, 20, 90, 32, WHITE); // กล่องเส้นขอบ - 3 display.setCursor(28, 42); display.setTextSize(0); // แบบอักษรกลับไปที่ display.println ปกติ ("กดปุ่มใดก็ได้"); display.display(); รอ = digitalRead (INTPIN); // ตรวจสอบเพื่อดูว่าการกดปุ่มรอจะเปลี่ยนเป็น 1 สิ้นสุดในขณะที่กดปุ่ม = 0; // กดปุ่มรีเซ็ต } } //-------------------- วาดสีอินพุตบรรทัดสุ่ม uint8_t -------------- ----- เป็นโมฆะ drawAlineForMe (uint8_t clr) { uint8_t line1X, line1Y, line2X, line2Y = 0; // กำหนดพิกัดสุ่มสำหรับเส้นแล้ววาดมัน // ตัวแปรไม่น้อยกว่าไม่มีอีกแล้ว line1X = สุ่ม (worldMinX+1, worldMaxX-1); line1Y = สุ่ม (worldMinY+1, worldMaxY-1); line2X = สุ่ม (worldMinX+1, worldMaxX-1); line2Y = สุ่ม (worldMinY+1, worldMaxY-1); display.drawLine(line1X, line1Y, line2X, line2Y, clr); } //------------------------------------------ การตรวจจับการชน -------- ------------------------
for(byte i=4;i<snakeSize;i++) { if(snakeX==snakePosX&&snakeY==snakePosy) { return 1; โทน (SND, 2000, 20); โทน (SND, 1000, 20); } คืนค่า 0; }
//-------------------------------- ติดตั้ง--------------- -------------------------------------
การตั้งค่าเป็นโมฆะ () { ล่าช้า (100); // เพียงแค่ให้โอกาสในการ "บูต" // Serial.begin(9600); // ยกเลิกการเลือกนี้หากคุณต้องการดูเอาต์พุตอนุกรม display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); // เริ่มต้นด้วยการแสดงผลที่สะอาดหมดจด display.setTextColor(WHITE); // ตั้งค่าขนาดการหมุนสีข้อความ ฯลฯ display.setRotation(0); display.setTextWrap (เท็จ); display.dim(0); // ตั้งค่า pinMode ความสว่างของจอแสดงผล (INTPIN, INPUT); // ตั้งค่าพอร์ตที่ถูกต้องเป็นอินพุต pinMode (UPPIN, INPUT); โหมดพิน (DWNPIN, อินพุต); โหมดพิน (LFTPIN, INPUT); โหมดพิน (RHTPIN, อินพุต); // นี่คือคำสั่ง interupt ซึ่ง "หยุด" Arduino เพื่ออ่านอินพุต //command- function- pin-function เพื่อดำเนินการเงื่อนไขบน pin AttachInterrupt (digitalPinToInterrupt (INTPIN), ขัดจังหวะ, RISING); // Serial.println("การตั้งค่าผ่าน"); waitForPress(); // แสดงหน้าจอเริ่มต้นของงู placeScran(); // วางอาหารมื้อแรก } //--------------------------- MAIN LOOP----------------- ---------------------- วงเป็นโมฆะ () { updateGame (); // ฟังก์ชั่นนี้คือสิ่งที่ถือรหัสหลัก }
ขั้นตอนที่ 3:
แนะนำ:
เมนูแสดงผล Arduino OLED พร้อมตัวเลือกให้เลือก: 8 ขั้นตอน
เมนูแสดงผล Arduino OLED พร้อมตัวเลือกในการเลือก: ในบทช่วยสอนนี้ เราจะเรียนรู้วิธีสร้างเมนูที่มีตัวเลือกการเลือกโดยใช้ OLED Display และ Visuino ดูวิดีโอ
Arduino วิธีใช้จอแสดงผล OLED ขนาด 1.3 นิ้ว SH1106: 7 ขั้นตอน
Arduino วิธีใช้จอแสดงผล OLED ขนาด 1.3 นิ้ว SH1106: ในบทช่วยสอนนี้ เราจะเรียนรู้วิธีใช้ซอฟต์แวร์ Arduino และ Visuino สำหรับจอแสดงผล OLED ขนาด 1.3 นิ้ว ดูวิดีโอ
Arduino ควบคุมความเร็วและทิศทางของมอเตอร์ DC โดยใช้โพเทนชิออมิเตอร์ จอแสดงผล OLED และปุ่ม: 6 ขั้นตอน
Arduino ควบคุมความเร็วและทิศทางของมอเตอร์ DC โดยใช้โพเทนชิออมิเตอร์ จอแสดงผล OLED และปุ่ม: ในบทช่วยสอนนี้ เราจะเรียนรู้วิธีใช้ไดรเวอร์ L298N DC MOTOR CONTROL และโพเทนชิออมิเตอร์เพื่อควบคุมความเร็วและทิศทางของมอเตอร์กระแสตรงด้วยปุ่มสองปุ่มและแสดงค่าโพเทนชิออมิเตอร์ บนจอแสดงผล OLED ชมวิดีโอสาธิต
NeoPixels Matrix:เกมงู: 4 ขั้นตอน
NeoPixels Matrix:เกมงู: คุณยังจำเกมงูที่เราเล่นในกล่องเกมหรือมือถือในวัยเด็กของเราได้หรือไม่? วันนี้เราจะมาเรียนรู้วิธีการสร้างเกมงูด้วย 8*8 NeoPixels Matrix เราเลือก Arduino uno เป็นศูนย์ควบคุมและโมดูล Joystick breakout เพื่อร่วม
เกมงู: 4 ขั้นตอน
เกมงู: สวัสดีทุกคน วันนี้ผมจะแสดงให้คุณเห็นถึงวิธีการสร้างเกมงูพื้นฐานใน Python และทำให้เพื่อน ๆ ประหลาดใจในวันหยุดนี้ มันง่ายมากคุณเพียงแค่ต้องติดตั้ง python 3 และ pygame ในคำแนะนำนี้ ฉันได้เพิ่มวิดีโอเกี่ยวกับวิธีการติดตั้ง pygame หลังจาก