[Arduino Project] สร้างเกมงู Dot Matrix 8×8 ด้วย Arduino พร้อม JoyStick

สร้างเกมงู Dot Matrix 8×8 ด้วย Arduino พร้อม JoyStick

1. แนวคิด ความสำคัญและความเป็นมาของโครงการ
โรคสมาธิสั้นนี้พบได้บ่อยในทุกประเทศทั่วโลก ในประเทศไทยพบว่า ประมาณ  5% ของเด็กในวัยเรียนป่วยเป็นโรคสมาธิสั้น หมายความว่า ห้องเรียนห้องหนึ่งถ้ามีนักเรียนอยู่ประมาณ 50 คน จะมีเด็กที่ป่วยเป็นโรคสมาธิสั้นอยู่ในห้องเรียนประมาณ 2-3 คน อาการขาดสมาธิ  คนนั้นจะมีลักษณะวอกแวกง่าย ขาดความตั้งใจในการทำงาน โดยเฉพาะอย่างยิ่งงานที่ต้องใช้ความคิด เด็กมักจะแสดงอาการเหม่อลอยบ่อยๆ ฝันกลางวัน ทำงานไม่เสร็จ เราจึงได้คิดเกมงูนี้ออกมาให้คนที่มีสมาธิสั้นได้ฝึกได้เล่นนอกจากจะให้ความสนุกสนานเพลิดเพลินกับแล้ว ยังเสริมสร้างพัฒนาการที่ดีอีกด้วย ช่วยเพิ่มประสิทธิภาพด้านความจำ ฝึกการสังเกต การฝึกไหวพริบและฝึกสมาธิให้กับคนที่มีสมาธิสั้น และพัฒนาสมองให้ดีขึ้นอีกด้วย

2. วัตถุประสงค์และเป้าหมาย
– เพื่อศึกษาการทำงานของโปรแกรม
– เพื่อศึกษาการใช้งานของ Arduino
– เพื่อให้ผู้ที่สนใจสามารถนำไปพัฒนาต่อได้
– สามารถนำไปประยุกต์ใช้ในชีวิตประจำวันได้

3. วัสดุอุปกรณ์
– Arduino UNO R3 CH340G 1  ตัว
– กล่องใส 1 กล่อง
– Dot matrix led 8×8 1 ตัว
– Joystick module 1 ตัว
– สายแพร์

4. ขั้นตอนการจัดทำโครงงาน D.I.Y. 

    

รูปการต่อวงจร

Source Code

#define MAX7219DIN 4
#define MAX7219CS 5
#define MAX7219CLK 6
#define JOYX A1
#define JOYY A0
#define BUTTON 2
#define SPEAKER 3

byte p[8]={0,0,0,0,0,0,0,0};      //bitmap to display
byte nums[10][3]={                   //bitmap of numbers
{28,34,28},
{36,62,32},
{50,42,36},
{42,42,20},
{28,18,62},
{46,42,18},
{28,42,18},
{50,10,6},
{54,42,54},
{4,42,28}
};

byte marquee1[]={0,0,0,0,0,0,0,0,0,127,9,9,6,120,
4,4,56,84,84,24,0,72,84,36,0,72,84,36,0,0, 0,  62, 68, 68,
56, 68, 68, 56, 0,  0,  72, 84, 36, 0,  62, 68, 68, 0,  116,  84,
120,  0,  120,  4,  4,  0,  62, 68, 68, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
byte marquee2[]={0,0,0,0,0,0,70,73,49,0,56,
68,68,0,56,68,68,56,0,120,4,4,0,60,84,
92,0,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0};

char sx[64];
char sy[64];                      //snake positions, zeroth is front of snake, first slen are valid
char dir=0;                       //1=up, 2=right, 3=down, 4=left
char slen=0;
int score=0;
char gamestate=0;                 //0=idle, 1=play, 2 =game over
unsigned long tc=80; //menu             //time between game cycles (~speed/difficulty)
unsigned long ts=250;//snake
void setup() {
MAX7219init();
MAX7219brightness(1);
pinMode(BUTTON,INPUT_PULLUP);
pinMode(SPEAKER,OUTPUT);
}

void loop() {
switch(gamestate){
case 0: doidle(); break;
case 1: dogame(); break;
case 2: dogameover(); break;
case 3: dogameend(); break;
}

delay(gamestate ==1 ? ts : tc);
}

void dogameend(){
gamestate=2;
tone(SPEAKER,100,500);
}

void dogameover(){
//tc=80;
static int n=0;
marquee2[30]=nums[(score/100)%10][0];
marquee2[31]=nums[(score/100)%10][1];
marquee2[32]=nums[(score/100)%10][2];
marquee2[34]=nums[(score/10)%10][0];
marquee2[35]=nums[(score/10)%10][1];
marquee2[36]=nums[(score/10)%10][2];
marquee2[38]=nums[(score/1)%10][0];
marquee2[39]=nums[(score/1)%10][1];
marquee2[40]=nums[(score/1)%10][2];
MAX7219sendbm(marquee2+n);
n++;
if(n>sizeof(marquee2)-8){n=0;}
if(digitalRead(BUTTON)==LOW){   //change modes,
gamestate=0;
MAX7219sendbm(marquee1);        //blank screen
while(digitalRead(BUTTON)==LOW){}// wait til released
}

}
void dogame(){
int i;                //loop variable
char newx,newy;
int a;
if(slen==0){        //game is reset > initialise
score=0;
dir=1;
sx[0]=3;
sy[0]=3;
sx[1]=3;
sy[1]=4;
sx[2]=3;
sy[2]=5;
slen=3;
}
newx=sx[0];
newy=sy[0];     //new snake head position
a=analogRead(JOYX);
if(a<256){dir=2;}
if(a>768){dir=4;}
a=analogRead(JOYY);
if(a<256){dir=1;}
if(a>768){dir=3;}
switch(dir){
case 1: newy=newy-1;break;
case 2: newx=newx+1;break;
case 3: newy=newy+1;break;
case 4: newx=newx-1;break;
}
if((newx<0)||(newx>7)||(newy<0)||(newy>7)){     //outside walls > game over
gamestate=3;
}
for(i=0;i<slen;i++){
if((newx==sx[i])&&(newy==sy[i])){gamestate=3;}  //collided with self > game over
}
for(i=63;i>0;i–){                             //move old positions
sx[i]=sx[i-1];
sy[i]=sy[i-1];
}
sx[0]=newx;
sy[0]=newy;
for(i=0;i<8;i++){p[i]=0;}                   //clear display
for(i=0;i<slen;i++){                        //draw snake
p[sx[i]]=p[sx[i]]|(1<<(sy[i]));
}

MAX7219sendbm(p);
score++;                //increase score
slen=(score+50)/25;    //increase length
tone(SPEAKER,440,10);  //chirp for game rhythm
}

void doidle(){
//tc=80;
static int n=0;
MAX7219sendbm(marquee1+n);
n++;
if(n>sizeof(marquee1)-8){n=0;}
if(digitalRead(BUTTON)==LOW){   //change modes,
gamestate=1;
MAX7219sendbm(marquee1);        //blank screen
//tc=200;                         //slow down
slen=0;                         //reset game
while(digitalRead(BUTTON)==LOW){}// wait til released
}
}

void MAX7219shown(byte n){
byte s[8];
s[0]=nums[(n/10)%10][0];
s[1]=nums[(n/10)%10][1];
s[2]=nums[(n/10)%10][2];
s[3]=0;
s[4]=nums[n%10][0];
s[5]=nums[n%10][1];
s[6]=nums[n%10][2];
s[7]=0;
MAX7219sendbm(s);
}

void MAX7219sendbm(byte p[]){
for(int i=0;i<8;i++){
MAX7219senddata(i+1,p[i]);
}
}

void MAX7219brightness(byte b){  //0-15 is range high nybble is ignored
MAX7219senddata(10,b);        //intensity
}

void MAX7219init(){
pinMode(MAX7219DIN,OUTPUT);
pinMode(MAX7219CS,OUTPUT);
pinMode(MAX7219CLK,OUTPUT);
digitalWrite(MAX7219CS,HIGH);   //CS off
digitalWrite(MAX7219CLK,LOW);   //CLK low
MAX7219senddata(15,0);        //test mode off
MAX7219senddata(12,1);        //display on
MAX7219senddata(9,0);         //no decode
MAX7219senddata(11,7);        //scan all
for(int i=1;i<9;i++){
MAX7219senddata(i,0);       //blank all
}
}

void MAX7219senddata(byte reg, byte data){
digitalWrite(MAX7219CS,LOW);   //CS on
for(int i=128;i>0;i=i>>1){
if(i&reg){
digitalWrite(MAX7219DIN,HIGH);
}else{
digitalWrite(MAX7219DIN,LOW);
}
digitalWrite(MAX7219CLK,HIGH);
digitalWrite(MAX7219CLK,LOW);   //CLK toggle
}
for(int i=128;i>0;i=i>>1){
if(i&data){
digitalWrite(MAX7219DIN,HIGH);
}else{
digitalWrite(MAX7219DIN,LOW);
}
digitalWrite(MAX7219CLK,HIGH);
digitalWrite(MAX7219CLK,LOW);   //CLK toggle
}

digitalWrite(MAX7219CS,HIGH);   //CS off
}

5. ผลการทดลอง

เริ่มต้น แสดงตัวหนังสือบน หน้าจอให้กดปุ่นกลางไหลไปเรื่อยๆ พอกดปุ่นกลางแล้วจะเริ่มเกมมีงูออกมาวิ่งตัวจะยาวขึ้นเรื่อยๆทุกๆ 8 วินาที

พอชนกำแพงหรือกินหางตัวเองจะแสดงสกอ กดปุ่มกลางเพื่อเริ่มเกมใหม่

พอชนกำแพงหรือกินหางตัวเองจะแสดงสกอ กดปุ่มกลางเพื่อเริ่มเกมใหม่

6. แนวทางในการพัฒนาต่อในอนาคต
สามารถประยุกต์ใช้ร่วมกับงานอื่น ๆ ได้อย่างไร
สามารถนำเป็นเพิ่มขนาดเป็น 16×16 ได้หรือมากกว่าและสามารถเขียนเกมอื่นเข้ามาควบคุมได้

7. ข้อสรุปและข้อเสนอแนะ
เราสามารถนำชิ้นงานไปเล่นเพื่อฝึกสมาธิและยังได้ความเพลิดเพลิน

D.I.Y.

การนำเสนองาน

  •  
  •  
  •  
  •  
  •  
  •  
TEERAPAT CHATTANJAI
at GlurGeek.Com
ขื่อ นาย ธีรพัฒน์ ฉัตรตันใจ 1600901464 ชื่อเล่น อั๊ง เรียนอยู่คณะวิศวกรรมศาสตร์ สาขาไฟฟ้า เข้ามาเพื่อส่งเกมงูครัช

Leave a Reply