#include <REG52.H>
sbit sound=P2^7; //这个是接峰鸣器
sbit rs = P2^0; //H=data; L=command;
sbit rw = P2^1; //H=read; L=write;
sbit e = P2^2; //input enable;
sbit busy=P0^7; //lcd busy bit
/*---------这里是液晶的一些命令定的控制字-----------8*/
#define com_expand_command 0x40
#define base_command 0x34
#define oppsite_cursor_dec 0x10
#define open_display_oppsite 0x0D
#define clear_screen 0x01
/*------下面的这些反白指令没有什么用处!--------*/
#define oppsite_first_line 0x04
#define oppsite_second_line 0x05
#define oppsite_third_line 0x06
#define oppsite_forth_line 0x07
/*------上面的这些反白指令没有什么用处!--------*/
/*-------------这里是定义那个绘图时设置地址时用的------*/
#define X1_ADDRESS 0x80
#define X2_ADDRESS 0x88
#define Y_ADDRESS 0x80
/*******-----这里用来向LCD定入数据时区分命令和数据的-----*/
#define comm 0 //命令
#define dat 1 //数据!
#define uint unsigned int
#define uchar unsigned char
#define uchar unsigned char
/*-----键盘扫描码定义------------------*/
#define DOWN_DOWN 0xe0 //第一键
#define UP_DOWN 0xd0 //第二键
#define RIGHT_DOWN 0xb0 //
#define LEFT_DOWN 0x70 //
/*------------屏上区域定义区---------------*/
#define RIGHT_MAX 31
#define DOWN_MAX 15
#define UP_MAX 0
#define LEFT_MAX 0
/*------------定义游戏状态--------------*/
#define GAME_OVER 0 //游戏结束了
#define GAME_RUNING 1 //游戏进行中
#define WAIT_FOR_USER_INPUT 3 //等待用户输入
#define GAME_WELCOME_SCREEN 4 //
#define SHOW_YOUR_RECORD 5//这个状态就是当游戏结束以后显示你的成绩
/*--------------方向定义----------------*/
#define RIGHT 0
#define LEFT 1
#define DOWN 2
#define UP 3
/*--------------定义屏幕序列号------------------*/
#define WELCOME_SCREEN 0 //第一个欢迎屏
#define WAITE_IN_PUT 1 //这是等待玩家选关的
#define YOUR_RECORD 2 //这个屏是当玩家OVER后显示他分数
#define CONGRATULATE 3 //这个是当玩家玩完一关后进入下一关时显示的
/*---------------------------*/
#define SNAKE_LONG 16 //定义蛇长
#define DEFAULT_SPEED 5//定义蛇的默认速度
#define X_POT 0
#define Y_POT 1 //蛇身是一个2维数组0是放X1放Y
#define MAX_RECORD 15//这个是定义当多少分时就进入下一关
/*---------定义一种结构体---------*/
struct postion
{
uchar x;
uchar y ;
};//这个结构体是用来表示一些点的数据
//*-----这个结构休是用来保存一些蛇改变方向时的数据它是有蛇前进时要用来删除尾巴时要用到-----*/
//这三点分别是头,尾,和食物
struct Snake
{
uchar Snake_body[SNAKE_LONG][2]; //其0为头15为尾
uchar direction;
uchar Speed;///速度这是由用户设定的
uchar Game_Mode; //这个是游戏的状态如如进行中,结速了等
struct postion Temp_Pot_Or_Last_Trail;//这里蛇在前进时用暂存数据的移过后这个里面就是上次蛇尾所在的点
uchar soft_conter;//这个是软件计数器 用来计数T1的中断次数,到了一定数值时就让蛇前进一步
uchar Current_screen_num; //这个是用来保存当前所显示的屏
uchar Currrent_Position;//保存光标所在的位置
uchar Screen_data[2][4];//这个是更新屏上的数据时,重构数据所使用的缓存
struct postion Food_Postion;//这个是食物的位置
uchar Record;//游戏得分数
} ;
uchar code NO_Data[10]={"0123456789"};//{"0","1","2","3","4","5","6","7","8","9"};
/*----------------这个地方是输出到屏上面的数据--------------*/
uchar code screen_data[][64]={
{" 综合程序 "
"开发:Crasyboye "
" 游戏--贪吃蛇 "
" 按任意键继续 "
},//第一屏
{
" "
" 第: 关"
" 请您选关 "
"增加/ 减少 确定"
},
///////////////////////////
{"您的得分为: "
" 继续努力 "
" "
" 按任意键继续 "
},
{" "
"恭喜!您顺利过关"
" 马上进下一关 "
" 按任意键继续 "
}
};
/*-----变量定义--------*/
struct Snake My_snake;
unsigned char KEY_WORD;
bit KEY_DOWN; //这个用来表示键位有按下了
/*----------函数声明-------------*/
void inicial_timer () ; /*--------初始化两个定时器----------*/
void voice_function() ; /*------发音子程序-------*/
/*---------确认某一点是否有有障碍物-----------*/
bit Sure_Postion_Have_pot(uchar row,uchar line); //row是行line是列
void Go_Ahead(); //这个函数用来使蛇向前前进一步
bit Sure_Pot_Empty(uchar x,uchar y); /*------------ 确认某一点是否是空点------------------*/
void One_Step();///这个函数里蛇走一步的
void wr_lcd (bit dat_comm,uchar content); /*-------------------写数据或指令到LCD-------------*/
void init_lcd (void); //初始化定时器
void chk_busy (void); /*---------------检测忙信号----------------*/
void Erasure(); //擦除屏幕函数 这是在绘图模式下
void delay_ms(unsigned int ms);////延时毫秒级的
void Erasure_Trail(); //擦尾
void Draw_Head();//画头
void Creat_Food();//产生一个食物并且检测食物是不是产生在蛇的身上如果是重新产生
void Re_Build_Food_Buffer(uchar x,uchar y);//这个是用来重构缓存数据
void Write_Food();//把食物画到屏上
void Inicial_Game();////p初始化游戏
void display_all_screen (uchar screen_num);//显示一整屏
void Show_Your_Record();//显示你的成绩
/*------键盘扫描也是中T0中断函数--------*/
void inter_timer0() interrupt 1
{
unsigned char b;
TR0=0;
P1=0xff;
b=P1;
b=b&0xf0;
if(b!=0xf0)
{
KEY_DOWN=1;
KEY_WORD=b;
voice_function();
}
while(b!=0xf0) //这个地方是用来消抖的
{
b=P1;
b=b&0xf0;
}
TR0=1;
}
/*--------初始化定时器----------*/
void inicial_timer ()
{
TMOD=0x11;
EA=1;
TR0=1;
TR1=1;
ET0=1;
ET1=1;
}
/*=----------这是定时器1的中断用来做为游戏的系系时钟------*/
void inter_timer1() interrupt 3
{
TR1=0;
TR0=0;
if(My_snake.soft_conter>=9-My_snake.Speed)
{
My_snake.soft_conter=0;
if(My_snake.Game_Mode==GAME_RUNING)
{
One_Step();
Erasure_Trail();
Draw_Head();
// Write_Food();
if(My_snake.Snake_body[0][Y_POT]==My_snake.Food_Postion.y&&My_snake.Snake_body[0][X_POT]==My_snake.Food_Postion.x)
{
Creat_Food();//产生一个食物并且检测食物是不是产生在蛇的身上如果是重新产生
Write_Food();
My_snake.Record++;
}
}
else My_snake.soft_conter++;
}
else My_snake.soft_conter++;
if(My_snake.Game_Mode==GAME_OVER)
{
Show_Your_Record();
}
TR1=1;
TR0=1;
}
/*------发音子程序-------*/
void voice_function()
{
int c,e,d;
for(d=0;d<1;d++)
{
for (c=0;c<50;c++)
for(e=0;e<100;e++)
sound=0;
}
sound=1;
}
/*---------确认某一点是否有有障碍物-----------*/
bit Sure_Postion_Have_pot() //row是行line是列
{
return 1;
}
/**-------------------这个是用来让蛇向前面一步-------------------**/
void Go_Ahead()
{
uchar i,temp_x,temp_y;
switch (My_snake.direction)
{
case RIGHT:
{
for(i=0;i<SNAKE_LONG;i++)
{
if(i==0)
{
My_snake.Temp_Pot_Or_Last_Trail.x=My_snake.Snake_body[0][X_POT];
My_snake.Temp_Pot_Or_Last_Trail.y=My_snake.Snake_body[0][Y_POT];
My_snake.Snake_body[0][X_POT]++;
} //如果是第一个点就X++
else
{
temp_x=My_snake.Snake_body[i][X_POT];
temp_y=My_snake.Snake_body[i][Y_POT];
My_snake.Snake_body[i][Y_POT]=My_snake.Temp_Pot_Or_Last_Trail.y;
My_snake.Snake_body[i][X_POT]=My_snake.Temp_Pot_Or_Last_Trail.x;
My_snake.Temp_Pot_Or_Last_Trail.x=temp_x;
My_snake.Temp_Pot_Or_Last_Trail.y=temp_y;
}
}
return;
}
/*----------------------------------------------------------------------------*/
case LEFT:
{
for(i=0;i<SNAKE_LONG;i++)
{
i