基于51单片机的点阵贪吃蛇

 这是基于51单片机的贪吃蛇小游戏,用四个独立按键控制上下左右,用8*8点阵作为显示

程序如下:

#include <reg52.h>
#include <intrins.h>
#include <stdlib.h>

#define SNAKE 20

unsigned char x[SNAKE];        //存放蛇的X轴坐标
unsigned char y[SNAKE];        //存放蛇的Y轴坐标

unsigned char point_x;         //存放果实的X轴坐标
unsigned char point_y;         //存放果实的Y轴坐标
/*
//点阵模块接口定义
sbit LEDARRAY_LAT = P3^6;//储存寄存器是时钟
sbit LEDARRAY_CLK = P3^5;//移位寄存器时钟输入端
sbit LEDARRAY_DI = P3^4;//串行数据输入端
sbit up    = P3^0;
sbit down  = P3^1;
sbit left  = P3^2;
sbit right = P3^3;
unsigned char num[8][8]={
			0,0,0,0,0,0,0,0,
			0,0,0,0,0,0,0,0,
			0,0,0,0,0,0,0,0,
			0,0,0,0,0,0,0,0,
			0,0,0,0,0,0,0,0,
			0,0,0,0,0,0,0,0,
			0,0,0,0,0,0,0,0,
			0,0,0,0,0,0,0,0
			};//定义8*8数组作为清屏数据(有点走弯路,也就不改了自己有能力可以自己改)




unsigned char move_flag=0;        //移动标志, 1 上,2 下,3 左,4 右;
unsigned char snake=3;            //蛇身长度   
unsigned int flag=1;              //是否需要生成果实


//SPI通信函数 发送一个直接数据给点阵模块
void Send_Byte( unsigned char dat)
{
	unsigned char i;//循环次数数变量
	LEDARRAY_CLK = 0;//拉低移位时钟
	_nop_();	
	LEDARRAY_LAT = 0;//拉低储存时钟
	_nop_();

	for( i = 0 ; i < 8 ; i++ ) //?循环8次写入一个字节数据
	{
		if( dat&0x01 )
		{
			LEDARRAY_DI = 1;	
		}
		else
		{
			LEDARRAY_DI = 0;
		}
		
		LEDARRAY_CLK = 1;				//上升沿发送数据
		//				_nop_();
		LEDARRAY_CLK = 0;
		//				_nop_();
				
		dat >>= 1;			
	}		
}

void chang_num()            //这个函数用来转码,把8*8数组中的‘0’,‘1’按列写成十六进制
{	int i,j;
	for(j=0;j<8;j++) 
	{
		for(i=7;i>=0;i--)    
		{  
		Dis_num[j]*=2;  
		Dis_num[j]+=num[i][j]&0x01;  
		}	
	}
}

void Display(unsigned char* Dis_dat,delay)     //显示函数
{
	unsigned char k, temp;
	unsigned int i;
	
	for(i = 0 ; i < delay ; i++)
	{
		temp = 0x7f;
		for(k = 0 ; k < 8 ; k++)		//一个字节8byte
		{
			Send_Byte(temp);			//列选择
			Send_Byte(Dis_dat[k]);			//行数据
			LEDARRAY_LAT =1;		        //锁存数据
			_nop_();
		
			LEDARRAY_LAT = 0;
			_nop_();
			temp = (temp>>1)|0x80;
		}
	}
}
void key()
{
	if(move_flag!=2&&(!up))
	{
		move_flag=1;
	}
	if(move_flag!=1&&(!down))
	{
		move_flag=2;
	}
	if(move_flag!=4&&(!left))
	{
		move_flag=3;
	}
	if(move_flag!=3&&(!right))
	{
		move_flag=4;
	}
}

void move()       //这个函数是让蛇走起来的,如果蛇现在向上走就把蛇尾所在坐标改为0,把蛇头上方所在坐标改为1.其他同理
{
	unsigned int i;
	if(move_flag==1)
	{
		for(i=snake;i>0;i--)
		{
			x[i+1]=x[i];
			y[i+1]=y[i];
		}
		x[1]=x[1]-1;
		y[1]=y[1]; 
	}
	if(move_flag==2)
	{
		for(i=snake;i>0;i--)
		{
			x[i+1]=x[i];
			y[i+1]=y[i];
		}
		x[1]=x[1]+1;
		y[1]=y[1]; 
	}
	if(move_flag==3)
	{
		for(i=snake;i>0;i--)
		{
			x[i+1]=x[i];
			y[i+1]=y[i];
		}
		x[1]=x[1];
		y[1]=y[1]-1; 
	}
	if(move_flag==4)
	{
		for(i=snake;i>0;i--)
		{
			x[i+1]=x[i];
			y[i+1]=y[i];
		}
		x[1]=x[1];
		y[1]=y[1]+1; 
	}
	
}



void bulid_point()        //生成果实函数
{
	unsigned int i;  
	if((x[1]==point_x)&&(y[1]==point_y))        //判断吃到果实
	{ 
		snake++;        //蛇的长度加1
		flag=1;         //标志需要生成果实
	}
	while(flag)            //生成果实
	{
		point_x=(unsigned char)(rand()%8);
		point_y=(unsigned char)(rand()%8);
		for(i=1;i<snake+1&&flag;i++)
		{
			if(point_x !=x[i]&&point_y!=y[i])
				flag=0;
		}
	}
}  

bit eat()            
{
	
}
void assign ()     //画蛇函数,在8*8二维数组中画出蛇,把蛇所在的每个坐标改为1
{
	unsigned int i,j;
	for(i=0;i<8;i++)
	{
		for(j=0;j<8;j++)
		{
			num[i][j]=0;
		}
	}
	for(i=1;i<snake+1;i++)
	{
		num[x[i]][y[i]]=1;
	}
	num[point_x][point_y]=1;
}



void main()
{
	snake=3;
	//x[0]=4;y[0]=3;
	x[1]=4;y[1]=4;
	x[2]=4;y[2]=5;
	x[3]=4;y[3]=6;
	while(1)
	{
		key();
		move();
		bulid_point();
		//eat();
		assign ();
		chang_num();
		Display(Dis_num,200);
		if(x[1]>7||y[1]>7)
		{
			while(1)
			{
				num[x[1]][y[1]]=0;
				chang_num();
				Display(Dis_num,200);
			}
		}
	}	 
}

  • 16
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值