#include<reg52.h>
#include <stdlib.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
#define Snake 15 //最大长度,蛇吃满多少就自动结束程序
sbit DS=P1^0; //595串口数据输入端
sbit OE=P1^1; //使能端,低电平有效
sbit ST=P1^2; //移位寄存器的时钟输入 SCK
sbit SH=P1^3; //存储器的时钟输入 RCK
char length,Level;
char addx,addy; //位移偏移量
char x_food,y_food; //食物坐标
uchar x[Snake-1]; //x坐标
uchar y[Snake-1]; //y坐标
uchar time,n,i,e;
uchar SPEED; //速度
char Play_en; //开始游戏标志
char Sad_flag;
sbit Key_EN=P2^0; //方向使能,默认是低电平
sbit up=P2^3; //定义方向键
sbit down=P2^2;
sbit left=P2^1;
sbit right=P2^4;
sbit Mode=P2^5;
char temp;
char Init_Snake_flag;
char Mode_flag;
char Mode_1,Mode_2;
uint Wait_Time;
char Eat_Food_super(char i);
void Game_play_super();
void Init_Snake();
void Display(uchar x,uchar y);
void delay()
{ char j,i;
for (i=0;i<25;i++)
for (j=0;j<10;j++);
}
/*******************************************
判断碰撞
*******************************************/
char Knock()
{
temp=0;
if((x[length-1]==(-1))||(x[length-1]==16)||(y[length-1]==(-1))||(y[length-1]==16))
temp=1; //撞墙
for(i=0;i<length-1;i++)
{
if((x[length-1]==x[i])&&(y[length-1]==y[i])) //撞自己
{
temp=1;
break;
}
}
return temp;
}
/*****************
方向处理
*****************/
void Key_Scan()
{
P2=0xff;
if (Mode==0) //模式转换处理按键
{
delay();
while (Mode==0);
Mode_flag=!Mode_flag;
}
if (Key_EN==0)
Play_en=1;
if(Play_en==1)
{
if(right==0)
{
addy=0; if (addx!=-1) addx=1;else addx=-1;
}
if(left==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;
}
}
}
void Transmit_Data(unsigned long Data)
{
uchar i;
unsigned long Num;
OE=0;
Num=Data;
for(i=0;i<32;i++)
{
if(Num&0x80000000)
DS=1;
else
DS=0;
SH=1; //上升沿,数据送入寄存器
SH=0;
Num<<=1;
}
ST=1; //上升沿,数据推出端口
ST=0;
}
void Display(uchar x,uchar y) //显示点函数
{
unsigned int L,H;
unsigned long point;
L=1<<(15-x);
H=~(1<<y);
point=L;
point<<=16;
point+=H;
Transmit_Data(point);
}
/*****************
碰撞表情 “囧”
*****************/
void Sad()
{
uchar i,j,k,n,m,a,b;
char g=2;
unsigned long Count;
if(Sad_flag==1)
{
for (i=0;i<3;i++)
{
Display(i+2,i+11);
}
for (i=11;i<14;i++)
{
Display(i,11+g);
g--;
}
for (i=0;i<16;i++)
{
Display(0,i);
}
for (j=0;j<16;j++)
{
Display(15,j);
}
for (k=0;k<16;k++)
{
Display(k,0);
}
for (n=0;n<16;n++)
{
Display(n,15);
}
for (n=4;n<12;n++)
{
Display(n,3);
Display(n,8);
}
for (n=4;n<8;n++)
{
Display(4,n);
Display(11,n);
}
}
}
void Put_food()
{
Display(x_food,y_food);
}
void Snake_Body()
{
uchar i;
for(i=0;i<length;i++)
{
Display(x[i],y[i]);
}
}
/**************/
//是否吃东西
/*************/
char Eat_Food(char i)
{ char j;
if(((x[length-1]==x_food)&&(y[length-1]==y_food))||i)
{
length++;
if (length<Snake)
{
if(Level==1&&Init_Snake_flag==0) //等级以及速度的处理
{
switch(length)
{
case 6: SPEED = 40;break;
case 8: SPEED = 35;break;
case 10: SPEED = 30;break;
case 14:
{
Init_Snake_flag=1;
SPEED = 30;
Level = 2;
Play_en=0;
} break;
default:break;
}
}
if(Level==2&&Init_Snake_flag==0)
{
switch(length)
{
case 6: SPEED = 25;break;
case 8: SPEED = 20;break;
case 10: SPEED = 15;break;
case 14:
{
Init_Snake_flag=1;
SPEED = 15;
Level = 3;
Play_en=0;
} break;
default:break;
}
}
if(Level==3&&Init_Snake_flag==0)
{
switch(length)
{
case 6: SPEED = 15;break;
case 8: SPEED = 10;break;
case 10: SPEED = 7;break;
case 14:
{
Init_Snake_flag=1;
SPEED = 50;
Level = 1;
Play_en=0;
} break;
default:break;
}
}
}
x[length-1] = x_food+addx;
y[length-1] = y_food+addy;
j=x[0]+rand()%10; //产生随机数
if(j>=0&&j<=15)
x_food=j;
else
x_food=x[0];
j=y[0]+rand()%10;
if(j>=0&&j<=15)
y_food=j;
else
y_food=y[0];
return 1;
}
return 0;
}
/***蛇初始化**/
void Init_Snake()
{
char i;
Wait_Time=0;
length=3;
x_food=7;
y_food=8;
addx=addy=0;
for(i=0; i<length; i++)
{
x[i]=5+i;y[i]=3;
}
}
void Init_Time(void)
{
TMOD = 0x01;
TH0 = 0xd8;
TL0 = 0xF0;
ET0 = 1;
EA = 1;
}
void start_play()
{
TR0 = 1;
}
void stop_play()
{
TR0 = 0;
}
void Game_play()
{
if (Wait_Time >= SPEED)
{
Wait_Time = 0;
for(i=0;i<length-1;i++)
{
x[i]=x[i+1];
y[i]=y[i+1];
}
if(!Eat_Food(0))
{
x[length-1]=x[length-1]+addx;
y[length-1]=y[length-1]+addy;
}
}
}
void main()
{
char n;
Init_Snake_flag=0;
Init_Snake();
SPEED=50;
Level=1;
temp=0;
P0=0xff;
Init_Time();
stop_play();
Mode_flag=0;
while(1)
{
if (Mode_flag==0)
P0=0xfe;
else P0=0xf7;
if(addx!=0||addy!=0)
{
start_play();
}
else
{
stop_play();
Key_Scan();
}
if (Init_Snake_flag==1)
{
Init_Snake();
Init_Snake_flag=0;
}
Snake_Body();
Put_food();
if (Mode_flag==0)
{
if(temp==1)
{
Play_en=0;
P0=0x0c;
Init_Snake_flag=1;
if (Level==2) //判断是否碰撞,如果碰撞了则降一个级别
{
Level=1;
SPEED = 50;
}
else if (Level==3)
{
Level=2;
SPEED = 30;
}
else
{
Level=1;
SPEED = 50;
}
Sad_flag=1;
temp=0;
}
if(Sad_flag==1)
{
Sad();
}
if(Play_en==1)
{
P0=0xff;
Sad_flag=0;
}
}
}
}
void Timer0() interrupt 1
{
TH0 = 0xd8;
TL0 = 0xF0;
Wait_Time++;
Key_Scan();
if (Mode_flag==0)
{
Game_play();
Knock();
}
else
{
Game_play_super();
}
}