[应用方案] 光立方实现3D贪吃蛇

[复制链接]
2033|3
 楼主| Roderman_z 发表于 2016-4-11 11:08 | 显示全部楼层 |阅读模式
这段代码是贪吃蛇的核心代码,一般贪吃蛇只有4个方向,这个是6个方向也就是3D的。
蛇能自己移动,用函数Snake_Move和Change_Direction实现。
我使用的是STC12C5A60S2,所以要更改的,只有以LED开头的函数
只要能实现一个点亮指定位置(x,y,z)灯的函数Led_Set_Bit
  1. /******************************************************************************
  2. * 文    件: Snake.c
  3. * 作    者: ZhnJa  
  4. * 修改日期: 2013-7-10
  5. * 说    明: 贪吃蛇相关
  6. ******************************************************************************/  
  7. #include "MyType.h"  
  8. #include "LED_CMD.H"  
  9. #include "snake.h"  
  10. #include "STC12C5A60S2.h"  
  11. #include <stdlib.h>  

  12. #define WidthMax  4  //蛇最寸高度  
  13. #define HeightMax 4  //蛇最大长度  
  14. #define LengthMax 4  //蛇最大长度  
  15. #define MaxLength 20 //总长度  

  16. #define Up 6  
  17. #define Down 5  
  18. #define Left 4  
  19. #define Right 3  
  20. #define For 2  
  21. #define Rea 1  

  22. typedef struct _Food  //食物结构体  
  23. {  
  24.    uchar x;/*食物的横坐标*/  
  25.    uchar y;/*实物的纵坐标*/  
  26.      uchar z;/*实物的z坐标*/  
  27.    uchar yes;/*是否出现食物的标志,0表示未产生,1表示产生*/  
  28. }Food;/*食物*/  

  29. typedef struct _Point //点结构体  
  30. {  
  31.   uchar x;  
  32.   uchar y;  
  33.     uchar z;  
  34. }Point;  

  35. typedef struct _Snake  
  36. {  
  37.    uchar x[MaxLength]; //蛇身节点的横坐标  
  38.    uchar y[MaxLength]; //蛇身节点的纵坐标  
  39.      uchar z[MaxLength]; //蛇节点  
  40.    uchar node;/*蛇长度*/  
  41.    uchar direction;/*蛇移动方向*/  
  42.    uchar life;/*蛇是否存活标志,0死亡,1存活,2表示暂停*/  
  43. }Snake;  

  44. xdata Snake snake={{1,2,3},{1,1,1},{1,1,1},3,Up,1};  
  45. xdata Food food={1,4,4};    //食物  
  46. Point TailPoint;//存放蛇尾巴节点的临时变量  
  47. Point NextPoint;//存放蛇下一次移动的位置  

  48. /********************************************
  49. *                           蛇初始化
  50. *参数:
  51. *功能:
  52. *********************************************/  
  53. void Init_Snake()  
  54. {  
  55.     unsigned char i;  
  56.     for(i=0;i<=2;i++)  
  57.     LED_Set_Bit(snake.x[i],snake.y[i],snake.z[i]);  
  58.     LED_Set_Bit(food.x,food.y,food.z);  
  59. }  
  60. /********************************************
  61. *                           蛇移动函数
  62. *参数:无
  63. *功能:删除最后一个节点,点亮下一个节点
  64. *********************************************/  
  65. uchar Snake_Move()  
  66. {  
  67.     uchar i;  
  68.     TailPoint.x=snake.x[0]; //保存蛇尾  
  69.     TailPoint.y=snake.y[0];  
  70.     TailPoint.z=snake.z[0];  

  71.   for(i=0;i<snake.node-1;i++)    //依次向尾部方向移动蛇各个节点的坐标  
  72.   {  
  73.         snake.x[i]=snake.x[i+1];  
  74.         snake.y[i]=snake.y[i+1];  
  75.         snake.z[i]=snake.z[i+1];  
  76.     }     
  77.     switch(snake.direction)  
  78.     {  
  79.         case Up:{snake.z[snake.node-1]+=1;break;}  
  80.         case Down:{snake.z[snake.node-1]-=1;break;}  
  81.         case Left:{snake.x[snake.node-1]-=1;break;}  
  82.         case Right:{snake.x[snake.node-1]+=1;break;}  
  83.         case For:{snake.y[snake.node-1]+=1;break;}  
  84.         case Rea:{snake.y[snake.node-1]-=1;break;}  
  85.     }  

  86.     LED_Reset_Bit(TailPoint.x,TailPoint.y,TailPoint.z);  
  87.     LED_Set_Bit(snake.x[snake.node-1],snake.y[snake.node-1],snake.z[snake.node-1]);  
  88.     return 1;  
  89. }  


 楼主| Roderman_z 发表于 2016-4-11 11:09 | 显示全部楼层
  1. bit IsLive()  
  2. {  
  3.     uchar i=0;  
  4.     //计算下一个点  
  5.     NextPoint.x=snake.x[snake.node-1];  
  6.     NextPoint.y=snake.y[snake.node-1];  
  7.     NextPoint.z=snake.z[snake.node-1];  
  8.     switch(snake.direction)  
  9.     {  
  10.         case Up:{NextPoint.z+=1;break;}  
  11.         case Down:{NextPoint.z-=1;break;}  
  12.         case Left:{NextPoint.x-=1;break;}  
  13.         case Right:{NextPoint.x+=1;break;}  
  14.         case For:{NextPoint.y+=1;break;}  
  15.         case Rea:{NextPoint.y-=1;break;}  
  16.     }  

  17.     //判断蛇有没有撞到自身  
  18.     for(i=0;i<=snake.node-1;i++)  
  19.   {  
  20.         if((snake.x[i]==NextPoint.x)&&(snake.y[i]==NextPoint.y)&&(snake.z[i]==NextPoint.z))  
  21.         {  
  22.            snake.life=0;  
  23.              return 0;  
  24.              break;  
  25.         }  
  26.     }  
  27.         //判断蛇有没有撞到墙  
  28.     if(NextPoint.x>=1&&NextPoint.x<=4  
  29.         &&NextPoint.y>=1&&NextPoint.y<=4  
  30.         &&NextPoint.z>=1&&NextPoint.z<=4)  
  31.         return 1;                 
  32.   else   
  33.   {  
  34.    snake.life=0;  
  35.    return 0;  
  36.   }  
  37. }  

  38. bit Change_Direction()  
  39. {  
  40.     uchar olddir=snake.direction;     
  41.     if(snake.x[snake.node-1] < food.x)  
  42.             snake.direction = Right;  
  43.         else if(snake.x[snake.node-1] > food.x)  
  44.                 snake.direction = Left;  
  45.         else if(snake.y[snake.node-1] <food.y)  
  46.             snake.direction = For;  
  47.         else if(snake.y[snake.node-1] > food.y)  
  48.             snake.direction = Rea;  
  49.         else if(snake.z[snake.node-1] > food.z)  
  50.             snake.direction = Down;  
  51.         else if(snake.z[snake.node-1] < food.z)  
  52.             snake.direction = Up;         
  53.         return 1;  
  54. }  

  55. //功能:吃食并且产生下一个实物的坐标  
  56. //返回值:1表示吃到食物,0表示未吃到食物  
  57. bit EatFood(void)  
  58. {  
  59.     uchar i;  
  60.    if(((snake.x[snake.node-1])==food.x)&&((snake.y[snake.node-1])==food.y)&&(snake.z[snake.node-1]==food.z))    //如果吃到食物  
  61.      {  
  62.         for(i=snake.node;i>0;i--)  //依次向头部方向移动蛇各个节点的坐标  
  63.         {  
  64.           snake.x[i]=snake.x[i-1];  
  65.           snake.y[i]=snake.y[i-1];  
  66.             snake.z[i]=snake.z[i-1];  
  67.         }  
  68.         snake.x[0]=TailPoint.x;  //恢复尾巴坐标  
  69.         snake.y[0]=TailPoint.y;  
  70.         snake.z[0]=TailPoint.z;  

  71.         snake.node++;    //节点个数加1  
  72.     //以下程序段为产生食物  
  73.         do  
  74.         {  
  75.           food.yes=1;//实物产生标志置1  
  76.           GetNewFoodLoc(&food.x,&food.y,&food.z);//随机产生新的食物的坐标  
  77.           for(i=0;i<snake.node-1;i++)  
  78.           {  
  79.             if((snake.x[i])==food.x&&((snake.y[i])==food.y)&&(snake.z[i]==food.z)) //判断食物出现的位置是否在蛇身上  
  80.             {  
  81.               food.yes=0; //食物产生标志置0  
  82.               break;  
  83.              }  
  84.           }  
  85.         }while(!food.yes);//直到产生的食物不在蛇身上为止  
  86.         LED_Set_Bit(food.x,food.y,food.z);//产生新的食物  
  87.         return 1;  
  88.      }  
  89.      return 0;  
  90. }  

  91. //读取定时器的随机值来获得食物坐标,同时不能越界  
  92. void GetNewFoodLoc(uchar *x,uchar *y,uchar *z)  
  93. {     
  94.    *x=TH0%4+1;     
  95.    *y=TL0%4+1;  
  96.      *z=(TL0+TH0)%4+1;  
  97. }  

  98. void Change_Direction2()  
  99. {  
  100.     uchar olddir=snake.direction;     
  101.     do{  
  102.         snake.direction=rand()%6+1;  
  103.         }  
  104.     while(snake.direction == olddir);  
  105. }  
  106. //表示食物的LED灯闪烁  
  107. void Shine_Food()  
  108. {  
  109.     LED_Shine(food.x,food.y,food.z);  
  110. }  

指定位置灭LED灯Led_Reset_Bit 以及 让LED闪烁的函数LED_Shine 即可。
DreamofOven 发表于 2016-4-11 15:14 | 显示全部楼层
贪吃蛇、乒乓球游戏是最经典的单片机游戏设计了
_寒寒_ 发表于 2016-4-12 16:48 | 显示全部楼层
来个视频呀
您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

354

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部