极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 71536|回复: 18

【Z也来玩点阵】Arduino I2C 8*8点阵玩贪吃蛇游戏~附程序讲解~

[复制链接]
发表于 2013-7-21 20:59:28 | 显示全部楼层 |阅读模式
本帖最后由 zzz 于 2019-5-17 09:25 编辑

今天中午Z收到了迷你强这两天一直在玩的I2C点阵,这种小8*8点阵最大的特点是内置恒流驱动,而且是IIC控制,支持arduino最新的GFX图形库,所以做起交互来可谓是相当的简单,下午随手写了一个贪吃蛇游戏,用的是大家都能看懂的算法~没有用C上常用的贪吃蛇算法来做,因为那样初学者理解起来可能会很困难,所以就特地用最简单的方式来写~先上一段测试视频~




代码详解

  1. #include <Wire.h> //I2C链接库
  2. #include "Adafruit_LEDBackpack.h" //点阵驱动库
  3. #include "Adafruit_GFX.h" //Arduino图形库

  4. Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix(); //设置I2C点阵型号

  5. static uint8_t __attribute__ ((progmem)) z[]={B01111110,B00000010,B00000100,B00001000,B00010000,B00100000,B01000000,B01111110}; //小Z的logo代码,其实就是一个一个点的量灭组成的,可以自己写~

  6. int speedS=8; //贪吃蛇的初始速度
  7. int socre=0; //游戏起始得分
  8. int FX,FY; //事物的坐标
  9. int SX,SY; //蛇头的坐标
  10. int KEY,K; //串口取得按键码和比对后的按键码,这里后面有说明
  11. char s[6]; //蛇身体坐标集合,一共3个点,6个元素

  12. void setup() {
  13. Serial.begin(9600);
  14. RANDOM(); //获取一个随机食物坐标
  15. s[1]=0;s[2]=2;s[3]=1;s[4]=2;s[5]=2;s[6]=2; //初始化蛇的身体坐标
  16. KEY=4; //初始化按键码,实际上就是行进方向,用1、2、3、4来代替4个正交方向

  17. matrix.begin(0x70); //设定IIC屏幕地址
  18. matrix.clear();  //屏幕清屏
  19. matrix.writeDisplay();  //屏幕显示
  20. matrix.setRotation(3);  //设置屏幕显示方向
  21. matrix.clear();

  22. Logo(); //绘制开机Logo,哈哈其实就是小Z的logo,视频里看不清,自己玩下就懂了~

  23. matrix.writeDisplay();
  24. delay(1000);

  25. matrix.setTextWrap(false);  //设置字体平滑模式
  26. matrix.setTextSize(1); //设置字体大小
  27. matrix.setTextColor(2); //设定LED颜色,这里说明下,除了双色点阵,其他都用2表示点亮LED,0表示熄灭~

  28. for (int8_t x=7; x>=-59; x--) {
  29. matrix.clear();
  30. matrix.setCursor(x,0);
  31. matrix.print("READY!!! GO");
  32. matrix.writeDisplay();
  33. delay(70);
  34. }
  35. //循环绘制文字,获得滚动效果

  36. matrix.clear();
  37. for(int i=1;i<=6;i+=2)
  38. {
  39. matrix.drawPixel(s[i], s[i+1], 2);
  40. }
  41. matrix.writeDisplay();
  42. delay(400);
  43. }
  44. //循环绘制蛇的身体,实际上就是3个点咯~

  45. void RANDOM()
  46. {
  47. FX=random(0, 7);
  48. FY=random(0, 7);
  49. }
  50. //随机食物获取函数

  51. void Delay(int timeF)
  52. {
  53. for(int t=1;t<=timeF;t++)
  54. {
  55. matrix.drawPixel(FX, FY, 2);
  56. matrix.writeDisplay();
  57. delay(50);
  58. matrix.drawPixel(FX, FY, 0);
  59. matrix.writeDisplay();
  60. delay(50);
  61. }
  62. }
  63. //重点说一下,这个是演示函数,实际上通过不断闪现食物来完成延迟,这样既可以做到精确延时,也可以让食物不断闪动,来让大家不断的看到~

  64. void Logo()
  65. {
  66. for (int x=1;x<=6;x++) {

  67. matrix.drawPixel(x, 0, 2);
  68. matrix.writeDisplay();
  69. delay(35);
  70. }
  71. for (int x=1;x<=6;x++) {

  72. matrix.drawPixel(7-x, x, 2);
  73. matrix.writeDisplay();
  74. delay(35);
  75. }
  76. for (int x=1;x<=6;x++) {

  77. matrix.drawPixel(x, 7, 2);
  78. matrix.writeDisplay();
  79. delay(35);
  80. }
  81. for (int x=1;x<=45;x++) {
  82. matrix.clear();
  83. matrix.writeDisplay();
  84. delay(x);
  85. matrix.drawBitmap(0,0,z,8,8,2);
  86. matrix.writeDisplay();
  87. delay(x);
  88. }
  89. }
  90. //Z Logo绘制函数,看不懂可以跳过~~~不过还是蛮简单的,仔细看下就明白了~

  91. void gameover()
  92. {
  93. for (int8_t x=7; x>=-125; x--) {
  94. matrix.clear();
  95. matrix.setCursor(x,0);
  96. matrix.print("GAME OVER YOUR SOCRE:");
  97. matrix.writeDisplay();
  98. delay(70);
  99. }
  100. //GameOver函数,显示游戏结束和得分

  101. for (int8_t x=7; x>=-39; x--) {
  102. matrix.clear();
  103. matrix.setCursor(x,0);
  104. matrix.print(socre);
  105. matrix.writeDisplay();
  106. delay(70);
  107. }

  108. s[1]=0;s[2]=2;s[3]=1;s[4]=2;s[5]=2;s[6]=2;//重置蛇的坐标
  109. }
  110. void loop() {

  111. if (Serial.available()){
  112. K=Serial.read()-48;//获得串口发送的按键信息
  113. if (K==1&&KEY!=2 ){
  114. KEY=K;
  115. }
  116. if (K==2&&KEY!=1 ){
  117. KEY=K;
  118. }
  119. if (K==3&&KEY!=4 ){
  120. KEY=K;
  121. }
  122. if (K==4&&KEY!=3 ){
  123. KEY=K;
  124. }
  125. }
  126. //重点,这里是在比对是否方向和目前蛇的行进方向相反,相反就放弃按键

  127. while(Serial.read()>=0); //清空串口缓冲区

  128. matrix.clear();
  129. if(KEY==1){
  130. s[1]=s[3];s[2]=s[4];s[3]=s[5];s[4]=s[6];s[6]=s[6]-1;
  131. }
  132. if(KEY==2){
  133. s[1]=s[3];s[2]=s[4];s[3]=s[5];s[4]=s[6];s[6]=s[6]+1;
  134. }
  135. if(KEY==3){
  136. s[1]=s[3];s[2]=s[4];s[3]=s[5];s[4]=s[6];s[5]=s[5]-1;
  137. }
  138. if(KEY==4){
  139. s[1]=s[3];s[2]=s[4];s[3]=s[5];s[4]=s[6];s[5]=s[5]+1;
  140. }
  141. //根据按键来移动蛇的身体
  142. for(int i=1;i<=6;i+=2)
  143. {
  144. matrix.drawPixel(s[i], s[i+1], 2);
  145. }
  146. matrix.writeDisplay();
  147. Delay(speedS);
  148. SX=s[5];SY=s[6]; //获取蛇头的坐标
  149. if(SY<0 or SY>7 or SX<0 or SX>7){
  150. gameover();
  151. }
  152. //判断是否超出边框,超出就跳转到GameOver
  153. if(SY==FY&&SX==FX){
  154. socre=socre+1;
  155. RANDOM();
  156. }
  157. //判断是否吃到了食物~吃到了就会加分和重新随机生成食物~
  158. speedS=speedS-int(socre/3); //根据得分加快蛇的速度
  159. }
复制代码


本帖子中包含更多资源

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

x

评分

参与人数 1 +3 收起 理由
幻生幻灭 + 3 高!

查看全部评分

回复

使用道具 举报

发表于 2013-7-21 21:03:10 | 显示全部楼层
好像很牛x的样子
回复 支持 反对

使用道具 举报

发表于 2013-7-21 21:22:30 | 显示全部楼层
霸气那,不知道有没有更多的细节。
回复 支持 反对

使用道具 举报

发表于 2013-7-21 21:28:53 | 显示全部楼层
好高级
回复 支持 反对

使用道具 举报

发表于 2013-7-22 20:21:25 | 显示全部楼层
好厉害呀呀呀呀!
回复 支持 反对

使用道具 举报

发表于 2013-7-22 20:26:33 | 显示全部楼层
很好玩的样子
回复 支持 反对

使用道具 举报

发表于 2013-7-22 21:28:43 | 显示全部楼层
大神啊!果断顶!收藏了
回复 支持 反对

使用道具 举报

发表于 2013-7-23 00:31:44 | 显示全部楼层
好多高手啊,这个也佩服啊
回复 支持 反对

使用道具 举报

发表于 2013-7-23 14:35:33 | 显示全部楼层
太牛,高手出少年。
回复 支持 反对

使用道具 举报

发表于 2013-7-23 16:44:58 | 显示全部楼层
厉害啊~~~~{:soso_e179:}
回复 支持 反对

使用道具 举报

发表于 2013-8-18 00:27:30 | 显示全部楼层
强帖必须留名
回复 支持 反对

使用道具 举报

发表于 2013-10-6 00:33:59 | 显示全部楼层
参照LZ的原理, 也写了一个 “MAX7219 8x8 LED" 贪吃蛇游戏...




  1. #include "LedControl.h"
  2. /*
  3. MAX7219 8x8 LED
  4. pin 12 is connected to the DataIn
  5. pin 11 is connected to the CLK
  6. pin 10 is connected to LOAD (CS)
  7. */

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

  9. int xValue; // JoyStick-Y
  10. int yValue; // JoyStick-X
  11. int SkValue; // JokStick-Click
  12. int Sxy[3][2]= {{2,4},{1,4},{0,4}}; //蛇身体坐标集合,一共3个点
  13. int speedS=8; //贪吃蛇的初始速度
  14. int FX,FY; //食物的坐标
  15. int SX,SY; //蛇头的坐标
  16. char KEY ='d'; // up, down, left, right
  17. int Speed =8;

  18. void setup() {
  19.         /*
  20.    The MAX72XX is in power-saving mode on startup,
  21.    we have to do a wakeup call
  22.    */
  23.         lc.shutdown(0,false);
  24.         /* Set the brightness to a medium values */
  25.         lc.setIntensity(0,2);
  26.         /* and clear the display */
  27.         lc.clearDisplay(0);

  28.         Serial.begin(9600);
  29.         delay(5000);

  30.         pinMode(9,INPUT);

  31.         //循环绘制蛇的身体,3个点
  32.         resetSnake();

  33. }

  34. void loop() {

  35.   //获得 按键信息
  36.   xValue = analogRead(A0); // JoyStick-Y
  37.   yValue = analogRead(A1); // JoyStick-X
  38.   SkValue = digitalRead(9); // JokStick-Click
  39.   
  40.    //获得的按键信息 发送串口
  41.    Serial.print("Y : ");
  42.    Serial.println(yValue);
  43.    Serial.print("X : ");
  44.    Serial.println(xValue);
  45.    Serial.print("Sk : ");
  46.    Serial.println(SkValue);

  47.    //获得 按键信息
  48.                 if(yValue>700)
  49.                 {
  50.                         KEY='r';
  51.                 }
  52.                 if(yValue<300) {
  53.                         KEY='l';
  54.                 }

  55.                 if(xValue>700)
  56.                 {
  57.                         KEY='d';
  58.                 }
  59.                 if(xValue<300) {
  60.                         KEY='u';
  61.                 }

  62.                 if(SkValue ==0)
  63.                 {
  64.                         lc.clearDisplay(0);
  65.                         resetSnake();
  66.                 }

  67.         drawSnake(LOW);

  68.         if(KEY =='u') {
  69.                         SX =Sxy[0][0]-1; // up
  70.                         SY =Sxy[0][1];
  71.                                 /* 根据按键来移动蛇的身体
  72.                                 Sxy[2][0] = Sxy[1][0];
  73.                                 Sxy[2][1] = Sxy[1][1];
  74.                                 Sxy[1][0] = Sxy[0][0];
  75.                                 Sxy[1][1] = Sxy[0][1];
  76.                                 */
  77.                         for (int i=2; i>0; i--) {
  78.                                 Sxy[i][0] = Sxy[i-1][0];
  79.                                 Sxy[i][1] = Sxy[i-1][1];
  80.                         }
  81.                         Sxy[0][0] =SX;
  82.                         Sxy[0][1] =SY;
  83.         }

  84.         if(KEY =='d') {
  85.                         SX =Sxy[0][0]+1; // down
  86.                         SY =Sxy[0][1];
  87.                         for (int i=2; i>0; i--) {
  88.                                 Sxy[i][0] = Sxy[i-1][0];
  89.                                 Sxy[i][1] = Sxy[i-1][1];
  90.                         }
  91.                         Sxy[0][0] =SX;
  92.                         Sxy[0][1] =SY;
  93.         }

  94.         if(KEY =='r') {
  95.                         SX =Sxy[0][0];
  96.                         SY =Sxy[0][1]+1; // right
  97.                         for (int i=2; i>0; i--) {
  98.                                 Sxy[i][0] = Sxy[i-1][0];
  99.                                 Sxy[i][1] = Sxy[i-1][1];
  100.                         }
  101.                         Sxy[0][0] =SX;
  102.                         Sxy[0][1] =SY;
  103.         }

  104.         if(KEY =='l') {
  105.                         SX =Sxy[0][0];
  106.                         SY =Sxy[0][1]-1; // left
  107.                         for (int i=2; i>0; i--) {
  108.                                 Sxy[i][0] = Sxy[i-1][0];
  109.                                 Sxy[i][1] = Sxy[i-1][1];
  110.                         }
  111.                         Sxy[0][0] =SX;
  112.                         Sxy[0][1] =SY;
  113.         }


  114.         //判断是否超出边框,超出就跳转到GameOver
  115.         if(SY<0 || SY>7 || SX<0 || SX>7) {
  116.                 gameover();
  117.                 resetSnake();
  118.         }

  119.         //判断是否吃到了食物~吃到就会加分和重新随机生成食物~
  120.         if(Sxy[0][0]==FX && Sxy[0][1]==FY) {
  121.                 RANDOM();
  122.                 Speed --;
  123.                 if (Speed<0) {
  124.                         Speed = 0;
  125.                 }
  126.         }

  127.         drawSnake(HIGH);
  128.         WAIT(Speed);       
  129. }


  130. // 重置蛇的坐标
  131. void resetSnake() {

  132.         int k=millis()%10 + 1;
  133.         for(int i=0; i<k; i++) {
  134.                 RANDOM(); //获取一个随机食物坐标
  135.         }

  136.         for (int i=0; i<3; i++) {
  137.                 // Sxy[3][2]= {{2,4},{1,4},{0,4}};
  138.                 Sxy[i][0] =2-i;
  139.                 Sxy[i][1] =4;
  140.         }

  141.         KEY ='d';
  142.         Speed = 8;
  143.         WAIT(5);
  144. }

  145. // 绘制蛇的函数
  146. void drawSnake(boolean OnOff) {

  147.         for (int i=0; i<3; i++) {
  148.                 lc.setLed(0,Sxy[i][0],Sxy[i][1],OnOff);
  149.         }
  150. }       

  151. //随机食物获取函数
  152. void RANDOM()
  153. {
  154.         FX=random(0, 7);
  155.         FY=random(0, 7);
  156. }

  157. //通过不断闪现食物来完成延迟,这样既可以做到精确延时,也可以让食物不断闪动
  158. void WAIT(int timeF)
  159. {
  160.         for(int t=1;t<=timeF;t++) {
  161.                 lc.setLed(0,FX,FY,HIGH);
  162.                 delay(50);
  163.                 lc.setLed(0,FX,FY,LOW);
  164.                 delay(50);
  165.         }
  166. }

  167. //GameOver函数,游戏结束
  168. void gameover()
  169. {
  170.         for (int j=0; j<10; j++) {
  171.                 drawSnake(HIGH);
  172.                 delay(250);
  173.                 drawSnake(LOW);
  174.                 delay(150);
  175.         }
  176.         delay(5000);
  177. }
复制代码

本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

发表于 2013-10-6 22:59:50 | 显示全部楼层
o(≧ o ≦)o
回复 支持 反对

使用道具 举报

发表于 2014-9-10 18:08:13 | 显示全部楼层
不错,就是这个模块有点贵啊。
回复 支持 反对

使用道具 举报

发表于 2015-4-20 17:49:58 | 显示全部楼层
谢谢分享学习一下
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-5-2 20:06 , Processed in 0.046205 second(s), 34 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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