找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2641|回复: 0
收起左侧

基于STC15单片机+OLED的贪吃蛇大作战程序 原理图与PCB文件

[复制链接]
ID:677834 发表于 2021-12-13 16:56 | 显示全部楼层 |阅读模式
基于STC15408AS的贪吃蛇游戏程序与硬件设计
制作出来的实物图如下:

实物图

实物图

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
51hei.png

贪吃蛇PCB设计

贪吃蛇PCB设计

贪吃蛇原理图设计

贪吃蛇原理图设计
51hei图片20211213165518.png

单片机源程序如下:
  1. #include "snake.h"
  2. #include "oled.h"
  3. #include "adc.h"
  4. #include "stdlib.h"
  5. #include "timer.h"
  6. int snake_Grid[32][2];//蛇身的存储数组,snake_Grid[][0]代表x坐标,snake_Grid[][1]代表y坐标
  7. extern u8 if_end;
  8. u8 snake_length = 5;//蛇身初始长度
  9. unsigned char squre[8]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  10. void snake_delay_ms(int ms)                //延时函数
  11. {
  12.         unsigned char i, j;
  13. while(ms--)
  14. {
  15.         _nop_();
  16.         _nop_();
  17.         _nop_();
  18.         i = 11;
  19.         j = 190;
  20.         do
  21.         {
  22.                 while (--j);
  23.         } while (--i);
  24.   }
  25. }

  26. void Draw_squre(unsigned char x,unsigned char y)//画方块,即地图显示部分
  27. {
  28.    u8 i;
  29.    OLED_Set_Pos(x*8,y);
  30.    for(i=0;i<8;i++)
  31.    {
  32.       OLED_WR_Byte(squre[i],OLED_DATA);
  33.    }
  34. }
  35. void Draw_Map()//画地图
  36. {  
  37.         u8 i;
  38.         for(i=0;i<15;i++)
  39.         {
  40.   Draw_squre(i,0);
  41.         Draw_squre(i,7);
  42.         }
  43.         for(i=0;i<8;i++)
  44.         {
  45.         Draw_squre(0,i);
  46.         Draw_squre(15,i);
  47.         }
  48. }
  49. unsigned char snake_head[8] = {0xFF,0x9F,0x9D,0xFD,0xFD,0x9D,0x9F,0xFF};
  50. void Draw_Head(unsigned char x,unsigned char y)//画蛇头函数
  51. {
  52.          u8 i;
  53.    OLED_Set_Pos(x*8,y);
  54.    for(i=7;i>0;i--)
  55.    {
  56.       OLED_WR_Byte(snake_head[i],OLED_DATA);
  57.    }
  58. }
  59. u8 Direction = 0;
  60. Coordinate old1 = {0};
  61. Coordinate old2 = {0};
  62. Coordinate snake_food = {1,1};
  63. Coordinate snake_body = {0,0};
  64. void Check_KEY()//摇杆检测函数
  65. {
  66.         int x_value,y_value;
  67.         x_value = Get_ADC10bitResult(0);
  68.         y_value = Get_ADC10bitResult(1);
  69.   if(x_value<30&&Direction!=Left_Direction)Direction = Right_Direction;
  70.   if(x_value>1000&&Direction!=Right_Direction)Direction = Left_Direction;
  71.   if(y_value>1000&&Direction!=Up_Direction)Direction = Down_Direction;
  72.         if(y_value<30&&Direction!=Down_Direction)Direction = Up_Direction;
  73. }
  74. void Record_Coordinate()//记录上一次的坐标
  75. {
  76.         old1.x = snake_Grid[0][0];
  77.         old1.y = snake_Grid[0][1];
  78.         old2.x = snake_Grid[snake_length-1][0];
  79.         old2.y = snake_Grid[snake_length-1][1];
  80. }
  81. int score = 0;
  82. void Check_State()//检测蛇的状态
  83. {
  84.         u8 i;
  85.         snake_body.x = snake_Grid[0][0];
  86.         snake_body.y = snake_Grid[0][1];
  87.   if(snake_Grid[0][0]==snake_food.x&&snake_Grid[0][1]==snake_food.y)//当食物的坐标和蛇头一致则记录一次
  88.         {
  89.                 score++;
  90.                 snake_food.x = rand()%14+1;
  91.                 snake_food.y = rand()%6+1;
  92.                 snake_length++;
  93.                 Rrfresh_Body(snake_food.x,snake_food.y);
  94.                 Draw_Food(snake_food.x,snake_food.y);
  95.                
  96.         }
  97.         for(i=1;i<snake_length-1;i++)
  98.            if(snake_body.x==snake_Grid[i][0]&&snake_body.y==snake_Grid[i][1])
  99.                          if_end = 1;
  100.         for(i=0;i<snake_length-1;i++)
  101.          while(snake_Grid[0][0]==snake_food.x&&snake_Grid[0][1]==snake_food.y)
  102.                 {
  103.                 snake_food.x = rand()%13+1;//随机生成食物
  104.                 snake_food.y = rand()%6+1;

  105.                 }
  106. }
  107. unsigned char food[8] = {0xFF,0xFF,0xC3,0xDB,0xDB,0xC3,0xFF,0xFF,};
  108. void Draw_Food(unsigned char x,unsigned char y)//画食物
  109. {
  110.    u8 i;
  111.    OLED_Set_Pos(x*8,y);
  112.    for(i=0;i<8;i++)
  113.    {
  114.       OLED_WR_Byte(food[i],OLED_DATA);
  115.    }
  116. }

  117. void Snake_Move()//移动函数
  118. {
  119.         u8 i;
  120.         Check_State();
  121.   for(i=snake_length-1;i>0;i--)
  122.         {
  123.           snake_Grid[i][0] = snake_Grid[i-1][0];
  124.                 snake_Grid[i][1] = snake_Grid[i-1][1];
  125.         }
  126.         switch(Direction)
  127.         {
  128.          case Right_Direction:
  129.          Record_Coordinate();
  130.          snake_Grid[0][0]++;
  131.          Rrfresh_Body(old1.x,old1.y);
  132.          Rrfresh_Body(old2.x,old2.y);
  133.          if(snake_Grid[0][0]>15)
  134.          {
  135.           if_end = 1;
  136.                 OLED_Clear();
  137.          }
  138.                 break;
  139.          case Left_Direction:
  140.          Record_Coordinate();
  141.          snake_Grid[0][0]--;
  142.          Rrfresh_Body(old1.x,old1.y);
  143.          Rrfresh_Body(old2.x,old2.y);
  144.          if(snake_Grid[0][0]<=0)
  145.          {
  146.                  if_end = 1;
  147.                  OLED_Clear();
  148.          }
  149.                 break;
  150.          case Up_Direction:
  151.          Record_Coordinate();
  152.          snake_Grid[0][1]--;
  153.          Rrfresh_Body(old1.x,old1.y);
  154.          Rrfresh_Body(old2.x,old2.y);
  155.          if(snake_Grid[0][1]<=0)
  156.          {
  157.                  if_end = 1;
  158.                          OLED_Clear();
  159.          }
  160.                 break;
  161.          case Down_Direction:
  162.          Record_Coordinate();
  163.          snake_Grid[0][1]++;
  164.          Rrfresh_Body(old1.x,old1.y);
  165.          Rrfresh_Body(old2.x,old2.y);
  166.          if(snake_Grid[0][1]>7)
  167.          {
  168.                  if_end = 1;
  169.                  OLED_Clear();
  170.          }
  171.                 break;
  172.         }

  173. }
  174. void Draw_Start_Interface()//开始界面的绘制
  175. {
  176.         u8 i;
  177.         for(i=0;i<6;i++)
  178.         {
  179.         OLED_ShowCHinese(16+i*16,3,i+4);
  180.         OLED_ShowCHinese(16+i*16,5,i+10);
  181.         }
  182.         snake_delay_ms(500);
  183.         OLED_Clear();
  184. }
  185. int snake_sum = 3;
  186. void Snake_Init()//初始化蛇
  187. {
  188.         u8 i;
  189.   snake_Grid[0][0] = 5;//身体为5
  190.         snake_Grid[0][1] = 5;
  191.   Draw_Start_Interface();
  192.         while(snake_sum)//加载界面
  193.         {
  194.                 snake_sum--;
  195.                 for(i=0;i<3;i++)
  196.         {
  197.         OLED_ShowCHinese(16+i*16,3,i+16);
  198.         }
  199.         for(i=0;i<3;i++)
  200.         {
  201.         OLED_ShowString(64+i*16,3,".");
  202.         snake_delay_ms(500);
  203.         }
  204.         OLED_Clear();
  205.   }
  206.         OLED_Clear();
  207.         Draw_Food(snake_food.x,snake_food.y);
  208.         Draw_Map();
  209.   for(i = snake_length-1;i>0;i--)
  210.         {
  211.           snake_Grid[i][0] = snake_Grid[0][0]-i;
  212.                 snake_Grid[i][1] = snake_Grid[0][1];
  213.         }
  214.         LED1 = 0;
  215.         LED2 = 0;
  216.         LED3 = 0;
  217. }
  218. const unsigned char code body[8]={0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xFF,0xFF};
  219. void Draw_Body(unsigned char x,unsigned char y)//画身体
  220. {
  221.    u8 i;
  222.    OLED_Set_Pos(x*8,y);
  223.    for(i=0;i<8;i++)
  224.    {
  225.       OLED_WR_Byte(body[i],OLED_DATA);
  226.    }
  227. }
  228. void Rrfresh_Body(unsigned char x,unsigned char y)//刷新身体
  229. {
  230.    u8 i;
  231.    OLED_Set_Pos(x*8,y);
  232.    for(i=0;i<8;i++)
  233.    {
  234.       OLED_WR_Byte(0,OLED_DATA);
  235.    }
  236. }
  237. void Game_if_continue()//游戏是否继续
  238. {

  239.         Direction = 5;
  240.         Check_KEY();
  241.   switch(Direction)
  242.         {
  243.           case Left_Direction:
  244.     Continue_Game();
  245.                 Direction = Right_Direction;
  246.                 snake_Grid[0][0] = 5;
  247.                 snake_Grid[0][1] = 5;
  248.                 Draw_Map();
  249.                 snake_food.x = 1;
  250.                 snake_food.y = 1;
  251.                 score = 0;
  252.                 Draw_Food(snake_food.x,snake_food.y);
  253.                 break;
  254.                 case Right_Direction:
  255.                 End_Game();
  256.     break;
  257.         }
  258. }
  259. void Continue_Game()//继续游戏
  260. {
  261.           if_end = 0;
  262.    snake_length = 5;
  263.          OLED_Clear();
  264. }
  265. void End_Game()//结束游戏
  266. {
  267.           static u8 n = 1;
  268.          if(n)
  269.          {
  270.                  n = 0;
  271.          OLED_Clear();
  272.          }
  273.    OLED_ShowString(0,3,"Thank you for your help",16);
  274.          while(1);
  275. }
复制代码

所有资料51hei附件下载:
贪吃蛇代码及pcB.7z (3.16 MB, 下载次数: 36)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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