เกมนี้ดัดแปลงมาจากเกมตู้ Arcade ชื่อ Cyclone ครับ หลักการคือผู้เล่นต้องกดปุ่มให้ไฟ LED ที่วิ่งวนเป็นวงกลมหยุดตรงจุดที่กำหนดให้ได้
ในคลิปก่อนหน้านี้ ผมเคยเอาเกมแบบเดียวกันมาให้ดูแล้ว แต่เป็นวงใหญ่ 60 LED และมีหลายเลเวล

รอบนี้ผมใช้ริงเล็ก 12 LED และเกมจะไม่แบ่งเลเวลแล้ว แต่จะเล่นต่อเนื่องไปเรื่อยๆ จนกว่าเราจะกดพลาด!

นอกจากนี้ยังมีจอ LCD แสดงคะแนนสูงสุด (Highscore) และรอบปัจจุบัน (Current Round) ด้วย
โค้ดต้นฉบับเอามาจาก GitHub ของ Joern Weise แล้วผมก็ปรับแต่งนิดหน่อย
เริ่มจากลดขั้นตอนการทดสอบ LED ลง แล้วก็เพิ่มเสียงเอฟเฟกต์ที่แตกต่างกันในแต่ละช่วงของเกม ทำให้มันสนุกขึ้นเยอะเลย
อุปกรณ์ก็ง่ายๆ ไม่มีอะไรซับซ้อน ประกอบด้วย:
- Arduino nano
- ริง LED 12 ดวง แบบ WS2812
- จอ LCD 16x2 พร้อมโมดูล I2C
- ปุ่มกด 2 อัน
- และ Buzzer

The FastLED Array Engine
ริง NeoPixel (เช่น 12 ดวง) ก็คืออาร์เรย์วงกลมนั่นแหละ
- ไลบรารี
<FastLED.h>จะสร้างอาร์เรย์ขึ้นมา:CRGB leds[12]; - Logic การหมุน: โค้ด C++ ใช้ลูป
forที่รันเร็วๆ เพื่อเลื่อน "จุด" ไฟ
for (int i = 0; i < 12; i++) {
leds[i] = CRGB::Red; // เปิดไฟตำแหน่งปัจจุบัน
leds[(i-1+12)%12] = CRGB::Black; // ปิดไฟตำแหน่งก่อนหน้า
FastLED.show();
delay(gameSpeed);
}
- ค่า
gameSpeedจะถูกสุ่มในแต่ละรอบ เราสามารถปรับค่าพวกนี้ในโค้ดได้ที่บรรทัด:#define STARTINTERVAL 250 //"Normal" move#define MAXINTERVAL 500 //Very slow move#define MININTERVAL 50 //Very fast move
Hardware Interrupts (AttachInterrupt)
สมมติไฟแดงวิ่งเร็ว 50 มิลลิวินาทีต่อดวง เวลาตอบสนองของมนุษย์จะถูกทดสอบสุดๆ
- ข้อเสียของการ Poll ธรรมดา: ถ้าใช้
digitalRead(buttonPin)ในloop()บางครั้ง Arduino อาจจะกำลังยุ่งกับคำสั่งFastLED.show()จนพลาดการกดปุ่มไปเลยก็ได้ - ทางออกด้วย Hardware: เราเดินสายปุ่มกดไปที่พินที่รองรับ Interrupt โดยเฉพาะ
attachInterrupt(digitalPinToInterrupt(pin), buttonPressed, FALLING);- พอกดปุ่มกดแรงๆ ระดับสัญญาณที่พินจะตกทันที ทำให้ CPU ของ Arduino หยุดการทำงานที่กำลังทำอยู่แบบฉับพลัน แล้วไปรันฟังก์ชัน
buttonPressedทันที เพื่อตรวจสอบว่ากดตรงจุดเป้าหมายหรือไม่ แล้วก็จะแสดงผลชนะ(ไฟเขียว) หรือแพ้(ไฟแดง)!

ส่วนการเล่นเกม อย่างที่บอกไปว่าเกมนี้ไม่มีเลเวลที่ความเร็วเพิ่มขึ้น แต่แต่ละรอบจะเริ่มด้วยความเร็วที่สุ่มใหม่ และเราสามารถปรับช่วงความเร็วได้ง่ายๆ ในโค้ดตามบรรทัดที่บอกไปแล้ว
#define STARTINTERVAL 250 // ความเร็วปกติ #define MAXINTERVAL 500 // ช้าสุดขั้ว #define MININTERVAL 50 // เร็วปรี๊ด

เอาล่ะ มาดูกันดีกว่าว่าของจริงมันทำงานยังไง
ตอนเปิดเกม LED ทั้งหมดจะติดไล่กันไป พร้อมเสียงเอฟเฟกต์ตั๊กๆ และมีข้อความแสดงผลการทดสอบบนหน้าจอ LCD ด้วย

จากนั้น กดปุ่มเพื่อเริ่มเกมได้เลย เป้าหมายคือ กดปุ่มให้ทันตอนที่ LED วิ่ง (ตัวหมุน) มาหยุดตรงกับ LED ที่ติดค้างอยู่ (ตัวนิ่ง) พอดี ในสองเลเวลแรกจะมี LED นิ่งอยู่ 3 ดวง ส่วนเลเวลต่อไปจะมีแค่ดวงเดียว จำนวนรอบที่ผ่านและคะแนนจะแสดงบนหน้าจอ

ถ้ากดพลาดโดน LED สีแดงล่ะก็ เกมจบ! แล้วคะแนนสูงสุด (High Score) จะปรากฏบนหน้าจอแทน

จำนวนรอบและคะแนนจะแสดงบนหน้าจอ ส่วนคะแนนสูงสุดนั้นจะถูกบันทึกลงใน EEPROM ของไมโครคอนโทรลเลอร์ ทำให้ข้อมูลไม่หายแม้จะรีเซ็ตเครื่อง

ถ้าอยากลบคะแนนสูงสุดทิ้ง เวลาเปิดเครื่องให้กดปุ่ม HSR ค้างไว้ สุดท้าย เกมนี้เราติดตั้งบนแผ่น PVC หนา 3 มม. และหุ้มด้วยวอลเปเปอร์สีแบบติดเอง จัดไปวัยรุ่น! สู้งานนะน้อง ห้ามช็อตนะตัวนี้