#include"config.h"
/*全局变量*/
uchar key=4; //存储方向: 1上 2下 3左 4右
uchar buff[8]={0}; //缓冲数组
uchar random=0; //随机种子(定时器1生成的随机种子)
bit flag500ms=0; //500ms标志(暂定蛇的速度是500ms移动)
bit flag_over=0; //游戏是否结束标志
/*函数声明*/
void in
tiSnake(uchar *snake,uchar len); //初始化蛇
bit BiteOneself(uchar *snake,uchar len); //是否咬到自己
void move(uchar *snake,uchar *len,uchar key); //移动
void scanning(void); //按键驱动
void initTimer(void); //初始化定时器
/*主函数*/
void main(void)
{
uchar snake[25];
//蛇:snake[0]存储食物信息 snake[1]存储蛇头信息
//其中每个字节前4位存储x坐标 后4位存储y坐标
uchar len=3;
//存储蛇的长度
intiSnake(snake,len); //初始化蛇
initTimer(); //初始化定时器
EA=1; //开启总中断
while(1)
{
if(flag500ms) //移动
{
flag500ms=0;
move(snake,&len,key);
flag_over=BiteOneself(snake,len);
}
if(flag_over) //死亡就重置
{
flag_over=0;
len=3;
memset(buff,0,8*sizeof(uchar));
key=4;
intiSnake(snake,len);
}
}
}
/*定时中断服务0*/
void timer0(void) interrupt 1
{
static uchar i=0;
static uchar j=0;
static uint k=0;
TH0=0xfc;
TL0=0x6c;
P0=0x00; //消隐,将点阵屏先关闭
P1=~(0x01<
P0=buff
;
i++;i&=0x07;
if(++j==5) {scanning();j=0;}
if(++k==500){flag500ms=1;k=0;}
}
/*定时中断服务1*/
void timer1(void) interrupt 3
{
random++;
}
//--------------------------------------//
// 贪吃蛇功能实现 //
//--------------------------------------//
/*坐标转换*/
void ConversionBUFF(uchar *snake,uchar len)
{
uchar i;
memset(buff,0,8*sizeof(uchar)); //清空缓冲数组
for(i=0;i<=len;i++) //将蛇位置转换为缓冲数组
buff[(snake&0x0f)]|=(0x01<<(snake>>4));
}
/*初始化蛇*/
void intiSnake(uchar *snake,uchar len)
{
snake[0]=0x55; snake[1]=0x33;
snake[2]=0x23; snake[3]=0x13;
ConversionBUFF(snake,len); //更新缓冲数组
}
/*是否咬到自己*/
bit BiteOneself(uchar *snake,uchar len)
{
uchar i;
for(i=2;i<=len;i++)
if(snake[1]==snake)
return 1;
}
/*食物是否在蛇身上*/
bit FoodInTheSnake(uchar len,uchar *snake)
{
uchar i;
for(i=1;i<=len;i++)
if(snake[0]==snake) return 0;
return 1;
}
/*随机生成食物*/
void ProduceFood(uchar len,uchar *snake)
{
uchar x,y;
srand(random); //初始化随机种子
while(1)
{
x=rand()%8; y=rand()%8; snake[0]=(x<<4)|y;
if(FoodInTheSnake(len,snake))
break;
}
}
/*移动*/
void move(uchar *snake,uchar *len,uchar key)
{
uchar temp=snake[1]; //临时变量,存储蛇头位置信息
uchar i;
switch(key) //移动
{
case 1:temp+=0x01;temp&=0xf7; break; //上
case 2:if(!(temp&0x0f)) temp|=0x07;else temp-=0x01; break; //下
case 3:if(!(temp&0xf0)) temp|=0x70;else temp-=0x10; break; //左
case 4:temp+=0x10;temp&=0x7f; break; //左
}
if(temp==snake[0]) //有食物
{
(*len)++; //长度增加
for(i=(*len);i>1;i--)snake=snake[i-1]; //刷新蛇身
snake[1]=temp; //更新蛇头
ProduceFood(*len,snake); //生成食物
}
else //无食物
{
for(i=(*len);i>1;i--)snake=snake[i-1]; //刷新蛇身
snake[1]=temp; //更新蛇头
}
ConversionBUFF(snake,*len); //更新缓冲数组
}
//--------------------------------------//
// 按键驱动 //
//--------------------------------------//
/*按键驱动*/
void scanning(void)
{
static uchar option=0;
bit condition=(KEY1&KEY2&KEY3&KEY4);;
switch(option)
{
case 0: //等待按键动作
if(condition!=1)
option=1;
break;
case 1: //判断该按键动作是否有效
if(condition!=1)
{
if(KEY1==0 && key!=0x02)
key=0x01;
if(KEY2==0 && key!=0x01)
key=0x02;
if(KEY3==0 && key!=0x04)
key=0x03;
if(KEY4==0 && key!=0x03)
key=0x04;
option=2;
}
else
option=0;
break;
case 2: //等待按键弹起
if(condition==1)
option=0;
break;
}
}
//--------------------------------------//
// 定时器配置
//
//--------------------------------------//
/*定时器初始化*/
void initTimer(void)
{
TMOD&=0xf0;
TMOD|=0x01;
TH0=0xfc;
TL0=0x6c; //定时器0定时1ms
TMOD&=0x0f;
TMOD|=0x20;
TH1=0x00;
TL1=0x00; //定时器1设置8位自动加载模式
TR0=1;
ET0=1;
TR1=1;
ET1=1;
}
/*简单的实现了贪吃蛇的功能*/
0