这个贪吃蛇游戏从5月4日到5月8日四天中凭着小时候玩这个游戏的感觉慢慢写出来的,也没多大去参考其他人的程序,同时也没运用队的数据结构知识编写,而是运用数组,所以相对来说漏洞挺多的,当然最主要的那一份逻辑构思,希望这里能帮助其他人给到一些灵感……
由于刚接触单片机也是这学期开始,编写菜单程序过程中也不免有累赘的地方。
总模块:
主函数main:
当然,参考他人程序,主函数免不了是主要参照,这里我就把主函数的源代码部分贴出来……
由于menu是此次游戏编程的重要部分,而且包括了菜单,而其他部分也只是一些比较公用的模块,加上大家用的引脚各不一样,为方便移植也没必要限定了引脚,所以就不贴出来了……
这里我就把menu的全部源代码全粘贴下来……
#include
#include"lcd12864.h"
#include"keyscan.h"
#include"delay.h"
unsigned char layer;//当前画面值
unsigned char addr;//光标地址
unsigned char lever;//记录游戏等级
unsigned char score[3];//记录游戏分数
/******** 蛇 ********/
xdata unsigned char she[32];//记录蛇头和蛇身的地址
unsigned char size;//记录蛇当前长度
unsigned char wayflag;//记录蛇当前走向
bit goflag;//记录蛇该不该走,1走,0停
unsigned char she_food[6];//记录蛇饵地址
bit foodflag;//记录蛇饵该不该更换
/****************************************
定时器1初始化
*****************************************/
void init_timer1(void)
{
TMOD|=0x10;
TH1=-50000/256;
TL1=-50000%256;
EA=1;
ET1=1;
TR1=1;
}
/********************************************
画面处理
*********************************************/
void menu(unsigned char layer)
{
unsigned char flag;//按键值
/**********主菜单*************/
if(layer==0)
{
write_com(0x01);//清屏
write_string(1,2,"贪吃蛇游戏");
write_string(2,1,"->开始游戏");
write_string(3,1,"->等级调节");
write_string(4,1,"->排名");
addr=0x90;
write_com(addr);
//此画面按键设置
while(1)
{
flag=keypro();
if(flag=='U')
{
if(addr==0x88)
addr=0x90;
else if(addr==0x98)
addr=0x88;
write_com(addr);
}
else if(flag=='D')
{
if(addr==0x90)
addr=0x88;
else if(addr==0x88)
addr=0x98;
write_com(addr);
}
else if(flag=='E')
{
if(addr==0x90)
layer=1;
else if(addr==0x88)
layer=2;
else if(addr==0x98)
layer=3;
break;
}
}
}
/***********************************/
/***********************************/
/***********************************/
/**********游戏画面*************/
if(layer==1)
{
unsigned char *pshe;//指向蛇的中间向量
unsigned char she_last;//记录蛇尾的地址
unsigned char she_last1;//记录蛇尾的前一步的地址
bit out=0;//退出标志,1退出
unsigned char score_temp;//记录临时的分数
unsigned char she_food_temp[6];
write_com(0x0C);//关闭光标,停止闪烁
write_com(0x01);//清屏
write_string(2,2,"Waiting");
DelayMs(250);
DelayMs(250);
write_dat('.');
DelayMs(250);
DelayMs(250);
write_dat('.');
DelayMs(250);
DelayMs(250);
write_dat('.');
DelayMs(250);
DelayMs(250);
write_com(0x01);//清屏
init_timer1();//定时器1初始化
she[1]=0x91;
she[2]=0x90;
wayflag='R';//蛇默认当前走向向右
size=2; //蛇当前长度默认为2,即2个单位长度
goflag=0; //蛇默认不该走
write_str(she[1],"口");//代表蛇头的字符
write_str(she[2],"田");//代表蛇身关节的字符
she_last=she[size];
// she_food_temp[0]=0x85;
// she_food_temp[1]=0x96;
// she_food_temp[2]=0x9E;
// she_food_temp[3]=0x8D;
// she_food_temp[4]=0x8F;
// she_food_temp[5]=0x97;
while(1)
{
flag=keypro();
if(goflag==1)
{
goflag=0;
write_str(she_last," ");
she_last1=she_last;
for(pshe=she+size;pshe>she+1;pshe--)
write_str(*pshe,"田");
write_str(she[1],"口");
she_last=she[size];
//吃到食物
for(pshe=she_food;psheshe+1;pshe--)
if(*pshe==she[1])//蛇身地址与蛇头地址相同代表蛇吃到自己了
{
//记录分数
score_temp=size;
for(pshe=score;pshe*pshe)
{
*pshe=score_temp;
break;
}
write_com(0x01);
write_com(0x0E);//开启光标但不闪烁
write_string(1,1,"你吃到自己啦!");
write_string(2,6,"--蛇蛇");
write_string(3,1,"->重新开始");
write_string(4,1,"->返回主菜单");
addr=0x88;
write_com(addr);
//清空蛇饵
she_food[0]=she_food[1]=she_food[2]=she_food[3]=she_food[4]=she_food[5]=0;
while(1)
{
flag=keypro();
if(flag=='U'||flag=='D')
{
if(addr==0x88)
addr=0x98;
else
addr=0x88;
write_com(addr);
}
else if(flag=='E')
{
flag='*';//避免与下面的语句有撞
if(addr==0x98)
{
out=1;
layer=0;
}
else//重新开始
{
write_com(0x01);//清屏
write_com(0x0C);//关闭光标
she[1]=0x91;
she[2]=0x90;
wayflag='R';//蛇默认当前走向向右
size=2; //蛇当前长度默认为2,即2个单位长度
goflag=0; //蛇默认不该走
write_str(she[1],"口");//代表蛇头的字符
write_str(she[2],"田");//代表蛇身关节的字符
she_last=she[size];
}
break;
}
}
}
//显示食物
if(foodflag==1)
{
foodflag=0;
for(pshe=she_food_temp;pshe重新开始");
write_string(4,1,"->返回主菜单");
addr=0x88;
write_com(addr);
//清空蛇饵
she_food[0]=she_food[1]=she_food[2]=she_food[3]=she_food[4]=she_food[5]=0;
while(1)
{
flag=keypro();
if(flag=='U'||flag=='D')
{
if(addr==0x88)
addr=0x98;
else
addr=0x88;
write_com(addr);
}
else if(flag=='E')
{
if(addr==0x98)
{
out=1;
layer=0;
}
else//重新开始
{
write_com(0x01);//清屏
write_com(0x0C);//关闭光标
she[1]=0x91;
she[2]=0x90;
wayflag='R';//蛇默认当前走向向右
size=2; //蛇当前长度默认为2,即2个单位长度
goflag=0; //蛇默认不该走
write_str(she[1],"口");//代表蛇头的字符
write_str(she[2],"田");//代表蛇身关节的字符
she_last=she[size];
}
break;
}
}
}
if(out==1)
{
out=0;
break;
}
}
}
/***********************************/
/***********************************/
/***********************************/
/**********等级调节菜单*************/
if(layer==2)
{
write_com(0x01);//清屏
write_string(1,1,"->低级");
write_string(2,1,"->中级");
write_string(3,1,"->高级");
write_string(4,1,"->返回主菜单");
addr=0x80;
write_com(addr);
//此画面按键设置
while(1)
{
flag=keypro();
if(flag=='U')
{
if(addr==0x90)
addr=0x80;
else if(addr==0x88)
addr=0x90;
else if(addr==0x98)
addr=0x88;
write_com(addr);
}
else if(flag=='D')
{
if(addr==0x80)
addr=0x90;
else if(addr==0x90)
addr=0x88;
else if(addr==0x88)
addr=0x98;
write_com(addr);
}
else if(flag=='E')
{
if(addr==0x80)
lever=6;
else if(addr==0x90)
lever=3;
else if(addr==0x88)
lever=1;
layer=0;
break;
}
}
}
/**********最高分菜单*************/
if(layer==3)
{
write_com(0x01);//清屏
write_string(1,1,"冠军");
write_string(2,1,"亚军");
write_string(3,1,"季军");
write_string(4,1,"->返回主菜单");
write_num(1,4,score[0]);
write_num(2,4,score[1]);
write_num(3,4,score[2]);
addr=0x98;
write_com(addr);
//此画面按键设置
while(1)
{
flag=keypro();
if(flag=='E')
{
layer=0;
break;
}
}
}
}
/********************************************
定时器1中断程序
*********************************************/
void timer1_isr(void) interrupt 3 using 1
{
static unsigned char i=0;
static unsigned char l=0;
unsigned char j;
unsigned char k;
TH1=-50000/256;
TL1=-50000%256;
i++;
l++;
if(i==lever*5)
{
i=0;
goflag=1;//标志蛇可以移动一步
for(j=size;j>1;j--)
she[j]=she[j-1];
if(wayflag=='L')
{
if(she[1]==0x80||she[1]==0x90||she[1]==0x88||she[1]==0x98)
she[1]+=7;
else
she[1]-=1;
}
else if(wayflag=='R')
{
if(she[1]==0x87||she[1]==0x97||she[1]==0x8F||she[1]==0x9F)
she[1]-=7;
else
she[1]+=1;
}
else if(wayflag=='U')
{
if(she[1]>=0x80&&she[1]<=0x87)
she[1]+=24;
else if(she[1]>=0x90&&she[1]<=0x97)
she[1]-=16;
else if(she[1]>=0x88&&she[1]<=0x8F)
she[1]+=8;
else if(she[1]>=0x98&&she[1]<=0x9F)
she[1]-=16;
}
else if(wayflag=='D')
{
if(she[1]>=0x80&&she[1]<=0x87)
she[1]+=16;
else if(she[1]>=0x90&&she[1]<=0x97)
she[1]-=8;
else if(she[1]>=0x88&&she[1]<=0x8F)
she[1]+=16;
else if(she[1]>=0x98&&she[1]<=0x9F)
she[1]-=24;
}
}
if(l==lever*40)
{
l=0;
foodflag=1;
for(j=0;j<6;j++)
{
she_food[j]=rand()%31;
for(k=1;k<=size;k++)
if(she[k]==she_food[j])
{
j--;
break;
}
}
}
}