贪吃蛇C语言txt这是一个禁忌相继崩溃的时代没人拦得着.docx
- 文档编号:24771176
- 上传时间:2023-06-01
- 格式:DOCX
- 页数:20
- 大小:20.20KB
贪吃蛇C语言txt这是一个禁忌相继崩溃的时代没人拦得着.docx
《贪吃蛇C语言txt这是一个禁忌相继崩溃的时代没人拦得着.docx》由会员分享,可在线阅读,更多相关《贪吃蛇C语言txt这是一个禁忌相继崩溃的时代没人拦得着.docx(20页珍藏版)》请在冰豆网上搜索。
贪吃蛇C语言txt这是一个禁忌相继崩溃的时代没人拦得着
贪吃蛇C语言.txt这是一个禁忌相继崩溃的时代,没人拦得着你,只有你自己拦着自己,你的禁忌越多成就就越少。
自卑有多种档次,最高档次的自卑表现为吹嘘自己干什么都是天才。
//贪吃蛇游戏程序,屏左半部用于游戏活动,右半部为分数显示
//游戏屏为16*16游戏点阵,可容纳蛇身块数256。
每个游戏点阵又由4*4个LCD基本点阵组成
//蛇行标志在定时器上置位,这里为游戏的主体部分。
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
#defineLCMDXBYTE[0xAfff]//液晶数据口
#defineLCMCXBYTE[0xAbff]//液晶命令口
#defineTIME_RUN10//定时器分品系数
#include"study.h"
#include"reg51.h"
#include"absacc.h"
#include"intrins.h"
//游戏部分
//x,y最大极限
#defineMAX_GAME_X15
#defineMAX_GAME_Y15
#definelcd_no_read1//编译选项,把这项屏蔽掉就采用LCD读出方式,否则采用显存形式
ucharsnake_flag,//蛇头标志76543210
//上下左右xgameoverfoodrun
snake_len,//蛇身长度
snake_food;//食物位置,高4位Y,低4位x
ucharxdatasnake_body[256];//蛇身每个部分的数据
//76543210
//高4位Y方向低4位X方向
#ifdeflcd_no_read
ucharxdatalcd_buf[8][64];//lcd缓冲,用于记录LCD内部的点阵,可以理解为显存
//当LCD无读出功能时,就要采用显示缓冲。
本LCD为可读,一般不用这个功能
//缓冲只记录蛇身活动的部分,即LCD左半屏
#endif
/******************************************************
*游戏LCD部分,根据游戏的特点把LCD分成16*16块
*用作游戏点阵,
*******************************************************/
//
//函数名:
clr_game_dot
//功能:
清一个游戏点
//输入参数:
游戏点的X,Y坐标
//注意事项:
这里的X,Y坐标和LCD底层的X,Y坐标不同,他最大只能是MAX_GAME_X,MAX_GAME_Y
//使用方式:
内部调用
voidclr_game_dot(ucharx,uchary)
{
ucharlcd_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+y/2;//设置Y位置
LCMC=0xe0;
if(y%2)//行的下半部
{
for(i=0;i<4;i++)
{
#ifdeflcd_no_read//以下是显存法的清点程序,其他例如亮点的部分和这个原理一样
tmp=lcd_buf[y>>1][(x<<2)+i];//先从缓冲读出要修改的LCD片的数据
tmp&=0x0f;//清对应的游戏点
LCMD=tmp;
_nop_();
lcd_buf[y>>1][(x<<2)+i]=tmp;//把新数据写回缓冲
#else
tmp=LCMD;tmp=LCMD;//读LCD的方法,要求连读2次
LCMD=tmp&0x0f;
#endif
}
}
else//行的上半部,下同
{
for(i=0;i<4;i++)
{
#ifdeflcd_no_read
tmp=lcd_buf[y>>1][(x<<2)+i];
tmp&=0xf0;
LCMD=tmp;
_nop_();
lcd_buf[y>>1][(x<<2)+i]=tmp;
#else
tmp=LCMD;tmp=LCMD;
LCMD=tmp&0xf0;
#endif
}
}
LCMC=0xee;
}
//函数名:
fill_game_dot
//功能:
亮一个游戏点
//输入参数:
游戏坐标的X,Y坐标
//注意事项:
这里的X,Y坐标和LCD底层的X,Y坐标不同,他最大只能是MAX_GAME_X,MAX_GAME_Y
//这个函数和上面的clr_game_dot基本相同,只是在写LCD数据的时候是全1而不是0
//使用方式:
内部调用
voidfill_game_dot(ucharx,uchary)
{
ucharlcd_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+y/2;//设置Y位置
LCMC=0xe0;
if(y%2)//行的下半部
{
for(i=0;i<4;i++)
{
#ifdeflcd_no_read
tmp=lcd_buf[y>>1][(x<<2)+i];
tmp|=0xf0;
LCMD=tmp;
_nop_();
lcd_buf[y>>1][(x<<2)+i]=tmp;
#else
tmp=LCMD;tmp=LCMD;
LCMD=tmp|0xf0;
#endif
}
}
else
{
for(i=0;i<4;i++)
{
#ifdeflcd_no_read
tmp=lcd_buf[y>>1][(x<<2)+i];
tmp|=0x0f;
LCMD=tmp;
_nop_();
lcd_buf[y>>1][(x<<2)+i]=tmp;
#else
tmp=LCMD;tmp=LCMD;
LCMD=tmp|0x0f;
#endif
}
}
LCMC=0xee;
}
//函数名:
fill_game_dot2
//功能:
亮一个游戏点(另一种方式,这里用来显示食物用)
//输入参数:
X,Y
//注意事项:
X,Y为游戏的点阵,非LCD点阵...还有LCD填充数据是0x05或0x50
//使用方式:
内部调用,显示蛇的食物的时候用这个函数,区分开蛇身和食物.
voidfill_game_dot2(ucharx,uchary)
{
ucharlcd_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+y/2;//设置Y位置
LCMC=0xe0;
if(y%2)
{
for(i=0;i<4;i++)
{
#ifdeflcd_no_read
tmp=lcd_buf[y>>1][(x<<2)+i];
tmp|=0x50;
LCMD=tmp;
_nop_();
lcd_buf[y>>1][(x<<2)+i]=tmp;
#else
tmp=LCMD;tmp=LCMD;
LCMD=tmp|0x50;
#endif
}
}
else
{
for(i=0;i<4;i++)
{
#ifdeflcd_no_read
tmp=lcd_buf[y>>1][(x<<2)+i];
tmp|=0x05;
LCMD=tmp;
_nop_();
lcd_buf[y>>1][(x<<2)+i]=tmp;
#else
tmp=LCMD;tmp=LCMD;
LCMD=tmp|0x05;
#endif
}
}
LCMC=0xee;
}
/************************************************************
*
*游戏算法部分(4*4LCD)
*
**************************************************************/
//函数名game_init()
//功能:
游戏开始的时候初始化画面的,这里只是简单地把132*64LCD用一条中间线划分开来
//注意事项:
暂时在中间画条线用来划分游戏空间
//使用方式:
内部调用,
voidgame_init()
{
uchari;
ucharxdata*da;
for(da=0;da<0x8000;da++)//清空xDATA,
*da=0x0;
cls(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节蛇身,向右跑
//使用情况:
内部调用
voidsnake_init()
{
fill_game_dot(0,0);//显示射身
fill_game_dot(1,0);
fill_game_dot(2,0);
snake_len=2;
snake_flag=0x10;//蛇的初始化,3个身.向右跑
snake_body[0]=0x02;//装入射身数据
snake_body[1]=0x01;
snake_body[2]=0x00;
//一开始游戏时的文字部分
setcursor(8,0);
lcdstring("分数为:
\r\n");
setcursor(8,2);
lcddigit(snake_len-2);
}
//函数名:
show_mark
//功能:
显示当前分数,暂时以蛇身个数为分数
//参数说明:
0,和非0,0代表游戏中的显示,!
0代表挂了的显示
//注意事项:
调用到LCD.c显示函数,并需要汉字库的支持.
//返回值在GAMEOVER时候有效,返回0退出游戏,1从新游戏
//使用情况:
snake_run()在蛇吃到食物的时候调用,在GAMEOVER后调用
ucharshow_mark(ucharmode)
{
ucharch;
setcursor(8,0);
lcdstring("分数为:
\r\n");
setcursor(8,2);
lcddigit(snake_len-2);
if(mode)//gameover中显示
{
setcursor(8,0);
lcddigit(snake_len-2);
lcdstring("分.");
setcursor(8,2);
lcdstring("C退出");
setcursor(8,4);
lcdstring("回车继续");
doch=getkey(1000);
while((ch!
='C')&&(ch!
='Y'));//游戏结束了会在这里死等,直到用户按键
if(ch=='Y')
return
(1);
else
return(0);
}
return(0);
}
//函数名:
snake_run
//功能:
蛇运行函数
//输入参数:
一个全局变量flag_snake,蛇根据这个变量判断运动方向
//注意事项:
蛇跑动函数,用于判断路径,食物,长大,死亡
//使用情况:
内部调用
voidsnake_run()
{
uchartmp_head_x,tmp_head_y;
uchari;
switch(snake_flag&0xf0)//取蛇头方向
{
case0x80:
//向上走y--
tmp_head_x=snake_body[0]&0x0f;
tmp_head_y=(snake_body[0]>>4);
if(tmp_head_y==0)snake_flag|=0x04;//这个代表撞墙了,就置GAMEOVER标志,下同
elsetmp_head_y--;
break;
case0x40:
//向下走y++
tmp_head_x=snake_body[0]&0x0f;
tmp_head_y=(snake_body[0]>>4);
if(tmp_head_y==MAX_GAME_Y)snake_flag|=0x04;
elsetmp_head_y++;
break;
case0x20:
//向左走x--
tmp_head_y=snake_body[0]>>4;
tmp_head_x=snake_body[0]&0x0f;
if(tmp_head_x==0)snake_flag|=0x04;
elsetmp_head_x--;
break;
case0x10:
//向右走x++
tmp_head_y=snake_body[0]>>4;
tmp_head_x=snake_body[0]&0x0f;
if(tmp_head_x==MAX_GAME_X)snake_flag|=0x04;
elsetmp_head_x++;
break;
default:
break;
}
if(!
(snake_flag&0x04))//如果在之前没有撞墙,就可以进行下一步判断
{
//以下是得到食物的判断。
if(snake_food!
=((tmp_head_y<<4)+tmp_head_x))//蛇头和食物坐标没重叠就代表没有吃到食物
{//得不到食物的处理
clr_game_dot(snake_body[snake_len]&0x0f,snake_body[snake_len]>>4);//灭蛇尾巴
for(i=snake_len;i>0;i--)//柔体传动
snake_body[i]=snake_body[i-1];
snake_body[0]=(tmp_head_y<<4)+tmp_head_x;
}
else
{//得到食物的处理
snake_body[snake_len+1]=snake_body[snake_len];//保留蛇尾巴(这是增长型柔体传动)
for(i=snake_len;i>0;i--)
snake_body[i]=snake_body[i-1];
snake_body[0]=(tmp_head_y<<4)+tmp_head_x;//新蛇头
snake_len++;//长度增加1
snake_flag&=~0x02;//清食物标志
show_mark(0);//显示分数
}
fill_game_dot(tmp_head_x,tmp_head_y);//显示新蛇头
}
for(i=1;i { if(snake_body[0]==snake_body[i]) { snake_flag|=0x04;//撞中了就置GAMEOVER标志 break; } } } //函数名: set_food //功能: 放食物 //注意事项: 这个函数在被调用前会先判断是否需要放食物, //这里用自己编写的随机数来产生食物,随机数和蛇身位置,定时器有关 //每次放食物的时候必须先判断是否和蛇身重叠了,重叠了要重新放 //这里设定了如果蛇长度达到某值了就不再放食物. //影响变量: snake_food //使用情况: 内部调用 voidset_food() { ucharseed0,seed1,i=0; seed0=snake_body[snake_len-2]; if(snake_len==250) { return;//蛇都快满屏了,就不放食物了,事实上我还没玩过超过100的呢: ) } seed0=((seed1>>3)*4+seed0+TL0);//随机数的生成,其实乱做就可以了: ) seed1=(snake_body[0]>>4)+seed0; snake_food=(seed1+seed0*3); food: for(i=0;i { if(snake_body[i]==snake_food) { snake_food=(snake_food+0x01);//如果重叠了,位置就+1,然后 gotofood;//重新比较,这里可以换成i=255,效果一样 } } fill_game_dot2(snake_food&0x0f,snake_food>>4);//放食物 snake_flag|=0x02;//置有食物标志 } //函数名: 定时器1初始化程序 //晶振22.1184,定时时间35MS voidtimer0_init(void) { TMOD=0x1; TH0=0x0; TL0=0x0; } //函数名: snake_game //功能: 整个游戏的主要函数 //注意事项: 游戏利用了定时器产生蛇的运行速速度 //调用前应该先初始化定时器 //使用情况: 外部调用 // externuchartime_service;//这个东东是使定时器公用的。 voidsnake_game() { uchartmp_snake_flag,ch; cls(8); time_service=1; lcdstring("贪吃蛇游戏\r\nC退出,任意键进入\r\n游戏说明: \r\n2: 上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&0x80))break;//向上走的时候,上下键盘都无效,下同 tmp_snake_flag&=0x0f;tmp_snake_flag|=0x80; break; case'5': //按了下按键 if((snake_flag&0x80)||(snake_flag&0x40))break; tmp_snake_flag&=0x0f;tmp_snake_flag|=0x40; break; case'4': //按了左按键 if((snake_flag&0x10||(snake_flag&0x20)))break; tmp_snake_flag&=0x0f;tmp_snake_flag|=0x20; break; case'6': //按了右按键 if((snake_flag&0x20||(snake_flag&0x10)))break; tmp_snake_flag&=0x0f;tmp_snake_flag|=0x10; break; case'C': //任何时候,按C就结束游戏 return; default: break; } if(! (snake_flag&0x02))//如果图上已经没食物了,就 set_food();//放食物 if((snake_flag&0x01))//判断是否够时间跑一步 { snake_flag=(snake_flag&0x0e)|tmp_snake_flag;//取消跑动标志,置新方向 snake_run(); tmp_snake_flag=snake_flag; } if((snake_flag&0x04))//判断游戏结束标志 { if(show_mark (1)) { snake_flag&=~0x04; gotobegin_game; } else return;//游戏结束
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 贪吃 语言 txt 一个 禁忌 相继 崩溃 时代 没人