资源描述
//说明:该程序是基于freescale MCU、三轴加速度传感器、ili9320 LCD所写的贪食蛇游
//戏,上传代码拥有全部的设计思路以及大部分函数主体
//=================================================================
// 宏定义按键
//=================================================================
#define Key_Up 1
#define Key_Down 4
#define Key_Left 2
#define Key_Right 3
#define uchar unsigned char
//=================================================================
// 使用结构体定义变量 使程序的名称更加的清楚
//=================================================================
struct
{
uchar X;
uchar Y;
uchar Yes;
}Food; //食物结构体
#define SNAKE_Max_Long 20 //最大长度
struct
{
uchar X[SNAKE_Max_Long];
uchar Y[SNAKE_Max_Long];
uchar Long;
uchar Life;
uchar Score; //蛇的分数
uchar Level; //蛇的等级
}Snake; //蛇结构体
uchar Key_V_temp=0; //取出上次按键值
uchar Key_Value=0;
static int l=0;
static uint16 KEY_Init[3]={0,0,0};
static uint16 KEY_BASE[3]={0,0,0};
score[20]={"0","10","20","30","40","50","60","70","80","90","100","110","120","130","140","150","160","170","180","190"};
int level[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
static const byte Channels[] = {13,14,15}; /* Contents for the device control register */
static word MMA_7260_OutV[3];
static byte SumChan;
static byte OutFlg;
void MMA_7260_Init_3(void)
{
OutFlg = FALSE; /* No measured value */
/* ATD0CTL4: SMP2=0,SMP1=0,SMP0=0,PRS4=0,PRS3=0,PRS2=1,PRS1=0,PRS0=1 */
ATD0CTL4 = 5; /* Set sample time and prescaler */
/* ATD0CTL3: DJM=0,S8C=0,S4C=0,S2C=0,S1C=1,FIFO=0,FRZ1=0,FRZ0=0 */
ATD0CTL3 = 8; /* Set ATD control register 3 */
/* ATD0CTL0: ??=0,??=0,??=0,??=0,WRAP3=1,WRAP2=1,WRAP1=1,WRAP0=1 */
ATD0CTL0 = 15; /* Set wrap around */
/* ATD0CTL1: ETRIGSEL=0,SRES1=1,SRES0=0,SMP_DIS=1,ETRIGCH3=1,ETRIGCH2=1,ETRIGCH1=1,ETRIGCH0=1 */
ATD0CTL1 = 95; /* Set resolution and discharge */
/* ATD0CTL2: ??=0,AFFC=1,ICLKSTP=0,ETRIGLE=0,ETRIGP=0,ETRIGE=0,ASCIE=0,ACMPIE=0 */
ATD0CTL2 = 64; /* Set ATD control register 2 */
}
//-----------------------------------------------------
static void MMA_7260_Measure_3(void)
{
for (SumChan=0; SumChan<3; SumChan++) {
ATD0CTL5 = Channels[SumChan]; /* Start measurement of next channel */
while (!ATD0STAT0_SCF) {} /* Wait for AD conversion complete */
MMA_7260_OutV[SumChan] = ATD0DR0; /* Save measured value */
}
OutFlg = TRUE; /* Measured values are available */
}
//-----------------------------------------------------
byte MMA_7260_GetValue16_3(word *Values)
{
if (!OutFlg) { /* Is measured value(s) available? */
return 0; /* If no then error */
}
/* Note: Next 4 lines are speed optimized */
*Values++ = MMA_7260_OutV[0]; /* Save measured values to the output buffer */
*Values++ = MMA_7260_OutV[1]; /* Save measured values to the output buffer */
*Values++ = MMA_7260_OutV[2]; /* Save measured values to the output buffer */
OutFlg = FALSE;
return 1; /* OK */
}
//=================================================================
////////////////////////贪食蛇游戏/////////////////////////////////
//=================================================================
//函数名称:Trun_On_Point Trun_Off_Point (uchar x,uchar y)
//函数功能:点亮或者熄灭 一个点。用于显示蛇身体
//入口参数:无
//出口参数:无
//特别说明:此 Trun_On,函数换成其他的就可以兼容其他的液晶
// 入8*8 点阵 12864 等
//=================================================================
void Trun_On_Point (uchar x,uchar y,uchar color)
{
ili9320_Rectangle((4*(x+2)),(4*(y+2)),(4*(x+3)),(4*(y+3)),color,color);
//Bar((4*(x+2)),(4*(y+2)),(4*(x+3)),(4*(y+3)),color);
}
void Trun_Off_Point (uchar x,uchar y)
{
ili9320_Rectangle((4*(x+2)),(4*(y+2)),(4*(x+3)),(4*(y+3)),0xFFFF,0xFFFF);
}
//=================================================================
//函数名称:void Init_SNAKE(void)
//函数功能:绘制游戏界面,初始化游戏等级等参数
//入口参数:无
//出口参数:无
//=================================================================
void Init_SNAKE(void)
{
uchar i;
//***********获取方向基准********************//
MMA_7260_Init_3();
MMA_7260_Measure_3();
MMA_7260_GetValue16_3(&KEY_BASE);
//以下语句可以通过串口检验三轴加速度数据
/*
if(Flag) {
printp(" Get X Channel: %10D",KEY_BASE[0]);
printp(" Get Y Channel: %10D",KEY_BASE[1]);
printp(" Get Z Channel: %10D",KEY_BASE[2]);
}
*/
//***********绘制游戏界面********************//
ili9320_Rectangle(4, 4, 166, 206,0,0);
ili9320_Rectangle(5, 5, 167, 207,0,0);
ili9320_Rectangle(6, 6, 168, 208,0,0);
ili9320_Rectangle(5, 5, 169, 209,0,0);
ili9320_Rectangle(7, 7, 167, 207,0xFFFF,0xFFFF);//绘制一个矩形框,160*240
ili9320_Write_multi_HZ_ASCII(167+10,32,32,32,"少女32.FON","少符32.FON","07电信一",0xF800);
ili9320_Write_multi_HZ_ASCII(167+10,66,32,32,"少女32.FON","少符32.FON","郑友金",0xF800);
ili9320_Write_multi_HZ_ASCII(167+10,100,32,32,"少女32.FON","少符32.FON","贪食蛇",0xF800);
//***********初始化蛇参数********************//
Snake.Long=2; //定义初始化蛇的长度
Snake.Life=0; //初始化蛇还活着
Snake.Score=0;
Food.Yes=1;
Key_Value=0;
for(i=0;i<Snake.Long;i++) //将蛇给赋值
{
Snake.X[i]=i+10;
Snake.Y[i]=10;
}
for(i=0;i<Snake.Long;i++) //将蛇给画出来
{
Trun_On_Point(Snake.X[i],Snake.Y[i],0);
}
}
//=================================================================
//函数名称:void Display_dead(uchar i)
//函数功能:显示死亡界面
//入口参数:无
//出口参数:无
//=================================================================
void Display_dead(uchar i)
{
l=0;
Snake.Level=0;
ili9320_Text(7+30,7+40,"GAME OVER",9,0,0xffff);
ili9320_Delay(3000);
Init_SNAKE();
}
//=================================================================
//函数名称:void Display_Pass(uchar i)
//函数功能:显示过关界面
//入口参数:无
//出口参数:无
//=================================================================
void Display_Pass(uchar i)
{
l++;
Snake.Level++;
ili9320_Text(7+30,7+40,"YOU WIN",7,0,0xffff);
ili9320_Delay(3000);
Init_SNAKE();
}
//=================================================================
//函数名称:void Display_finish(uchar i);
//函数功能:显示通关界面
//入口参数:无
//出口参数:无
//=================================================================
void Display_finish(uchar i)
{
l=0;
Snake.Level=0;
ili9320_Text(7+30,7+40,"YOU WIN",7,0,0xffff);
ili9320_Text(7+30,7+80,"GAME FINISHED",13,0,0xffff);
ili9320_Delay(4000);
Init_SNAKE();
}
//=================================================================
//函数名称:void Run_SNAKE(void)
//函数功能:蛇运动函数
//入口参数:无
//出口参数:无
//=================================================================
void Run_SNAKE(void)
{
/*********************采用扫描MMA_7260方式确立方向*******************/
uchar i=0;
uint16 KEY_Init[4]={0,0,0,0};
//***********获取方向基准********************//
MMA_7260_Init_3();
MMA_7260_Measure_3();
MMA_7260_GetValue16_3(&KEY_Init);
//以下语句可以通过串口检验三轴加速度数据
/*
if(Flag) {
printp(" Get X1 Channel: %10D",KEY_Init[0]);
printp(" Get Y1 Channel: %10D",KEY_Init[1]);
printp("Get Z1 Channel: %10D",KEY_Init[2]);
printp(" Get X2 Channel: %10D",KEY_Init[0]-KEY_BASE[0]);
printp(" Get Y2 Channel: %10D",KEY_Init[1]-KEY_BASE[1]);
printp("Get Z2 Channel: %10D",KEY_Init[2]-KEY_BASE[2]);
}
*/
if((KEY_Init[0]-KEY_BASE[0])>500 && (KEY_Init[0]-KEY_BASE[0])<3000)Key_Value=Key_Left;
if((KEY_BASE[0]-KEY_Init[0])>500 && (KEY_BASE[0]-KEY_Init[0])<3000)Key_Value=Key_Right;
if((KEY_Init[1]-KEY_BASE[1])>500 && (KEY_Init[1]-KEY_BASE[1])<3000)Key_Value=Key_Up;
if((KEY_BASE[1]-KEY_Init[1])>500 && (KEY_BASE[1]-KEY_Init[1])<3000)Key_Value=Key_Down;
//Cpu_Delay100US(2100-Snake.Level*400);
/*********************方向取值完毕*******************/
/*********************根据按键选择蛇的运动方向*******************/
//if((Key_Value==Key_Right&&Key_V_temp!=Key_Left)||(Key_Value==Key_Left&&Key_V_temp==Key_Right))
if(Key_Value==Key_Right)
{ //1.蛇行不是左向,下步可以右向。2.蛇行右向,按左向无效,继续右向
Trun_Off_Point(Snake.X[0],Snake.Y[0]); //先把蛇尾给熄灭掉
for(i=0;i<Snake.Long-1;i++) //蛇身都是它前一段的蛇身的位置
{
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+1;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //蛇头向你要求的方向移动
for(i=0;i<Snake.Long;i++) //这个让蛇显示出来的函数
{
Trun_On_Point(Snake.X[i],Snake.Y[i],0xffff);
}
Key_Value=0;
// Key_V_temp=Key_Right;
}
//if((Key_Value==Key_Left&&Key_V_temp!=Key_Right)||(Key_Value==Key_Right&&Key_V_temp==Key_Left))
if(Key_Value==Key_Left)
{
Trun_Off_Point(Snake.X[0],Snake.Y[0]); //先把蛇尾给熄灭掉
for(i=0;i<Snake.Long-1;i++) //蛇身都是它前一段的蛇身的位置
{
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]-1;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //蛇头向你要求的方向移动
for(i=0;i<Snake.Long;i++) //这个让蛇显示出来的函数
{
Trun_On_Point(Snake.X[i],Snake.Y[i],0xffff);
}
Key_Value=0;
// Key_V_temp=Key_Left;
}
//if(( Key_Value==Key_Up&&Key_V_temp!=Key_Down)||( Key_Value==Key_Down&&Key_V_temp==Key_Up))
if( Key_Value==Key_Up)
{
Trun_Off_Point(Snake.X[0],Snake.Y[0]); //先把蛇尾给熄灭掉
for(i=0;i<Snake.Long-1;i++) //蛇身都是它前一段的蛇身的位置
{
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]-1; //蛇头向你要求的方向移动
for(i=0;i<Snake.Long;i++) //这个让蛇显示出来的函数
{
Trun_On_Point(Snake.X[i],Snake.Y[i],0xffff);
}
Key_Value=0;
//Key_V_temp=Key_Up;
}
//if(( Key_Value==Key_Down&&Key_V_temp!=Key_Up)||( Key_Value==Key_Up&&Key_V_temp==Key_Down))
if( Key_Value==Key_Down)
{
Trun_Off_Point(Snake.X[0],Snake.Y[0]); //先把蛇尾给熄灭掉
for(i=0;i<Snake.Long-1;i++) //蛇身都是它前一段的蛇身的位置
{
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+1; //蛇头向你要求的方向移动
for(i=0;i<Snake.Long;i++) //这个让蛇显示出来的函数
{
Trun_On_Point(Snake.X[i],Snake.Y[i],0xffff);
}
Key_Value=0;
// Key_V_temp=Key_Down;
}
/****************根据按键选择蛇的运动程序结束*******************/
/////////////////////////////////////////////////////////////////
/************************判断蛇是否死亡***********************/
if(Snake.X[Snake.Long-1]>=39||Snake.Y[Snake.Long-1]>=49)//判蛇头是否撞到墙壁
{
Snake.Life=1;
}
for(i=3;i<Snake.Long;i++)//从第三节开始判断蛇头是否咬到自己
{
if(Snake.X[i]==Snake.X[0]&&Snake.Y[i]==Snake.Y[0])
{
Snake.Life=1;
}
}
if(Snake.Life==1) //if the snake over
{
i=Key_Value;
Display_dead(i);
}
/******************判断蛇是否死亡程序结束***********************/
/////////////////////////////////////////////////////////////////
/******************判断游戏是否全部完成***********************/
/////////////////////////////////////////////////////////////////
if(Snake.Level==20) //if game finished
{
i=Key_Value;
Display_finish(i);
}
/************************判断蛇是否最长了**********************/
if(Snake.Long==SNAKE_Max_Long)
{
i=Key_Value;
Display_Pass(i);
}
/////////////////////////////////////////////////////////////////
/*************************判蛇是否吃到食物**********************/
if(Snake.X[Snake.Long-1]==Food.X&&Snake.Y[Snake.Long-1]==Food.Y)//
{
//Trun_Off_Point(Food.X,Food.Y); //消隐食物
Snake.Long++;//蛇节数加1
Snake.X[Snake.Long-1]=Food.X;
Snake.Y[Snake.Long-1]=Food.Y;
Snake.Score+=1;
//ili9320_Text(167+10,7+30,score[Snake.Score],3,0,0xffff);
//LCDShow_uCharNumber(96,24,Snake.Score,0xcc88,0xBE5F);
Food.Yes=1; //食物标志置1
}
/////////////////////////////////////////////////////////////////
/***************************放果子程序*************************/
if(Food.Yes==0)
{
Trun_On_Point(Food.X,Food.Y,0xffff);
}
if(Food.Yes==1)
{
while(1)
{
Food.X=(KEY_Init[0]+(KEY_Init[1]>>8))&0x0024-8; //获得随机数
Food.Y=(KEY_Init[2]+(KEY_Init[1]>>8))&0x002c-8;
for(i=0;i<Snake.Long;i++) //判断产生的食物坐标是否和蛇身重合
{
if((Food.X==Snake.X[i])&&(Food.X==Snake.Y[i]))
break;
}
if(i==Snake.Long)
{
Food.Yes=0;
break; //产生有效的食物坐标
}
}
}
/////////////////////////////////////////////////////////////////
/**************************延时用于调整游戏速度************************/
ili9320_Delay(550-level[l]*50);
/////////////////////////////////////////////////////////////////
}
//////////////////////////////////////////////////////////////////
//////////////////////////贪食蛇游戏//////////////////////////////
//////////////////////////////////////////////////////////////////
void MMA7260(void)
{
Init_SNAKE();
while(1)
{
Run_SNAKE();
}
}
展开阅读全文