欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于51单片机的贪吃蛇游戏

程序员文章站 2024-03-18 17:01:58
...

1.简介
本设计为一款贪吃蛇游戏,显示器采用8*8点阵,主控制器采用51单片机,并通过按键实现对游戏的操作。

2.贪吃蛇算法介绍
吃蛇游戏算法的实现,即如何通过液晶屏显示蛇的移动。

  1. 其实蛇看似移动的过程中,实质只有两个点再变,即蛇头前进方向增加一个点,蛇尾减少一个点。
  2. 知道如何显示蛇的移动后,再一个关键问题就是蛇的转折问题,如何控制蛇尾消失的点沿着蛇的路径。通俗的说就是蛇怎么实现曲折移动,这里就用到了循环队列,每次蛇头前进方向发生变化后,队列增加一个结点,结点中包含蛇头方向变化的位置,以及蛇头转变的方向。
  3. 蛇尾每次移动的过程中都会与队列头指针所储存的位置做一次判断,当蛇尾到达这一位置后,从结点中取出保存的蛇头的移动方向赋给蛇尾,结点出队列即删除这一结点。
  4. 由于队列是头出尾进,所以蛇头先产生的结点,蛇尾会先与其进行判断,并且删除它,即实现了蛇的曲折运动。

3.硬件设计
此设计的硬件相对简单,主要由四部分组成,分别为单片机最小系统、8x8LED矩阵模块、按键电路、系统电源。硬件框图如下,
基于51单片机的贪吃蛇游戏
(1)8*8LED矩阵电路
8X8点阵LED结构如下图所示:
基于51单片机的贪吃蛇游戏
从图中可以看出,8X8点阵共需要64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一列置1电平,某一行置0电平,则相应的二极管就亮;要实现显示图形或字体,只需考虑其显示方式。通过编程控制各显示点对应LED阳极和阴极端的电平,就可以有效的控制各显示点的亮灭。
例如:要实现一根柱形的亮法,如图所示,对应的一列为一根竖柱,或者对应的一行为一根横柱,因此实现柱的亮的方法如下所述:
一根竖柱:对应的列置1,而行则采用扫描的方法来实现。
一根横柱:对应的行置0,而列则采用扫描的方法来实现。
此外,为了增大单片机的驱动能力,在单片机的P0脚上增加了一个74HC245缓冲器,增强对LED的驱动能力,电路如下
基于51单片机的贪吃蛇游戏
(2)按键电路
在此设计中设置了五个按键,分别为方向使能、上、下、左、右,方式为当方向使能按键按下后,四个方向的按键动作才有效。电路如图,
基于51单片机的贪吃蛇游戏
(3)硬件电路图
基于51单片机的贪吃蛇游戏
基于51单片机的贪吃蛇游戏
4.软件设计
(1) 按键操作程序

/*******************************************
判断碰撞
*******************************************/
bit knock()
{
	bit k;
	k=0;
	if(x[1]>7||y[1]>7)
		k=1;                             //撞墙
	for(i=2;i<n;i++)
		if((x[1]==x[i])&(y[1]==y[i]))
			k=1;  //撞自己
	return k;
}
/*****************
上下左右键位处理
*****************/
void turnkey()// interrupt 0 using 2  
{
	if(keyenable == 0)
	{
		key_en ^= 1;   //取反操作
	}
	if(key_en)
	{
		if(left==0){addy=0;if(addx!=1)addx=-1; else addx=1;}
		if(right==0){addy=0;if(addx!=-1)addx=1; else addx=-1;}
		if(up==0){addx=0;if(addy!=-1)addy=1; else addy=-1;}
		if(down==0){addx=0;if(addy!=1)addy=-1; else addy=1;}
	}
}
/*****************
乘方程序
*****************/
uchar mux(uchar temp) 
{
	if(temp==7)return 128;
	if(temp==6)return 64;
	if(temp==5)return 32;
	if(temp==4)return 16;
	if(temp==3)return 8;
	if(temp==2)return 4;
	if(temp==1)return 2;
	if(temp==0)return 1;
	return 0;
}

(2)主程序

/*****************
主程序
*****************/	
void main(void)
{
	e=SPEED;
	P0=0x00;
	P1=0xff;
	P2=0x00;
	P3=0x00;
	
	while(1)       
	{
		//if(keyenable==1){P1=0x00;P2=0xff;}else{P1=0xff;P2=0x00;}
		for(i=3;i<SNAKE+1;i++)
			x[i]=100;
		for(i=3;i<SNAKE+1;i++)
			y[i]=100;//初始化
		
		x[0]=4;y[0]=4;                                                //果子                            
		n=3;                                                          //蛇长 n=-1
		x[1]=1;y[1]=0;                                                //蛇头
		x[2]=0;y[2]=0;                                                //蛇尾1
		addx=0;addy=0;                                                //位移偏移
		//k=1;
		while(1)
		{
				if(keyenable)
					break;
				timer0(1);
		}
		while(1)         
		{
			timer0(e);
			if(knock())
			{
				e=SPEED;
				break;
			}                          //判断碰撞
      if((x[0]==x[1]+addx)&(y[0]==y[1]+addy))         //是否吃东西
      {
				n++;
				if(n==SNAKE+1)
				{
					n=3;
					e=e-10;
					for(i=3;i<SNAKE+1;i++)
						x[i]=100;
          for(i=3;i<SNAKE+1;i++)
						y[i]=100;
				}
        x[0]=x[n-2];
        y[0]=y[n-2];
			}
			for(i=n-1;i>1;i--){x[i]=x[i-1];y[i]=y[i-1];}        
			//x[n-1]=x[2];y[n-1]=y[2];
			x[1]=x[2]+addx;y[1]=y[2]+addy;                     //移动
		}						
	}			
}

源码+PCB+AD原理图 下载:关注公众号,首页回复“贪吃蛇”获取资料
基于51单片机的贪吃蛇游戏