极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 19568|回复: 5

“重力感应”点阵贪吃蛇

[复制链接]
发表于 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控制芯片。
\
\
\
最后来个演示视频啦



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

  3. /*
  4. MAX7219
  5. pin 12-Din
  6. pin 11-CLK
  7. pin 10-CS
  8. */
  9. #define Register_ID 0
  10. #define Register_2D 0x2D
  11. #define Register_X0 0x32
  12. #define Register_X1 0x33
  13. #define Register_Y0 0x34
  14. #define Register_Y1 0x35
  15. #define Register_Z0 0x36
  16. #define Register_Z1 0x37


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


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

  24. int Sxy[3][2]= {
  25.   {
  26.     2,4        }
  27.   ,{
  28.     1,4        }
  29.   ,{
  30.     0,4        }
  31. }; //蛇身体坐标集合,一共3个点

  32. char K;

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

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

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

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

  37. int socre=0;

  38. unsigned long delaytime=200;



  39. void setup() {
  40.   Wire.begin();  //初始化I2C
  41.   delay(100);
  42.   Wire.beginTransmission(ADXAddress);
  43.   Wire.write(Register_2D);
  44.   Wire.write(8);
  45.   Wire.endTransmission();



  46.   lc.shutdown(0,false);

  47.   lc.setIntensity(0,2);

  48.   lc.clearDisplay(0);



  49.   Serial.begin(9600);

  50.   //delay(5000);

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

  56.   resetSnake();



  57. }



  58. void loop() {
  59.   
  60.   Wire.beginTransmission(ADXAddress);
  61.   Wire.write(Register_X0);
  62.   Wire.write(Register_X1);
  63.   Wire.endTransmission();
  64.   Wire.requestFrom(ADXAddress,2);
  65.   if(Wire.available()<=2);
  66.   {
  67.     X0 = Wire.read();
  68.     X1 = Wire.read();
  69.     X1 = X1<<8;
  70.     X_out = X0+X1;
  71.   }

  72.   Wire.beginTransmission(ADXAddress);
  73.   Wire.write(Register_Y0);
  74.   Wire.write(Register_Y1);
  75.   Wire.endTransmission();
  76.   Wire.requestFrom(ADXAddress,2);
  77.   if(Wire.available()<=2);
  78.   {
  79.     Y0 = Wire.read();
  80.     Y1 = Wire.read();
  81.     Y1 = Y1<<8;
  82.     Y_out = Y0+Y1;
  83.   }

  84.   Wire.beginTransmission(ADXAddress);
  85.   Wire.write(Register_Z0);
  86.   Wire.write(Register_Z1);
  87.   Wire.endTransmission();
  88.   Wire.requestFrom(ADXAddress,2);
  89.   if(Wire.available()<=2);
  90.   {
  91.     Z0 = Wire.read();
  92.     Z1 = Wire.read();
  93.     Z1 = Z1<<8;
  94.     Z_out = Z0+Z1;
  95.   }
  96.   Xg = X_out;//把输出结果转换为重力加速度g,精确到小数点后2位。
  97.   Yg = Y_out;
  98.   Zg = Z_out;

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

  102.   {

  103.     K='r';

  104.   }

  105.   if(Xg>70) {

  106.     K='l';

  107.   }



  108.   if(Yg>70)

  109.   {

  110.     K='d';

  111.   }

  112.   if(Yg<-70) {

  113.     K='u';

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

  117. KEY=K;

  118. }

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

  120. KEY=K;

  121. }

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

  123. KEY=K;

  124. }

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

  126. KEY=K;

  127. }
  128. //
  129.   drawSnake(LOW);



  130.   if(KEY =='u') {

  131.     SX =Sxy[0][0]-1; // up

  132.     SY =Sxy[0][1];

  133.     /* 根据按键来移动蛇的身体
  134.      
  135.      Sxy[2][0] = Sxy[1][0];
  136.      
  137.      Sxy[2][1] = Sxy[1][1];
  138.      
  139.      Sxy[1][0] = Sxy[0][0];
  140.      
  141.      Sxy[1][1] = Sxy[0][1];
  142.      
  143.      */

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

  145.       Sxy[i][0] = Sxy[i-1][0];

  146.       Sxy[i][1] = Sxy[i-1][1];

  147.     }

  148.     Sxy[0][0] =SX;

  149.     Sxy[0][1] =SY;

  150.   }



  151.   if(KEY =='d') {

  152.     SX =Sxy[0][0]+1; // down

  153.     SY =Sxy[0][1];

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

  155.       Sxy[i][0] = Sxy[i-1][0];

  156.       Sxy[i][1] = Sxy[i-1][1];

  157.     }

  158.     Sxy[0][0] =SX;

  159.     Sxy[0][1] =SY;

  160.   }



  161.   if(KEY =='r') {

  162.     SX =Sxy[0][0];

  163.     SY =Sxy[0][1]+1; // right

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

  165.       Sxy[i][0] = Sxy[i-1][0];

  166.       Sxy[i][1] = Sxy[i-1][1];

  167.     }

  168.     Sxy[0][0] =SX;

  169.     Sxy[0][1] =SY;

  170.   }



  171.   if(KEY =='l') {

  172.     SX =Sxy[0][0];

  173.     SY =Sxy[0][1]-1; // left

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

  175.       Sxy[i][0] = Sxy[i-1][0];

  176.       Sxy[i][1] = Sxy[i-1][1];

  177.     }

  178.     Sxy[0][0] =SX;

  179.     Sxy[0][1] =SY;

  180.   }





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

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

  183.     gameover();

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

  188.     ReadyGO();

  189.     resetSnake();

  190.     socre=0;
  191.   }



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

  193.   if(Sxy[0][0]==FX && Sxy[0][1]==FY) {

  194.     RANDOM();

  195.     Speed --;

  196.     if (Speed<0) {

  197.       Speed = 0;

  198.     }
  199.     socre=socre+1;

  200.   }



  201.   drawSnake(HIGH);

  202.   WAIT(Speed);        

  203. }

  204. //开始动画

  205. void write() {
  206.   for(int i=8;i>=0;i--)
  207.   {
  208.     lc.setIntensity(0,2*i-1);
  209.     lc.setLed(0,i,i,true);
  210.     delay(delaytime);
  211.     lc.setLed(0,7-i,i,true);
  212.   }
  213.   delay(delaytime);
  214.   for(int i=3;i>=0;i--)
  215.   {
  216.     lc.setLed(0,i,i,false);
  217.     delay(50);
  218.     lc.setLed(0,7-i,i,false);
  219.   }
  220.   delay(delaytime/2);
  221.   for(int i=4;i>=0;i--)
  222.   {
  223.     lc.setIntensity(0,8);
  224.     lc.setLed(0,3,i,true);
  225.     lc.setLed(0,4,i,true);
  226.     delay(delaytime);
  227.   }
  228.   lc.clearDisplay(0);
  229. }

  230. //开始ReadyGo

  231. void ReadyGO() {

  232.   byte Ready[5][8]={
  233.     {
  234.       B11000111,B11001000,B11010000,B11111100,B11000010,B11000010,B11000010,B11111100                        }
  235.     ,
  236.     {
  237.       B00011111,B01111000,B11110000,B11111100,B11000010,B11000010,B01100010,B00111100                            }
  238.     ,
  239.     {
  240.       B00000011,B01111111,B11100010,B11000010,B11000010,B11000010,B01100110,B00111100                            }
  241.     ,
  242.     {
  243.       B00110011,B01001111,B11000110,B11000110,B01111110,B00011110,B00000110,B00000110                            }
  244.     ,
  245.     {
  246.       B11100000,B00111000,B00011100,B00110110,B00100110,B00100010,B01000010,B00000000                            }
  247.   };
  248.   for(int x=0;x<5;x++)
  249.   {
  250.     for(int i=0;i<8;i++)
  251.     {
  252.       for(int y=0;y<8;y++)
  253.       {
  254.         lc.setColumn(0,y,Ready[x][y]<<i);
  255.       }
  256.       delay(delaytime/2);
  257.     }   
  258.   }
  259.   byte Go[8]={
  260.     B01101111,B10011101,B10001111,B10000000,B10000000,B10001000,B01110000,B00000000    }
  261.   ;
  262.   for(int i=0;i<8;i++)
  263.   {
  264.     lc.setIntensity(0,8);
  265.     delay(100);
  266.     lc.setColumn(0,i,Go[i]);
  267.   }
  268.   delay(3000);
  269.   lc.clearDisplay(0);
  270. }


  271. // 重置蛇的坐标

  272. void resetSnake() {



  273.   int k=millis()%10 + 1;

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

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

  276.   }



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

  278.     // Sxy[3][2]= {{2,4},{1,4},{0,4}};

  279.     Sxy[i][0] =2-i;

  280.     Sxy[i][1] =4;

  281.   }



  282.   KEY ='d';

  283.   Speed = 11;

  284.   WAIT(5);

  285. }



  286. // 绘制蛇的函数

  287. void drawSnake(boolean OnOff) {



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

  289.     lc.setLed(0,Sxy[i][0],Sxy[i][1],OnOff);

  290.   }

  291. }        



  292. //随机食物获取函数

  293. void RANDOM()

  294. {

  295.   FX=random(0, 7);

  296.   FY=random(0, 7);

  297. }



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

  299. void WAIT(int timeF)

  300. {

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

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

  303.     delay(50);

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

  305.     delay(50);

  306.   }

  307. }



  308. //GameOver函数,游戏结束

  309. void gameover()

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

  312.     drawSnake(HIGH);

  313.     delay(100);

  314.     drawSnake(LOW);

  315.     delay(100);
  316.   }
  317.   byte Over[8]={
  318.     B11101010,B10001100,B11101010,B11101110,B00000000,B11100100,B10101010,B11101010    };
  319.   for(int i=0;i<8;i++)
  320.   {
  321.     lc.setIntensity(0,4);
  322.     delay(100);
  323.     lc.setColumn(0,i,Over[i]);
  324.   }
  325.   delay(3000);
  326.   byte GameOver[5][8]={
  327.     {
  328.       B01000100,B01001100,B01000101,B01010110,B01001100,B11010101,B01011111,B00101000            }
  329.     ,
  330.     {
  331.       B11110011,B10010101,B11110001,B10010111,B11110001,B10001111,B01000100,B00100010            }
  332.     ,
  333.     {
  334.       B00100001,B10101001,B01110110,B00101111,B11111001,B10101001,B01101111,B00100000            }
  335.     ,
  336.     {
  337.       B00000100,B01001100,B00100100,B00010101,B10111110,B01000100,B00100000,B00010000            }
  338.     ,
  339.     {
  340.       B00000000,B00011000,B00011000,B00000000,B00011000,B00011000,B00000000,B00000000            }
  341.     ,
  342.   };
  343.   for(int x=0;x<5;x++)
  344.   {
  345.     for(int i=0;i<8;i++)
  346.     {
  347.       for(int y=0;y<8;y++)
  348.       {
  349.         lc.setColumn(0,y,GameOver[x][y]<<i);
  350.       }
  351.       delay(delaytime/2);
  352.     }   
  353.   }
  354.   lc.clearDisplay(0);

  355.   byte Num[12][8]={
  356.     {
  357.       B01111000,B11001100,B11001100,B11001100,B11001100,B11001100,B11001100,B01111000       }
  358.     ,
  359.     {
  360.       B01111110,B01111110,B00011000,B00011000,B00011000,B00011000,B01111000,B00111000       }
  361.     ,
  362.     {
  363.       B11111111,B11111111,B01100000,B00111100,B00000010,B01000010,B01111110,B00111100       }
  364.     ,
  365.     {
  366.       B00111110,B01100010,B01000110,B00001100,B00011100,B00000010,B00000010,B00111100       }
  367.     ,
  368.     {
  369.       B00011000,B00011000,B00011000,B11111110,B10011110,B01011000,B00111000,B00011000       }
  370.     ,
  371.     {
  372.       B11111100,B11111100,B00001100,B00001100,B11111100,B11000000,B11000000,B11111100       }
  373.     ,
  374.     {
  375.       B01111000,B11111100,B11001100,B11001100,B11111000,B11000000,B01110000,B00111000       }
  376.     ,
  377.     {
  378.       B00001100,B00001100,B00001100,B00001100,B00001100,B00001100,B01111100,B01111100       }
  379.     ,
  380.     {
  381.       B01111000,B11111100,B11001100,B11001100,B11111100,B11001100,B11111100,B01111000       }
  382.     ,
  383.     {
  384.       B00001100,B00001100,B00001100,B00001100,B11111100,B10001100,B10001100,B11111100       }
  385.     ,
  386.     {
  387.       B01101111,B01101001,B01101001,B01101001,B01101001,B01101001,B01101001,B01101111       }
  388.     ,
  389.     {
  390.       B01101100,B01101100,B01101100,B01101100,B01101100,B01101100,B01101100,B01101100       }
  391.     ,
  392.   };
  393.   if(socre==0)
  394.   {
  395.     for(int y=0;y<8;y++)
  396.     {
  397.       lc.setColumn(0,y,Num[0][y]);
  398.     }
  399.   }
  400.   if(socre==1)
  401.   {
  402.     for(int y=0;y<8;y++)
  403.     {
  404.       lc.setColumn(0,y,Num[1][y]);
  405.     }
  406.   }
  407.   if(socre==2)
  408.   {
  409.     for(int y=0;y<8;y++)
  410.     {
  411.       lc.setColumn(0,y,Num[2][y]);
  412.     }
  413.   }
  414.   if(socre==3)
  415.   {
  416.     for(int y=0;y<8;y++)
  417.     {
  418.       lc.setColumn(0,y,Num[3][y]);
  419.     }
  420.   }
  421.   if(socre==4)
  422.   {
  423.     for(int y=0;y<8;y++)
  424.     {
  425.       lc.setColumn(0,y,Num[4][y]);
  426.     }
  427.   }
  428.   if(socre==5)
  429.   {
  430.     for(int y=0;y<8;y++)
  431.     {
  432.       lc.setColumn(0,y,Num[5][y]);
  433.     }
  434.   }
  435.   if(socre==6)
  436.   {
  437.     for(int y=0;y<8;y++)
  438.     {
  439.       lc.setColumn(0,y,Num[6][y]);
  440.     }
  441.   }
  442.   if(socre==7)
  443.   {
  444.     for(int y=0;y<8;y++)
  445.     {
  446.       lc.setColumn(0,y,Num[7][y]);
  447.     }
  448.   }
  449.   if(socre==8)
  450.   {
  451.     for(int y=0;y<8;y++)
  452.     {
  453.       lc.setColumn(0,y,Num[8][y]);
  454.     }
  455.   }
  456.   if(socre==9)
  457.   {
  458.     for(int y=0;y<8;y++)
  459.     {
  460.       lc.setColumn(0,y,Num[9][y]);
  461.     }
  462.   }
  463.   if(socre==10)
  464.   {
  465.     for(int y=0;y<8;y++)
  466.     {
  467.       lc.setColumn(0,y,Num[10][y]);
  468.     }
  469.   }
  470.   if(socre==11)
  471.   {
  472.     for(int y=0;y<8;y++)
  473.     {
  474.       lc.setColumn(0,y,Num[11][y]);
  475.     }
  476.   }
  477.   delay(5000);
  478.   lc.clearDisplay(0);

  479. }



复制代码


所需要的库文件- LedControl



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-11-15 20:21:18 | 显示全部楼层
有木有电路图呀
回复 支持 反对

使用道具 举报

发表于 2014-2-16 19:44:13 | 显示全部楼层
thanks for sharing LedControl.h
回复 支持 反对

使用道具 举报

发表于 2014-3-3 21:52:59 | 显示全部楼层
给一下针脚定义和连接吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-4 12:14:05 | 显示全部楼层
eee987 发表于 2014-3-3 21:52
给一下针脚定义和连接吧

不知道你要那些的针脚定义?
回复 支持 反对

使用道具 举报

发表于 2016-3-8 21:45:54 | 显示全部楼层
您好 不知道是否方便提供硬体方面的接线图
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-15 04:28 , Processed in 0.039669 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表