這是基於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進行詢問。