童年时光,小小贪吃蛇

这个贪吃蛇游戏从54日到58日四天中凭着小时候玩这个游戏的感觉慢慢写出来的,也没多大去参考其他人的程序,同时也没运用队的数据结构知识编写,而是运用数组,所以相对来说漏洞挺多的,当然最主要的那一份逻辑构思,希望这里能帮助其他人给到一些灵感……

         由于刚接触单片机也是这学期开始,编写菜单程序过程中也不免有累赘的地方。

 

总模块:

    

主函数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;
				}
		}
	}

}


 

你可能感兴趣的:(游戏开发)