📄 snake.c
字号:
/*-----------------------------------------------------------------------*/
//工程名:贪吃蛇
//描述:结合"61板"、键盘模组和液晶模组完成手机游戏贪吃蛇
// 键盘定义为1*8键盘
// 硬件接口IOA15-8接液晶数据线,IOA7-0接键盘,键盘另一端接高电平
// IOB4、IOB5、IOB6分别接A0、RWP、EP
//组成函数:main.c System.asm isr.asm sacm_user.asm sacmV32.asm
// spce.asm SPLC501DisplayTAB.asm SPLC501Hardware.asm
// Splc501sys.asm Splc501var.asm
//调用的库:
//日期:2005/01/13
//修改:2005/01/25
/*-----------------------------------------------------------------------*/
#define N 200 //定义贪吃蛇的节数
#define music 0x0001 //1*8键盘的键号值,功能:进入游戏带背景音乐/开启音乐
#define n_music 0x0002 //1*8键盘的键号值,功能:进入游戏不带背景音乐/关闭音乐
#define UP 0X0004 //1*8键盘的键号值,功能:向上
#define DOWN 0X0008 //1*8键盘的键号值,功能:向下
#define LEFT 0X0010 //1*8键盘的键号值,功能:向左
#define RIGHT 0X0020 //1*8键盘的键号值,功能:向右
#define QUIT 0X0040 //1*8键盘的键号值,功能:退出
extern unsigned int flag; //定义外部变量,标志位,用于等待
unsigned int random_num; //存储随机数,由于得到食物坐标
int i; //临时变量,用于循环
int no_music; //标志位,是否需要音乐
/*-----------------------------------------------------------------------*/
//定义结构体类型变量
struct Food //食物
{
int x; //食物的横坐标
int y; //食物的纵坐标
int yes; //是否需要食物,1表示需要,0表示不需要
}food;
struct Snake //蛇
{
int x[N]; //贪吃蛇的第N节横坐标
int y[N]; //贪吃蛇的第N节纵坐标
int node; //贪吃蛇的节数
int direction; //贪吃蛇的行动方向
int life; //贪吃蛇的生命,0表示活,1表示死
}snake;
/*-----------------------------------------------------------------------*/
//说明函数
/*-----------------------------------------------------------------------*/
//函数名称:GameOver()
//功能描述:贪吃蛇游戏结束,显示GameOver
//语法格式:void GameOver()
//入口参数;无
//出口参数:无
//注意事项:仅为用户模型
/*-----------------------------------------------------------------------*/
void GameOver()
{
LCD501_ClrScreen(0);//FG_ClearScreen(0); //调用液晶函数,清屏
//FG_SetLineStyle(2); //调用液晶函数,用实线填充
LCD501_Line(0,0,90,0);//FG_LineTo(0,0,90,0); //调用液晶函数,画直线
LCD501_Line(90,0,90,63);//FG_LineTo(90,0,90,63); //调用液晶函数,画直线
LCD501_Line(90,63,0,63);//FG_LineTo(90,63,0,63); //调用液晶函数,画直线
LCD501_Line(0,0,0,63);//FG_LineTo(0,0,0,63); //调用液晶函数,画直线
//FG_SetCharMode(0); //调用液晶函数,用实体输出
LCD501_FontSet(0);
LCD501_PutString(127,50,"snake"); //FG_PutStr("snake",small,127,50); //调用液晶函数,输出SNAKE
LCD501_FontSet(1);
LCD501_PutString(85,40,"GameOver!!");//FG_PutStr("GameOver!!",large,85,40);//调用液晶函数,输出GameOver!!
//for(;;) //程序停在此处
//{
*P_Watchdog_Clear=0x0001; //清看门狗
//}
}
/*-----------------------------------------------------------------------*/
//函数名称:GamePlay()
//功能描述:贪吃蛇游戏人机界面,具体操作与游戏
//语法格式:void GamePlay()
//入口参数;无
//出口参数:无
//注意事项:仅为用户模型
/*-----------------------------------------------------------------------*/
void GamePlay()
{
food.yes=1; //初始化,屏幕上需要食物
snake.life=0; //初始化,蛇活
snake.direction=4; //初始化,蛇向右行动
snake.x[0]=60; //初始化,蛇头的位置,横坐标
snake.y[0]=50; //初始化,蛇头的位置,纵坐标
snake.x[1]=61;
snake.y[1]=50;
snake.x[2]=62;
snake.y[2]=50;
snake.x[3]=63;
snake.y[3]=50;
snake.node=4; //初始化,蛇的节数
///////////////////////////////////////////////
/* if(no_music==1)
{
SACM_A2000_Initial(Auto); //初始化A2000
SACM_A2000_Play(0,3,3); //放音
}
Reset_Int();*/ //重新设置中断
while(1)
{
if(no_music==1)
{
if((SACM_A2000_Status()&0x01) == 0) //判断语音是否播放结束 函数包含在Sacmv32.lib
SACM_A2000_Play(0,DAC1+DAC2,Ramp_Up_On+Ramp_Dn_On);//语音播放 函数包含在Sacmv32.lib
}
K_code=0x0000; //清除上次键值
System_ServiceLoop(); //扫描键盘,获得按键值
*P_Watchdog_Clear=0x0001; //清看门狗
random_num=*P_TimerB_Data; //获得随机数
if(food.yes==1) //需要食物
{
food.x=random_num%88+2; //获得食物横坐标
food.y=random_num%61+2; //获得食物纵坐标
food.yes=0; //清除需要食物标志
}
if(food.yes==0)
{
FG_SetRectStyle(3); //在屏幕上画出食物
FG_Rectangle(food.x,food.y,food.x+1,food.y+1);
}
if(K_code==QUIT) //如果键值为退出键,结束游戏
break;
if(K_code==n_music) //关闭背景音乐
{
SACM_A2000_Stop(); //停止播放
no_music=0; //清除标志
}
if(K_code==music) //开启背景音乐
{
SACM_A2000_Initial(Auto); //初始化放音函数
SACM_A2000_Play(0,3,3); //播放音乐
no_music=1; //设置标志位
}
//1表示向上,2表示向下,3表示向左,4表示向右
else if(K_code==UP&&snake.direction==3) //键值为向上,贪吃蛇向左行动
snake.direction=1; //贪吃蛇向上行动
else if(K_code==UP&&snake.direction==4) //键值为向上,贪吃蛇向右行动
snake.direction=1; //贪吃蛇向上行动
else if(K_code==DOWN&&snake.direction==3) //键值为向下,贪吃蛇向左行动
snake.direction=2; //贪吃蛇向下行动
else if(K_code==DOWN&&snake.direction==4) //键值为向下,贪吃蛇向右行动
snake.direction=2; //贪吃蛇向下行动
else if(K_code==LEFT&&snake.direction==1) //键值为向左,贪吃蛇向上行动
snake.direction=3; //贪吃蛇向左行动
else if(K_code==LEFT&&snake.direction==2) //键值为向左,贪吃蛇向下行动
snake.direction=3; //贪吃蛇向左行动
else if(K_code==RIGHT&&snake.direction==1) //键值为向右,贪吃蛇向上行动
snake.direction=4; //贪吃蛇向右行动
else if(K_code==RIGHT&&snake.direction==2) //键值为向右,贪吃蛇向下行动
snake.direction=4; //贪吃蛇向右行动
////////////////////
if(snake.x[0]<0||snake.x[0]>90||snake.y[0]>63) //判断蛇是否撞到边框
{
FG_ClearScreen(0);
GameOver(); //游戏结束
snake.life=1; //蛇死
}
if(snake.y[0]<1)
{
FG_ClearScreen(0);
GameOver(); //游戏结束
snake.life=1; //蛇死
}
for(i=3;i<snake.node;i++)
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]) //判断蛇是否撞到自己
{
GameOver();
snake.life=1;
}
}
//注意贪吃蛇不能向相反方向行动
if(flag==1) //延时更新画面,flag在中断中改变用于延时
{
flag=0; //清中断标志
//画贪吃蛇,贪吃蛇关键算法
switch(snake.direction) //根据行动方向改变蛇头位置
{
case 1:snake.y[0]+=1; //1表示向上
break;
case 2:snake.y[0]-=1; //2表示向下
break;
case 3:snake.x[0]+=1; //3表示向左
break;
case 4:snake.x[0]-=1; //4表示向右
break;
}
FG_SetRectStyle(3); //用实体画线
for(i=0;i<snake.node;i++) //循环画出蛇
FG_Rectangle(snake.x[i],snake.y[i],snake.x[i]+1,snake.y[i]+1);
FG_ClearRect(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+1,snake.y[snake.node-1]+1);
//关键:擦除蛇尾
for(i=snake.node-1;i>0;i--)
{
snake.x[i]=snake.x[i-1]; //移动各节蛇的坐标
snake.y[i]=snake.y[i-1];
}
/////////////////////////////
//重新设置中断
Reset_Int();
}
if(snake.life==1) //蛇死
break; //跳出PlayGame函数
if(snake.x[0]==food.x&&snake.y[0]==food.y) //蛇吃到食物
{
FG_SetRectStyle(0);
FG_ClearRect(food.x,food.y,food.x+1,food.y-1);//擦掉食物
snake.node++; //蛇节数加一节
food.yes=1; //需要食物
}
*P_Watchdog_Clear=0x00001;
}
}
/*-----------------------------------------------------------------------*/
//函数名称:Draw()
//功能描述:画贪吃蛇初始界面
//语法格式:void Draw()
//入口参数;无
//出口参数:无
//注意事项:仅为用户模型
/*-----------------------------------------------------------------------*/
void Draw()
{
FG_ClearScreen(0); //调用液晶函数,清屏
//FG_SetLineStyle(2); //调用液晶函数,用实线填充
FG_LineTo(0,0,90,0); //调用液晶函数,画直线
FG_LineTo(90,0,90,63); //调用液晶函数,画直线
FG_LineTo(90,63,0,63); //调用液晶函数,画直线
FG_LineTo(0,0,0,63); //调用液晶函数,画直线
FG_SetCharMode(0); //调用液晶函数,用实体输出
FG_PutStr("snake",small,127,50); //调用液晶函数,输出small:
}
/*-----------------------------------------------------------------------*/
//函数名称:Welcome_Init()
//功能描述:在开机时显示画面
//语法格式:void Welcome_Init()
//入口参数;无
//出口参数:无
//注意事项:仅为用户模型
/*-----------------------------------------------------------------------*/
void Welcome_Init()
{
FG_ClearScreen(0); //调用液晶函数,清屏
FG_SetLineStyle(2); //调用液晶函数,用实线填充
FG_LineTo(0,0,127,0); //调用液晶函数,画直线
FG_LineTo(127,0,127,63); //调用液晶函数,画直线
FG_LineTo(0,63,127,63); //调用液晶函数,画直线
FG_LineTo(0,0,0,63); //调用液晶函数,画直线
FG_SetCharMode(0); //调用液晶函数,用实体输出
for(i=0;i<0x007e;i++)
{
FG_PutStr("Welcome Play Game",small,121,50); //调用液晶函数,输出
*P_Watchdog_Clear=0x00001; //清看门狗
}
FG_ClearScreen(0); //清屏
while(1)
{
FG_PutStr("Play with music",small,121,50); //输出字符
FG_PutStr("press 1",small,121,40); //输出字符
FG_PutStr("Play without music",small,121,30); //输出字符
FG_PutStr("press 2",small,121,20); //输出字符
*P_Watchdog_Clear = 0x0001; //清看门狗
K_code=0x0000; //清除上次键值
System_ServiceLoop(); //扫描键盘
if(K_code ==0x0002) //进入游戏带背景音乐
break;
if(K_code ==0x0001) //进入游戏不带背景音乐
{
no_music=0;
break;
}
}
}
/*-----------------------------------------------------------------------*/
//函数名称:main()
//功能描述:主函数
//语法格式:void main()
//入口参数;无
//出口参数:无
//注意事项:仅为用户模型
/*-----------------------------------------------------------------------*/
/*
void main()
{
no_music = 1; //初始化标志位
Init_sys(); //初始化液晶
FG_InitGraphic(); //初始化液晶接口函数
Set_TimerB(); //开启定时器,为得到随机数做准备
Set_Int(); //设置中断
Welcome_Init(); //设置开机画面
Draw(); //画贪吃蛇
GamePlay(); //玩游戏
GameOver(); //游戏结束
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -