找回密码
 注册

QQ登录

只需一步,快速开始

搜索

51单片机LCD12864液晶贪吃蛇游戏代码和Proteus仿真

[复制链接]
eng 发表于 2021-6-14 03:42:20 | 显示全部楼层 |阅读模式
51单片机+12864液晶的贪吃蛇游戏机的详细资料。仿真实物都做过,效果比较满意。花的精力也比较多,代码也全都是自己一行一行的写下来。所以做完之后想把这些东西都整理一下,方便后面要做这些东西的人。
完整单片机c源码和proteus仿真文件:
51单片机 12864液晶贪吃蛇游戏机(完美版).zip (170.69 KB, 售价: 5 E币)
环境: keil V4.02    protues version 7.5
这个东西最主要的几块。
1.单片机用的是stc的,51内核,你首先要会这个···
2.用状态机实现按键。这个里面有别人写的技术帖子··
3.液晶是12864,2种控制器都做过,一个控制器是ST7920带字库的,一个控制器是KS0108不带字库的。2个的英文资料我都放在里面了。首先得弄懂液晶要怎么样和单片机连接。
要在液晶上面做游戏,推荐先看英文资料,一定要看英文,研究液晶读写时序和初始化方法,然后找别人的程序,实现液晶的基本操作,画点,写汉字什么的,读液晶···然后自己写程序实现液晶的所有基本操作。这样才能对液晶有充分的认识,才能开始在上面做游戏。有了这个基础,以后学别的液晶也会快的多。
4.菜单,游戏少不了要用到菜单,比如选择难度,选择地图什么的。我里面放了一个别人的论文,看了之后应该就会自己写了。(注意论文里面讲的是用函数指针实现菜单,但是KEIL这个环境下用51函数指针会很困难,推荐像我那样直接传菜单号)
5.贪吃蛇游戏,推荐先不要看别人的程序,自己在电脑上面下个贪吃蛇游戏,玩的时候就观察贪吃蛇游戏的特征···比如蛇在怎么动,蛇要怎么描述,是每个点都描述还是只要蛇头蛇尾···蛇转弯的时候怎么写?  对于上面的问题,可以参考别人的程序,然后就开始动手画图什么的表示出来这些过程,一个功能一个功能逐一实现。(推荐看带字库的那个程序,那个程序代码是最终优化版本。思路很清晰···)
6.液晶的动画,动画实际上就是图片一张一张的显示,我在里面放了一个把彩色照片黑白二值化的工具,可以找到自己喜欢的GIF动画,用提取工具把照片一张一张提取出来,然后黑白二值化,然后取模工具取模,然后实现···虽然过程蛮枯燥,但是效果还不过,也可以学到不少东西。
最后希望大家在看这个的时候,特别是贪吃蛇游戏实现的时候,哪一个方面有更好的办法一定通知我,因为我觉得我实现贪吃蛇游戏的方法已经很不错了。如果能有更好的,我会非常希望学习下····

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
1.png
部分源码:完整源码见附件
  1. struct loop_queue  //利用数组实现循环队列,拐点不会超过15个。所以大小选15足以。
  2. {   
  3.         unsigned int front;
  4.         unsigned int rear;
  5.         unsigned int count;
  6.         struct she dat[num];
  7. };
  8. //不熟悉数组实现循环队列的可以在纸上画一下操作过程

  9. struct she tou,wei,food; //蛇的头尾节点  和食物点
  10. struct loop_queue queue;//循环队列  蛇转弯则形成拐点 将拐点入队列  尾巴到达拐点则拐点出队列

  11. unsigned char flag_exit_game; //返回标志  为1时  从贪吃蛇游戏返回菜单
  12. unsigned char flag_game_over; //结束标志  为1时  显示游戏结束画面 同时使返回标志为1
  13. unsigned char tcs_key_flag;  //贪吃蛇在一次移动中   只允许捕获一次按键  也就是只能产生一个拐点
  14. unsigned char tcs_key_state; //用于按键状态机的实现
  15. unsigned int  tcs_df;  //贪吃蛇得分
  16. unsigned char tcs_stop;//贪吃蛇暂定功能的实现

  17. unsigned char tcs_nd;  //贪吃蛇难度的选择
  18. unsigned char tcs_dt;  //贪吃蛇地图的选择 这2个是全局变量  在menu里面要用到


  19. void tcs_bianjie(unsigned int he);//贪吃蛇游戏地图的实现和边界
  20. void timer0_initial();
  21. void timer1_initial();

  22. //循环队列的基本操作
  23. void queue_initial(struct loop_queue *q);  
  24. void queue_in(struct loop_queue *q,struct she h)  ;
  25. struct she queue_out(struct loop_queue *q)  ;

  26. void tcs_game_initial();
  27. void food_produce();

  28. void tcs_game()
  29. {
  30.         struct she check;  //用与暂存蛇即将移动的点  从而进行判断
  31.         unsigned int he;
  32.         unsigned char flag;//flag作为吃到食物的标志

  33.         flag_exit_game=0;
  34.         flag_game_over=0;
  35.         tcs_key_state=0;
  36.         tcs_df=0;
  37.         tcs_stop=1;

  38. //        draw_lcd_picture(&tcs_picture[0]); //贪吃蛇游戏画面
  39. //        delay_ms(2000);

  40.         tcs_bianjie(tcs_dt); //贪吃蛇游戏边界
  41.         tcs_game_initial();//贪吃蛇初始化  主要是设定蛇头蛇尾  并显示蛇
  42.         timer0_initial(); //定时器0工作在方式2  8位自动装初值  只计数不中断 用来产生随机数
  43.         timer1_initial(); //定时器1工作在方式1        16位     10ms中断一次扫描键盘

  44.         do
  45.         {
  46.                 food_produce();//产生一个随机数 即随即产生x y value3个值确定一个点为食物
  47.                 he=test_point_exist(food.x,food.y,food.value);//检测产生的点的地方是否已经有点存在
  48.         }
  49.         while(he==food.value);//如果随机数产生在蛇的身体以及边界上 则重新再产生一个  
  50.         draw_lcd_point(food.x,food.y,food.value);//显示食物 先读取这个点所在xy的情况 以免破坏现场
  51.         
  52.         queue_initial(&queue);//初始化循环队列  使队列空  front rear 即头尾指针为0

  53.         while(1)
  54.         {
  55.                 if(flag_exit_game==1)//如果游戏过程中按下返回键  则立即结束游戏  返回菜单
  56.                         break;
  57.                 if(flag_game_over==1)//如果游戏过程中蛇死了  则立即结束游戏 显示结束动画 按键后返回菜单
  58.                         break;
  59.                
  60.                 ET1=1;   //允许扫描按键          贪吃蛇游戏难度决定蛇2次移动之间的间隔时间  也就是检测按键的时间
  61.                 tcs_key_flag=0; //允许捕获按键  在检测按键时间内  只允许生产一个拐点  即捕获到一个有效的
  62.                                                 //按键以后  就置一这个变量 不允许再增加拐点
  63.                 while(tcs_stop==0);//暂定键按下会取反tcs_stop的值  从而实现暂停功能
  64.                 switch(tcs_nd)
  65.                 {
  66.                         case 0:  {delay_ms(10); break;}//0代表变态难度  蛇的2次移动之间只有10ms的机会检测键盘按下
  67.                         case 1:  {delay_ms(50); break;}//难度减小  2次移动间隔增加
  68.                         case 2:  {delay_ms(100); break;}
  69.                 }
  70.                 ET1=0;

  71.                 switch(tou.direction)//这个switch用来根据蛇头的x y value值以及当前蛇头移动的方向
  72.                                                          //取出蛇头要到达的下一个点  存入check中  来判断是否撞墙 吃到食物 什么的···
  73.                 {        
  74.                         case 0: {         
  75.                                                 check.y=tou.y;
  76.                                                 if(tou.value==0x0001)//x的值要发生改变
  77.                                                 {
  78.                                                         if(tou.x==3)//蛇碰到上屏幕的右边界  则回到左边界
  79.                                                                 check.x=0;
  80.                                                         else if(tou.x==11)//蛇碰到下屏幕的右边界  则回到左边界
复制代码

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

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-4-27 09:34

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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