code-AR 发表于 2013-11-14 13:29:07

“重力感应”点阵贪吃蛇

本帖最后由 code-AR 于 2013-11-14 13:33 编辑

前段时间看了Z大的基于IIC的点阵,编写的贪吃蛇。
要看帖子移步这里
【Z也来玩点阵】Arduino I2C 8*8点阵玩贪吃蛇游戏~附程序讲解~
http://www.geek-workshop.com/thread-5407-1-1.html

看完有些想法,但是手上只有基于Max7219的点阵模块,后来又看见了hmjack2008 同学贡献的代码,基于此我开始了重力版的制作,完成后能够通过重力感应控制贪吃蛇的方向,能够显示积分。

首先上图先,

组装好,工作中。。。

拆卸下来滴部件。

主控用的是张老师的Microduino,因为用锂电池供电,外加了个BM模块。

重力控制是用的ADXL345

点阵就是这个了,是MAX7219控制芯片。
\
\
\
最后来个演示视频啦
http://v.youku.com/v_show/id_XNjM0NjEyODA0.html


关键的代码详解
#include "LedControl.h"
#include <Wire.h>//调用arduino自带的I2C库

/*
MAX7219
pin 12-Din
pin 11-CLK
pin 10-CS
*/
#define Register_ID 0
#define Register_2D 0x2D
#define Register_X0 0x32
#define Register_X1 0x33
#define Register_Y0 0x34
#define Register_Y1 0x35
#define Register_Z0 0x36
#define Register_Z1 0x37


int ADXAddress = 0xA7>>1;//转换为7位地址
int reading = 0;
int X0,X1,X_out;
int Y0,Y1,Y_out;
int Z1,Z0,Z_out;
double Xg,Yg,Zg;


LedControl lc=LedControl(12,11,10,1);

int Sxy= {
{
    2,4      }
,{
    1,4      }
,{
    0,4      }
}; //蛇身体坐标集合,一共3个点

char K;

int FX,FY; //食物的坐标

int SX,SY; //蛇头的坐标

char KEY ='d'; // up, down, left, right

int Speed =8;//贪吃蛇的初始速度

int socre=0;

unsigned long delaytime=200;



void setup() {
Wire.begin();//初始化I2C
delay(100);
Wire.beginTransmission(ADXAddress);
Wire.write(Register_2D);
Wire.write(8);
Wire.endTransmission();



lc.shutdown(0,false);

lc.setIntensity(0,2);

lc.clearDisplay(0);



Serial.begin(9600);

//delay(5000);

//开始动画
write();
delay(1000);
ReadyGO();
//循环绘制蛇的身体,3个点

resetSnake();



}



void loop() {

Wire.beginTransmission(ADXAddress);
Wire.write(Register_X0);
Wire.write(Register_X1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress,2);
if(Wire.available()<=2);
{
    X0 = Wire.read();
    X1 = Wire.read();
    X1 = X1<<8;
    X_out = X0+X1;
}

Wire.beginTransmission(ADXAddress);
Wire.write(Register_Y0);
Wire.write(Register_Y1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress,2);
if(Wire.available()<=2);
{
    Y0 = Wire.read();
    Y1 = Wire.read();
    Y1 = Y1<<8;
    Y_out = Y0+Y1;
}

Wire.beginTransmission(ADXAddress);
Wire.write(Register_Z0);
Wire.write(Register_Z1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress,2);
if(Wire.available()<=2);
{
    Z0 = Wire.read();
    Z1 = Wire.read();
    Z1 = Z1<<8;
    Z_out = Z0+Z1;
}
Xg = X_out;//把输出结果转换为重力加速度g,精确到小数点后2位。
Yg = Y_out;
Zg = Z_out;

lc.setIntensity(0,2);
//获得 按键信息
if(Xg<-70)

{

    K='r';

}

if(Xg>70) {

    K='l';

}



if(Yg>70)

{

    K='d';

}

if(Yg<-70) {

    K='u';

}
//这里开始是验证是否与行进方向相反,选择控制方向
if (K=='u'&&KEY!='d' ){

KEY=K;

}

if (K=='d'&&KEY!='u' ){

KEY=K;

}

if (K=='l'&&KEY!='r' ){

KEY=K;

}

if (K=='r'&&KEY!='l' ){

KEY=K;

}
//
drawSnake(LOW);



if(KEY =='u') {

    SX =Sxy-1; // up

    SY =Sxy;

    /* 根据按键来移动蛇的身体
   
   Sxy = Sxy;
   
   Sxy = Sxy;
   
   Sxy = Sxy;
   
   Sxy = Sxy;
   
   */

    for (int i=2; i>0; i--) {

      Sxy = Sxy;

      Sxy = Sxy;

    }

    Sxy =SX;

    Sxy =SY;

}



if(KEY =='d') {

    SX =Sxy+1; // down

    SY =Sxy;

    for (int i=2; i>0; i--) {

      Sxy = Sxy;

      Sxy = Sxy;

    }

    Sxy =SX;

    Sxy =SY;

}



if(KEY =='r') {

    SX =Sxy;

    SY =Sxy+1; // right

    for (int i=2; i>0; i--) {

      Sxy = Sxy;

      Sxy = Sxy;

    }

    Sxy =SX;

    Sxy =SY;

}



if(KEY =='l') {

    SX =Sxy;

    SY =Sxy-1; // left

    for (int i=2; i>0; i--) {

      Sxy = Sxy;

      Sxy = Sxy;

    }

    Sxy =SX;

    Sxy =SY;

}





//判断是否超出边框,超出就跳转到GameOver

if(SY<0 || SY>7 || SX<0 || SX>7) {

    gameover();

    if(Zg<-10)
    {
      lc.shutdown(0,true);
    }

    ReadyGO();

    resetSnake();

    socre=0;
}



//判断是否吃到了食物~吃到就会加分和重新随机生成食物~

if(Sxy==FX && Sxy==FY) {

    RANDOM();

    Speed --;

    if (Speed<0) {

      Speed = 0;

    }
    socre=socre+1;

}



drawSnake(HIGH);

WAIT(Speed);      

}

//开始动画

void write() {
for(int i=8;i>=0;i--)
{
    lc.setIntensity(0,2*i-1);
    lc.setLed(0,i,i,true);
    delay(delaytime);
    lc.setLed(0,7-i,i,true);
}
delay(delaytime);
for(int i=3;i>=0;i--)
{
    lc.setLed(0,i,i,false);
    delay(50);
    lc.setLed(0,7-i,i,false);
}
delay(delaytime/2);
for(int i=4;i>=0;i--)
{
    lc.setIntensity(0,8);
    lc.setLed(0,3,i,true);
    lc.setLed(0,4,i,true);
    delay(delaytime);
}
lc.clearDisplay(0);
}

//开始ReadyGo

void ReadyGO() {

byte Ready={
    {
      B11000111,B11001000,B11010000,B11111100,B11000010,B11000010,B11000010,B11111100                        }
    ,
    {
      B00011111,B01111000,B11110000,B11111100,B11000010,B11000010,B01100010,B00111100                            }
    ,
    {
      B00000011,B01111111,B11100010,B11000010,B11000010,B11000010,B01100110,B00111100                            }
    ,
    {
      B00110011,B01001111,B11000110,B11000110,B01111110,B00011110,B00000110,B00000110                            }
    ,
    {
      B11100000,B00111000,B00011100,B00110110,B00100110,B00100010,B01000010,B00000000                            }
};
for(int x=0;x<5;x++)
{
    for(int i=0;i<8;i++)
    {
      for(int y=0;y<8;y++)
      {
      lc.setColumn(0,y,Ready<<i);
      }
      delay(delaytime/2);
    }   
}
byte Go={
    B01101111,B10011101,B10001111,B10000000,B10000000,B10001000,B01110000,B00000000    }
;
for(int i=0;i<8;i++)
{
    lc.setIntensity(0,8);
    delay(100);
    lc.setColumn(0,i,Go);
}
delay(3000);
lc.clearDisplay(0);
}


// 重置蛇的坐标

void resetSnake() {



int k=millis()%10 + 1;

for(int i=0; i<k; i++) {

    RANDOM(); //获取一个随机食物坐标

}



for (int i=0; i<3; i++) {

    // Sxy= {{2,4},{1,4},{0,4}};

    Sxy =2-i;

    Sxy =4;

}



KEY ='d';

Speed = 11;

WAIT(5);

}



// 绘制蛇的函数

void drawSnake(boolean OnOff) {



for (int i=0; i<3; i++) {

    lc.setLed(0,Sxy,Sxy,OnOff);

}

}      



//随机食物获取函数

void RANDOM()

{

FX=random(0, 7);

FY=random(0, 7);

}



//通过不断闪现食物来完成延迟,这样既可以做到精确延时,也可以让食物不断闪动

void WAIT(int timeF)

{

for(int t=1;t<=timeF;t++) {

    lc.setLed(0,FX,FY,HIGH);

    delay(50);

    lc.setLed(0,FX,FY,LOW);

    delay(50);

}

}



//GameOver函数,游戏结束

void gameover()

{
for (int j=0; j<10; j++) {

    drawSnake(HIGH);

    delay(100);

    drawSnake(LOW);

    delay(100);
}
byte Over={
    B11101010,B10001100,B11101010,B11101110,B00000000,B11100100,B10101010,B11101010    };
for(int i=0;i<8;i++)
{
    lc.setIntensity(0,4);
    delay(100);
    lc.setColumn(0,i,Over);
}
delay(3000);
byte GameOver={
    {
      B01000100,B01001100,B01000101,B01010110,B01001100,B11010101,B01011111,B00101000            }
    ,
    {
      B11110011,B10010101,B11110001,B10010111,B11110001,B10001111,B01000100,B00100010            }
    ,
    {
      B00100001,B10101001,B01110110,B00101111,B11111001,B10101001,B01101111,B00100000            }
    ,
    {
      B00000100,B01001100,B00100100,B00010101,B10111110,B01000100,B00100000,B00010000            }
    ,
    {
      B00000000,B00011000,B00011000,B00000000,B00011000,B00011000,B00000000,B00000000            }
    ,
};
for(int x=0;x<5;x++)
{
    for(int i=0;i<8;i++)
    {
      for(int y=0;y<8;y++)
      {
      lc.setColumn(0,y,GameOver<<i);
      }
      delay(delaytime/2);
    }   
}
lc.clearDisplay(0);

byte Num={
    {
      B01111000,B11001100,B11001100,B11001100,B11001100,B11001100,B11001100,B01111000       }
    ,
    {
      B01111110,B01111110,B00011000,B00011000,B00011000,B00011000,B01111000,B00111000       }
    ,
    {
      B11111111,B11111111,B01100000,B00111100,B00000010,B01000010,B01111110,B00111100       }
    ,
    {
      B00111110,B01100010,B01000110,B00001100,B00011100,B00000010,B00000010,B00111100       }
    ,
    {
      B00011000,B00011000,B00011000,B11111110,B10011110,B01011000,B00111000,B00011000       }
    ,
    {
      B11111100,B11111100,B00001100,B00001100,B11111100,B11000000,B11000000,B11111100       }
    ,
    {
      B01111000,B11111100,B11001100,B11001100,B11111000,B11000000,B01110000,B00111000       }
    ,
    {
      B00001100,B00001100,B00001100,B00001100,B00001100,B00001100,B01111100,B01111100       }
    ,
    {
      B01111000,B11111100,B11001100,B11001100,B11111100,B11001100,B11111100,B01111000       }
    ,
    {
      B00001100,B00001100,B00001100,B00001100,B11111100,B10001100,B10001100,B11111100       }
    ,
    {
      B01101111,B01101001,B01101001,B01101001,B01101001,B01101001,B01101001,B01101111       }
    ,
    {
      B01101100,B01101100,B01101100,B01101100,B01101100,B01101100,B01101100,B01101100       }
    ,
};
if(socre==0)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==1)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==2)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==3)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==4)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==5)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==6)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==7)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==8)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==9)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==10)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
if(socre==11)
{
    for(int y=0;y<8;y++)
    {
      lc.setColumn(0,y,Num);
    }
}
delay(5000);
lc.clearDisplay(0);

}





所需要的库文件- LedControl



北斗 发表于 2013-11-15 20:21:18

有木有电路图呀:)

namyzal 发表于 2014-2-16 19:44:13

thanks for sharing LedControl.h

eee987 发表于 2014-3-3 21:52:59

给一下针脚定义和连接吧

code-AR 发表于 2014-3-4 12:14:05

eee987 发表于 2014-3-3 21:52 static/image/common/back.gif
给一下针脚定义和连接吧

不知道你要那些的针脚定义?

nlpss93048 发表于 2016-3-8 21:45:54

您好 不知道是否方便提供硬体方面的接线图
页: [1]
查看完整版本: “重力感应”点阵贪吃蛇