




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、贪吃蛇C 语言.txt 这是一个禁忌相继崩溃的时代,没人拦得着你,只有你自己拦着自己,你的禁忌越多成就就越少。自卑有多种档次,最高档次的自卑表现为吹嘘自己干什么都是天才。/ 贪吃蛇游戏程序,屏左半部用于游戏活动,右半部为分数显示/游戏屏为16*16游戏点阵,可容纳蛇身块数256。每个游戏点阵又由4*4个LCD基本点阵组成/ 蛇行标志在定时器上置位,这里为游戏的主体部分。#define uchar unsigned char#define uint unsigned int#define ulong unsigned long/ 液晶数据口/ 液晶命令口#define LCMDXBYTE0xAf
2、ff#define LCMCXBYTE0xAbff#define TIME_RUN 10/ 定时器分品系数#include "study.h"#include "reg51.h"#include "absacc.h"#include "intrins.h"/ 游戏部分/x,y 最大极限#define MAX_GAME_X 15#define lcd_no_read 1 否则采用显存形式uchar snake_flag,snake_len, snake_food;#define MAX_GAME_Y 15/编译选项,
3、把这项屏蔽掉就采用LCD读出方式,/ 蛇头标志7 6 5 4 3 210/上 下 左 右 x gameover food run/ 蛇身长度/ 食物位置, 高 4 位 Y, 低 4 位 xuchar xdata snake_body256;/ 蛇身每个部分的数据/7 6 5 4 3 2 1 0/局4位Y方向低4位X方问#ifdef lcd_no_readuchar xdata lcd_buf864;/lcd/缓冲,用于记录 LCD内部的点阵,可以理解为显存当LCD无读出功能时,就要采用显示缓冲。 本LCD为可读,般不用这个功能/缓冲只记录蛇身活动的部分,即LCD左半屏#endif/*游戏LCD
4、部分,根据游戏的特点把LCD分成16*16块用作游戏点阵, */ 函数名 :clr_game_dot/ 功能 : 清一个游戏点/输入参数:游戏点的X, Y坐标/ 注 意 事 项 : 这 里 的 X , Y 坐 标 和 LCD 底 层 的 X, Y 坐 标 不 同 , 他 最 大 只 能 是 MAX_GAME_X,MAX_GAME_Y/ 使用方式: 内部调用void clr_game_dot(uchar x,uchar y)uchar lcd_x,i,tmp;while(x>MAX_GAME_X)x-=(MAX_GAME_X+1); / 这个是写程序习惯的保护措施,预防输入范围过大whil
5、e(y>MAX_GAME_Y)y-=(MAX_GAME_Y+1);lcd_x=x<<2;LCMC=lcd_x&0x0f;/ 设置 x 位置LCMC=(lcd_x>>4)|0x10;LCMC=0xb0+y/设置丫位置LCMC=0xe0;if(y%2)/ 行的下半部for(i=0;i<4;i+)/ 以下是显存法的清点程序,其他例如亮点的部分和这#ifdef lcd_no_read个原理一样tmp=lcd_bufy>>1(x<<2)+i;的数据tmp&=0x0f;LCMD=tmp;_nop_();lcd_bufy>&g
6、t;1(x<<2)+i=tmp;/先从缓冲读出要修改的LCD片/ 清对应的游戏点/ 把新数据写回缓冲#else/读LCD的方法,要求连读 2次tmp=LCMD;tmp=LCMD;LCMD=tmp&0x0f;#endifelse/ 行的上半部, 下同for(i=0;i<4;i+)#ifdef lcd_no_readtmp=lcd_bufy>>1(x<<2)+i;tmp&=0xf0;LCMD=tmp;_nop_();lcd_bufy>>1(x<<2)+i=tmp;#elsetmp=LCMD;tmp=LCMD;LCMD
7、=tmp&0xf0;#endifLCMC=0xee;/ 函数名 :fill_game_dot/ 功能 : 亮一个游戏点/输入参数:游戏坐标的X, 丫坐标/ 注 意 事 项 : 这 里 的 X, Y 坐 标 和 LCD 底 层 的X, Y 坐 标 不 同 , 他 最 大 只 能 是MAX_GAME_X,MAX_GAME_Y/这个函数和上面的 clr_game_dot基本相同,只是在写LCD数据的时彳是全1而不是0/ 使用方式: 内部调用void fill_game_dot(uchar x,uchar y)uchar lcd_x,i,tmp;while(x>MAX_GAME_X)x-
8、=(MAX_GAME_X+1);while(y>MAX_GAME_Y)y-=(MAX_GAME_Y+1);lcd_x=x<<2;LCMC=lcd_x&0x0f;/ 设置 x 位置LCMC=(lcd_x>>4)|0x10;LCMC=0xb0+y设置丫位置LCMC=0xe0;if(y%2)/ 行的下半部for(i=0;i<4;i+)#ifdef lcd_no_readtmp=lcd_bufy>>1(x<<2)+i;tmp|=0xf0;LCMD=tmp;_nop_();lcd_bufy>>1(x<<2)+i=
9、tmp;#elsetmp=LCMD;tmp=LCMD;LCMD=tmp|0xf0;#endifelsefor(i=0;i<4;i+)#ifdef lcd_no_readtmp=lcd_bufy>>1(x<<2)+i;tmp|=0x0f;LCMD=tmp;_nop_();lcd_bufy>>1(x<<2)+i=tmp;#elsetmp=LCMD;tmp=LCMD;LCMD=tmp|0x0f;#endifLCMC=0xee;/ 函数名 :fill_game_dot2/ 功能 : 亮一个游戏点( 另一种方式, 这里用来显示食物用)/ 输入参数:X
10、,Y/注意事项:X,Y为游戏的点阵,非LCD点阵 还有LCD填充数据是0x05或0x50/ 使用方式: 内部调用, 显示蛇的食物的时候用这个函数, 区分开蛇身和食物.void fill_game_dot2(uchar x,uchar y)uchar lcd_x,i,tmp;while(x>MAX_GAME_X)x-=(MAX_GAME_X+1);while(y>MAX_GAME_Y)y-=(MAX_GAME_Y+1);lcd_x=x<<2;LCMC=lcd_x&0x0f;/ 设置 x 位置LCMC=(lcd_x>>4)|0x10;LCMC=0xb0+
11、y/设置丫位置LCMC=0xe0;if(y%2)for(i=0;i<4;i+)#ifdef lcd_no_readtmp=lcd_bufy>>1(x<<2)+i;tmp|=0x50;LCMD=tmp;_nop_();lcd_bufy>>1(x<<2)+i=tmp;#elsetmp=LCMD;tmp=LCMD;LCMD=tmp|0x50;#endifelsefor(i=0;i<4;i+)#ifdef lcd_no_readtmp=lcd_bufy>>1(x<<2)+i;tmp|=0x05;LCMD=tmp;_no
12、p_();lcd_bufy>>1(x<<2)+i=tmp;#elsetmp=LCMD;tmp=LCMD;LCMD=tmp|0x05;#endifLCMC=0xee;,*游戏算法部分(4*4LCD)*/ 函数名 game_init()/ 功能 : 游戏开始的时候初始化画面的, 这里只是简单地把132*64LCD 用一条中间线划分开来/ 注意事项: 暂时在中间画条线用来划分游戏空间/ 使用方式: 内部调用,void game_init()uchar i;uchar xdata *da;for(da=0;da<0x8000;da+)/ 清空xDATA,*da=0x0;c
13、ls(9);/ 丁丁的清屏函数initlcd();for(i=0;i<8;i+)LCMC=64&0x0f;LCMC=(64>>4)|0x10;/ 线在 x=64,LCMC=0xb0+i;/y=(0-15) 的地方LCMC=0xe0;/把LCD划分,左边用来游戏LCMD=0xff;LCMC=0xee;/ 函数名 :snake_init/ 功能 : 蛇初始化/ 注意事项: 初始化只有3 节蛇身 , 向右跑/ 使用情况: 内部调用void snake_init()fill_game_dot(0,0);fill_game_dot(1,0);fill_game_dot(2,0)
14、;snake_len=2;snake_flag=0x10;snake_body0=0x02;snake_body1=0x01;/ 显示射身/ 蛇的初始化,3 个身 . 向右跑/ 装入射身数据snake_body2=0x00;/ 一开始游戏时的文字部分setcursor(8,0);lcdstring(" 分数为 :rn");setcursor(8,2);lcddigit(snake_len-2);/ 函数名 :show_mark/ 功能 : 显示当前分数, 暂时以蛇身个数为分数/ 参数说明:0, 和非 0, 0 代表游戏中的显示,!0 代表挂了的显示/ 注意事项: 调用到 L
15、CD.c 显示函数, 并需要汉字库的支持./返回值在GAMEOVER候有效,返回0退出游戏,1从新游戏/使用情况:snake_run()在蛇吃到食物的时候调用,在GAMEOVER调用 uchar show_mark(uchar mode)uchar ch;setcursor(8,0);lcdstring(" 分数为 :rn");setcursor(8,2);lcddigit(snake_len-2);if(mode)/gameover 中显示setcursor(8,0);lcddigit(snake_len-2);lcdstring("分 .");set
16、cursor(8,2);lcdstring("C退出 ");setcursor(8,4);lcdstring(" 回车继续");do ch=getkey(1000);while( (ch!='C') && (ch!='Y') );/ 游戏结束了会在这里死等,直到用户按键if(ch='Y')return(1);elsereturn(0);return(0);/ 函数名 :snake_run/ 功能 : 蛇运行函数/ 输入参数: 一个全局变量flag_snake ,蛇根据这个变量判断运动方向/
17、注意事项: 蛇跑动函数, 用于判断路径, 食物 , 长大 , 死亡/ 使用情况: 内部调用void snake_run()uchar tmp_head_x,tmp_head_y;uchar i;switch(snake_flag&0xf0)/ 取蛇头方向case 0x80:/ 向上走 y-tmp_head_x=snake_body0&0x0f;tmp_head_y=(snake_body0>>4);if(tmp_head_y=0)snake_flag|=0x04;/ 这 个 代 表 撞 墙 了 , 就 置 GAMEOVER志,下同else tmp_head_y-;b
18、reak;case 0x40:/ 向下走 y+tmp_head_x=snake_body0&0x0f;tmp_head_y=(snake_body0>>4);if(tmp_head_y=MAX_GAME_Y)snake_flag|=0x04;else tmp_head_y+;break;case 0x20:/ 向左走 x-tmp_head_y=snake_body0>>4;tmp_head_x=snake_body0&0x0f;if(tmp_head_x=0)snake_flag|=0x04;else tmp_head_x-;break;case 0x1
19、0:/ 向右走 x+tmp_head_y=snake_body0>>4;tmp_head_x=snake_body0&0x0f;if(tmp_head_x=MAX_GAME_X)snake_flag|=0x04;else tmp_head_x+;break;default:break;if(!(snake_flag&0x04)/ 如果在之前没有撞墙,就可以进行下一步判断/ 以下是得到食物的判断。蛇头和食物坐标没重叠if(snake_food!=( (tmp_head_y<<4)+tmp_head_x )/就代表没有吃到食物/ 得不到食物的处理clr_ga
20、me_dot(snake_bodysnake_len&0x0f,snake_bodysnake_len>>4);/灭蛇尾巴for(i=snake_len;i>0;i-)/ 柔体传动snake_bodyi=snake_bodyi-1;snake_body0=( tmp_head_y<<4 ) + tmp_head_x;else/ 得到食物的处理snake_bodysnake_len+1=snake_bodysnake_len;/ 保留蛇尾巴(这是增长型柔体传动)for(i=snake_len;i>0;i-)snake_bodyi=snake_bodyi
21、-1;snake_body0=( tmp_head_y<<4 ) + tmp_head_x;/ 新蛇头 snake_len+;/ 长度增加1snake_flag&=0x02;/ 清食物标志 show_mark(0);/ 显示分数 fill_game_dot(tmp_head_x,tmp_head_y);/ 显示新蛇头for(i=1;i<snake_len+1;i+)/ 判断是否撞中自己if(snake_body0=snake_bodyi)snake_flag|=0x04;/ 撞中了就置 GAMEOVER志break;/ 函数名 :set_food/ 功能 : 放食物/
22、 注意事项: 这个函数在被调用前会先判断是否需要放食物,/这里用自己编写的随机数来产生食物, 随机数和蛇身位置, 定时器有关/每次放食物的时候必须先判断是否和蛇身重叠了, 重叠了要重新放/这里设定了如果蛇长度达到某值了就不再放食物./ 影响变量:snake_food/ 使用情况: 内部调用void set_food()uchar seed0,seed1,i=0;seed0=snake_bodysnake_len-2;if(snake_len=250)return;/ 蛇都快满屏了,就不放食物了, 事实上我还没玩过超过100 的呢 :) seed0=(seed1>>3)*4+seed
23、0+TL0);/ 随机数的生成, 其实乱做就可以了:)seed1=(snake_body0>>4)+seed0;snake_food=(seed1+seed0*3);food:for(i=0;i<snake_len+1;i+) / 食物不能和蛇身重叠if( snake_bodyi=snake_food )snake_food=(snake_food+0x01);/ 如果重叠了,位置就+1,然后goto food;/ 重新比较, 这里可以换成i=255, 效果一样fill_game_dot2(snake_food&0x0f,snake_food>>4);/
24、放食物snake_flag|=0x02;/ 置有食物标志/ 函数名 : 定时器 1 初始化程序/ 晶振 22.1184 ,定时时间35MSvoid timer0_init(void)TMOD=0x1;TH0=0x0;TL0=0x0;/ 函数名 :snake_game/ 功能 : 整个游戏的主要函数/ 注意事项: 游戏利用了定时器产生蛇的运行速速度/调用前应该先初始化定时器/ 使用情况: 外部调用/extern uchar time_service;/ 这个东东是使定时器公用的。void snake_game()uchar tmp_snake_flag,ch;cls(8);time_servic
25、e=1;lcdstring(" 贪吃蛇游戏rnC 退出 , 任意键进入rn 游戏说明:rn2: 上 5: 下 4: 左 6: 右");while(ch=getkey(1000)=0);if(ch='C') return;ch=0;begin_game:game_init(); / 一堆初始化snake_init();timer0_init();TR0=1;ET0=1;EA=1;tmp_snake_flag=snake_flag;while(1)ch=getkey(1000);switch(ch)case '2':/ 按了上按键if( (snake_flag&0x40) | (snake_flag
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安徽省滁州市来安县第三中学2026届化学高一第一学期期末考试模拟试题含解析
- 供应商促销活动策划方案
- 绿化植树活动方案
- 山东生理学试题及答案
- 家电公司采购付款管理规章
- 超市收货员试题及答案
- 插班面试题问题及答案
- 渣女测试试题及答案
- 心理健康咨询师考试试题及答案
- 焊接材料考试题及答案
- 全套ISO45001职业健康安全管理体系文件(手册及程序文件)
- 《沙盘模拟课程》课件
- JT-T-1094-2016营运客车安全技术条件
- 2024年陕西宝鸡市市级机关及其直属机构遴选公务员及选聘事业人员39人重点基础提升难、易点模拟试题(共500题)附带答案详解
- 静脉输血并发症预防及处理
- 物业设施设备管理指南
- EPC项目质量控制目标及分解
- 《高温熔融金属吊运安全规程》(AQ7011-2018)
- 铁道工程技术专业调研报告
- 面点师简历模板
- 超详细展览会、展会期间事项推进表
评论
0/150
提交评论