基於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);
			}
		}
	}	 
}

代碼中都有解釋應該可以看懂,如有問題請加Q羣317635311進行詢問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章