贪吃蛇实验
更新时间:2023-10-30 01:15:01 阅读量: 综合文库 文档下载
实验:贪吃蛇
一、实验目的
1.运用所学过的单片机知识,编写简单的贪吃蛇游戏; 2.学会单片机大部分功能的运用。 二、实验原理 1. TFT 彩屏工作原理
TFT(Thin Film Transistor)LCD 即薄膜场效应晶体管LCD,是有源矩阵类型液晶显示器(AM-LCD)中的一种。和TN 技术不同的是,TFT 的显示采用“背透式”照射方式——假想的光源路径不是像TN 液晶那样从上至下,而是从下向上。这样的作法是在液晶的背部设置特殊光管,光源照射时通过下偏光板向上透出。由于上下夹层的电极改成FET 电极和共通电极,在FET 电极导通时,液晶分子的表现也会发生改变,可以通过遮光和透光来达到显示的目的,响应时间大大提高到80ms 左右。因其具有比TN LCD 更高的对比度和更丰富的色彩,荧屏更新频率也更快,故TFT 俗称“真彩”。
LCD 是由二层玻璃基板夹住液晶组成的,形成一个平行板电容器,通过嵌入在下玻璃基板上的TFT 对这个电容器和内置的存储电容充电,维持每幅图像所需要的电压直到下一幅画面更新。液晶的彩色都是透明的必须给LCD 衬以白色的背光板上才能将五颜六色表达出来,而要使白色的背光板有反射就需要在四周加上白色灯光。因此在TFT LCD 的底部都组合了灯具,如CCFL 或LED。
2.矩阵按钮
矩阵按键又称为行列式按键,他是用4 条I/O 线作为行线,4 条I/O 线作为列线组成的按键,在行线和列线的每一个交叉点上,设置一个按键。如图所示,
按键识别原理:
在某一时刻只让一条列线处于低电平,其余列线均处于高电平,则当这一列有键按下时,该键所在的行电平将会由高电平变为低电平,可判定该列相应的行
有键按下。当第0 列处于低电平时,逐行查找是否有行线变低,若有,则第0 列与该行的交叉点按键按下;若无,则表示第0 列无键按下,再让下一列处在低电平,依此循环,这种方式称为键盘扫描。
3.贪吃蛇操作原理
贪吃蛇本身是由好几个点连成的一条线段,只要通过延时函数使线段在时间前后往指定的方向进一步就行了,即将所有线段上的点往指定方向移动一段,就会出现贪吃蛇的基本运动。贪吃蛇的方向可以通过设置几个指定的按钮来控制。
贪吃蛇吃的食物那个点可以由随机函数rand()产生一个随机数组,再每次显示一个数组里的点就可以达到预计的随机点。
最后再通过判断边界,输赢条件,使程序更加完善,界面美观。 三、实验代码。
#include
#include\ #include\ #include\ #include\
#include\
// Provide a definition for M_PI, if it was not provided by math.h. #ifndef M_PI
#define M_PI 3.14159265358979323846F #endif
uint16_t sc; //长度
unsignedint k=0,start=0,s=3000; //k按键数,start开始键 unsignedint sum=0;//吃到的食物数量
//********************************************************************* uint32_t g_ui32SysClock;
staticvolatileunsignedlong g_ulTickCount; #define SERIES_LENGTH 240
typedefstruct _snack {
uint32_tx; uint32_ty; }ssnack;
staticssnack snack[40],a[50];//a为随机数 staticssnack food;//食物
voidTFTLCD_DrawLine(ssnack sk1,ssnack sk2,uint32_t color) // 画蛇线段 {
uint32_t i=0,PointNum = 0; if(sk1.x==sk2.x) //沿Y方向画线 {PointNum = abs(sk1.y-sk2.y); if(sk1.y<=sk2.y) {
for(i=0;i TFTLCD_DrawPoint(sk1.x,sk1.y+i,color); } } Else { for(i=0;i } } { TFTLCD_DrawPoint(sk1.x,sk2.y+i,color); } elseif (sk1.y==sk2.y)//沿X方向画线 {PointNum = abs(sk1.x-sk2.x); if(sk1.x<=sk2.x) { } else { } } } void SnackInit(void) //对蛇进行初始化 { uint32_t i; snack[0].x=50; snack[0].y=50; for(i=1;i<=5;i++) { snack[i].x=50; snack[i].y=50+10*i; TFTLCD_DrawLine(snack[i-1],snack[i],GREEN); for(i=0;i { TFTLCD_DrawPoint(sk2.x+i,sk2.y,color); } for(i=0;i TFTLCD_DrawPoint(sk1.x+i,sk2.y,color); } TFTLCD_DrawHorizontalLine(0,240,340,GREEN); } void SnackDown(void) // 往下走 { uint32_t n; TFTLCD_DrawLine(snack[1],snack[0],BLACK); SysCtlDelay(500*(20000000/s));//2 for(n=0;n snack[n]=snack[n+1]; } snack[sc].y=snack[sc].y+10; TFTLCD_DrawLine(snack[sc-1],snack[sc],GREEN); SysCtlDelay(500*(20000000/s));//2 } void SnackRight(void)//往右走 { uint32_t n,j; j=sc-1; TFTLCD_DrawLine(snack[1],snack[0],BLACK); SysCtlDelay(500*(20000000/s));//2 for(n=0;n<=j;n++) { snack[n]=snack[n+1]; } snack[sc].x=snack[sc].x+10; TFTLCD_DrawLine(snack[j],snack[sc],GREEN); SysCtlDelay(500*(20000000/s));//2 } void SnackLeft(void) //往左走 { uint32_t n,j; j=sc-1; TFTLCD_DrawLine(snack[1],snack[0],BLACK); SysCtlDelay(500*(20000000/s));//2 for(n=0;n<=j;n++) { snack[n]=snack[n+1]; } snack[sc].x=snack[sc].x-10; TFTLCD_DrawLine(snack[j],snack[sc],GREEN); SysCtlDelay(500*(20000000/s));//2 } void SnackUp(void)//往上走 { uint32_t n,j; j=sc-1; TFTLCD_DrawLine(snack[1],snack[0],BLACK); SysCtlDelay(500*(20000000/s));//2 for(n=0;n<=j;n++) { snack[n]=snack[n+1]; } snack[sc].y=snack[sc].y-10; TFTLCD_DrawLine(snack[j],snack[sc],GREEN); SysCtlDelay(500*(20000000/s));//2 } //***************************************************************************** #define TICKS_PER_SECOND 40 #define FSECONDS_PER_TICK (1.0F / (float)TICKS_PER_SECOND) //***************************************************************************** void SysTickIntHandler(void) { g_ulTickCount++; if(g_ulTickCount>=320) g_ulTickCount = 0; } //***************************************************************************** void ConfigureUART(void) { // // Enable the GPIO Peripheral used by the UART. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Enable UART0 SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Configure GPIO Pins for UART mode. GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Initialize the UART for console I/O. UARTStdioConfig(0, 115400, g_ui32SysClock); } volatileuint32_t ui32Loop; volatileuint32_t key; voiddelay() { int ui32Loop0; for(ui32Loop0=0;ui32Loop0<1000;ui32Loop0++) //delay {;} } intidentify_key()// 按钮的控制 { key=0; GPIO_PORTD_AHB_DATA_R = 0x00; GPIO_PORTH_AHB_DATA_R = 0x0c; GPIO_PORTM_DATA_R = 0x08; for(ui32Loop=0;ui32Loop<1000;ui32Loop++) //delay { } if((GPIO_PORTN_DATA_R&0x08)==0x00) { } GPIO_PORTD_AHB_DATA_R = 0x02; GPIO_PORTH_AHB_DATA_R = 0x04; GPIO_PORTM_DATA_R = 0x08; for(ui32Loop=0;ui32Loop<1000;ui32Loop++) { } if((GPIO_PORTP_DATA_R&0x04)==0x00)//&&(GPIO_PORTP_DATA_R==0x04) { } delay(); if((GPIO_PORTP_DATA_R&0x04)==0x00) { } key=2; return 0; ; delay(); if((GPIO_PORTN_DATA_R&0x08)==0x00) { } key=5; return 0; ; else if((GPIO_PORTN_DATA_R&0x08)==0x00) { } delay(); if((GPIO_PORTN_DATA_R&0x08)==0x00) { } key=6; return 0; else if((GPIO_PORTN_DATA_R&0x04)==0x00) { } delay(); if((GPIO_PORTN_DATA_R&0x04)==0x00) { } key=10; return 0; GPIO_PORTD_AHB_DATA_R = 0x02; GPIO_PORTH_AHB_DATA_R = 0x08; GPIO_PORTM_DATA_R = 0x08; for(ui32Loop=0;ui32Loop<1000;ui32Loop++) { } if((GPIO_PORTN_DATA_R&0x08)==0x00) } delay(); if((GPIO_PORTN_DATA_R&0x08)==0x00) { } key=7; return 0; { ; return 1; } void pingmu(void) //进入游戏时显示等待及操作提醒 { uint32_t mb=0; TFTLCD_ShowString(30,120,\,WHITE,BLACK); TFTLCD_ShowString(30,160,\,WHITE,BLACK); TFTLCD_ShowString(30,140,\,WHITE,BLACK); for(mb=0;mb<=10;mb++) { SysCtlDelay(500*(20000000/3000));//2 } TFTLCD_ShowString(30,160,\,WHITE,BLACK); for(mb=0;mb<=10;mb++) { SysCtlDelay(500*(20000000/3000));//2 } TFTLCD_ShowString(30,160,\,WHITE,BLACK); for(mb=0;mb<=10;mb++) { SysCtlDelay(500*(20000000/3000));//2 } TFTLCD_ShowString(30,160,\,WHITE,BLACK); for(mb=0;mb<=10;mb++) { SysCtlDelay(500*(20000000/3000));//2 } TFTLCD_FillBlock(0, 240, 0, 400, BLACK); TFTLCD_DrawHorizontalLine(120,150,220,GREEN);//往下的按钮 TFTLCD_DrawHorizontalLine(120,150,250,GREEN); TFTLCD_DrawVerticalLine(220,250,120,GREEN); TFTLCD_DrawVerticalLine(220,250,150,GREEN); TFTLCD_ShowString(125,230,\,WHITE,BLACK); TFTLCD_DrawHorizontalLine(120,150,170,GREEN);//中间按钮 TFTLCD_DrawHorizontalLine(120,150,200,GREEN); TFTLCD_DrawVerticalLine(170,200,120,GREEN); TFTLCD_DrawVerticalLine(170,200,150,GREEN); TFTLCD_ShowString(125,180,\,WHITE,BLACK); TFTLCD_DrawHorizontalLine(120,150,120,GREEN);//往上按钮 TFTLCD_DrawHorizontalLine(120,150,150,GREEN); TFTLCD_DrawVerticalLine(120,150,120,GREEN); TFTLCD_DrawVerticalLine(120,150,150,GREEN); TFTLCD_ShowString(125,130,\,WHITE,BLACK); TFTLCD_DrawHorizontalLine(70,100,170,GREEN);//往左按钮 TFTLCD_DrawHorizontalLine(70,100,200,GREEN); TFTLCD_DrawVerticalLine(170,200,70,GREEN); TFTLCD_DrawVerticalLine(170,200,100,GREEN); TFTLCD_ShowString(75,180,\,WHITE,BLACK); TFTLCD_DrawHorizontalLine(170,200,170,GREEN);//往右按钮 TFTLCD_DrawHorizontalLine(170,200,200,GREEN); TFTLCD_DrawVerticalLine(170,200,170,GREEN); TFTLCD_DrawVerticalLine(170,200,200,GREEN); TFTLCD_ShowString(175,180,\,WHITE,BLACK); SysCtlDelay(1000*(20000000/100));// TFTLCD_FillBlock(0, 240, 0, 400, BLACK); } void Rand()//产生一个随机数组 { uint32_t i; srand((unsigned) time(NULL)); for(i=0;i<50;i++) { a[i].x=rand()*10 % 200+20;//20~220 a[i].y=rand()*10 % 300+40;//20~340 } } voidmain() { sc=5;//蛇长度 uint32_t j,i; uint32_t num=0;//随机数组的编号 SYSCTL_RCGCGPIO_R |= ( SYSCTL_RCGCGPIO_R13 | SYSCTL_RCGCGPIO_R12 | SYSCTL_RCGCGPIO_R11 |SYSCTL_RCGCGPIO_R10| SYSCTL_RCGCGPIO_R7 | SYSCTL_RCGCGPIO_R3 ); GPIO_PORTN_DIR_R = 0x03; GPIO_PORTM_DIR_R = 0x28; GPIO_PORTH_AHB_DIR_R = 0x0c; GPIO_PORTP_DIR_R = 0x00; GPIO_PORTD_AHB_DIR_R = 0x02; //GPIO_PORTF_AHB_DIR_R = 0x11; GPIO_PORTL_DIR_R = 0x0f; GPIO_PORTN_DEN_R = 0x0f; GPIO_PORTM_DEN_R = 0x28; GPIO_PORTH_AHB_DEN_R = 0x0c; GPIO_PORTP_DEN_R = 0x04; GPIO_PORTD_AHB_DEN_R = 0x03; GPIO_PORTL_DEN_R = 0x0f; //uint32_t mb=0; // The FPU should be enabled because some compilers will use floating- // point registers, even for non-floating-point code. If the FPU is not // enabled this will cause a fault. This also ensures that floating- // point operations could be added to this anumlication and would work // correctly and use the hardware floating-point unit. Finally, lazy // stacking is enabled for interrupt handlers. This allows floating- // point instructions to be used within interrupt handlers, but at the // expense of extra stack usage. FPUEnable(); FPULazyStackingEnable(); // Run from the PLL at 120 MHz. g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // // Enable interrupts to the processor. // IntMasterEnable(); // // Enable the SysTick Interrupt. // SysTickIntEnable(); // // Enable SysTick. // SysTickEnable(); ConfigureUART(); EPIGPIOinit(); TFT_400x240_OTM4001Ainit(g_ui32SysClock); // Open BackLight. GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_PIN_0); pingmu(); IntMasterEnable(); Rand();//根据系统时间产生随机数 //食物点初始化 food.x=50; food.y=200; //蛇初始化 SnackInit(); while(1) { TFTLCD_DrawPoint(food.x,food.y,WHITE); //在屏幕下方显示吃到的食物的个数 TFTLCD_ShowString(0,350,\,WHITE,BLACK); TFTLCD_ShowData(180,350,sum,WHITE,BLACK); //判断,蛇头不能碰到蛇身 for(i=0;i if(snack[sc].x==snack[i].x&&snack[sc].y==snack[i].y) { TFTLCD_FillBlock(1, 240, 0, 400, BLACK); } TFTLCD_ShowString(50,150,\,WHITE,BLACK); SysCtlDelay(1000*(20000000/300)); TFTLCD_FillBlock(1, 240, 0, 400, BLACK); SnackInit(); start=0; sc=5; k=0; s=300; sum=0; } if(start!=1) { //开始游戏提示 } identify_key(); if(key==6) start=1; //判断方向,防止反向运行 if(key!=0) { if((k==5||k==6)&&key==7) k=5; TFTLCD_ShowString(60,120,\,WHITE,BLACK); TFTLCD_ShowString(55,160,\,WHITE,BLACK); TFTLCD_ShowString(55,200,\,WHITE,BLACK); identify_key(); if(key==6) { TFTLCD_FillBlock(0, 240, 0, 400, BLACK); SnackInit(); } else if(k==7&&key==5) k=7; else } if(k==2&&key==10) k=2; else if(k==10&&key==2) k=10; else k=key; if(start==1) { if(sum>= 10)//吃到十个食物时判定为游戏成功 { TFTLCD_FillBlock(1, 240, 0, 400, BLACK); //清屏 TFTLCD_ShowString(50,150,\,WHITE,BLACK); SysCtlDelay(1000*(20000000/300)); TFTLCD_FillBlock(1, 240, 0, 400, BLACK); SnackInit(); start=0; sc=5; k=0; s=300; sum=0; } if(k==5||k==6)//按下N5按钮或开始游戏时向下走 { SnackDown(); if(snack[sc].x==food.x&&snack[sc].y==food.y) { j=sc; sc=sc+1; snack[sc].x=snack[j].x; snack[sc].y=snack[j].y+10; TFTLCD_DrawLine(snack[j],snack[sc],GREEN); food.x=a[num].x; food.y=a[num].y; TFTLCD_DrawPoint(food.x,food.y,WHITE); num=num+1; s+=400; sum++; } if(snack[sc].x==0||snack[sc].x==240||snack[sc].y==0||snack[sc].y==340) { TFTLCD_FillBlock(1, 240, 0, 400, BLACK); TFTLCD_ShowString(50,150,\,WHITE,BLACK); SysCtlDelay(1000*(20000000/300)); TFTLCD_FillBlock(1, 240, 0, 400, BLACK); SnackInit(); start=0; sc=5; k=0; s=3000; sum=0; } } if(k==10)//按下N10按钮时往右走 { SnackRight(); //panduan(sc); if(snack[sc].x==food.x&&snack[sc].y==food.y) { j=sc; sc=sc+1; snack[sc].x=snack[j].x+10; snack[sc].y=snack[j].y; TFTLCD_DrawLine(snack[j],snack[sc],GREEN); food.x=a[0].x; food.y=a[0].y; } TFTLCD_DrawPoint(food.x,food.y,WHITE); num=num+1; s+=400; sum++; if(snack[sc].x==0||snack[sc].x==240||snack[sc].y==0||snack[sc].y==340) { TFTLCD_FillBlock(1, 240, 0, 400, BLACK); TFTLCD_ShowString(50,150,\,WHITE,BLACK); SysCtlDelay(1000*(20000000/300)); TFTLCD_FillBlock(1, 240, 0, 400, BLACK); SnackInit(); start=0; sc=5; k=0; } if(k==2)//按下N2按钮时往左走 { if(snack[sc].x==0||snack[sc].x==240||snack[sc].y==0||snack[sc].y==340) SnackLeft(); //panduan(sc); if(snack[sc].x==food.x&&snack[sc].y==food.y) { j=sc; sc=sc+1; snack[sc].x=snack[j].x-10; snack[sc].y=snack[j].y; TFTLCD_DrawLine(snack[j],snack[sc],GREEN); } num=0; s=3000; sum=0; food.x=a[num].x; food.y=a[num].y; TFTLCD_DrawPoint(food.x,food.y,WHITE); num=num+1; s+=400; sum++; } { TFTLCD_FillBlock(1, 240, 0, 400, BLACK); TFTLCD_ShowString(50,150,\,WHITE,BLACK); SysCtlDelay(1000*(20000000/300)); TFTLCD_FillBlock(1, 240, 0, 400, BLACK); SnackInit(); start=0; sc=5; k=0; s=3000; sum=0; } if(k==7)//按下N7按钮时往上走 { if(snack[sc].x==0||snack[sc].x==240||snack[sc].y==0||snack[sc].y==340) { TFTLCD_FillBlock(1, 240, 0, 400, BLACK); SnackUp(); //panduan(sc); if(snack[sc].x==food.x&&snack[sc].y==food.y) { j=sc; sc=sc+1; snack[sc].x=snack[j].x; snack[sc].y=snack[j].y-10; TFTLCD_DrawLine(snack[j],snack[sc],GREEN); } food.x=a[num].x; food.y=a[num].y; TFTLCD_DrawPoint(food.x,food.y,WHITE); num=num+1; s+=400; sum++; } TFTLCD_ShowString(50,150,\,WHITE,BLACK); SysCtlDelay(1000*(20000000/300)); TFTLCD_FillBlock(1, 240, 0, 400, BLACK); SnackInit(); start=0; sc=5; k=0; s=3000; sum=0; } } } if(num>=49) // num=0; } } 随机点数组全取完时重制随机数数组。
正在阅读:
贪吃蛇实验10-30
炼油厂生产废水处理毕业论文03版05-01
焦庙镇2011年上半年观摩解说词10-02
年产2000吨色氨酸的工厂设计1106-06
浅谈企业风险管理体系的建设思路12-24
毕业设计开题报告06-03
2019年4月自考计算机应用基础考前试题和答案0001812-08
武汉医学预科班适合那些学生就读?03-12
东北师范现代汉语(二)16秋在线作业204-24
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 贪吃
- 实验
- XX银行数据机房建设项目解决方案书 - 图文
- 朱姓男孩起名大全
- 六安市茶叶种植专业合作社名录2018版1558家 - 图文
- 六年级英语 unit 4 知识点总结
- 微观经济学习题答案
- 《入菩萨行论》生西法师笔录第174课
- 铁路信号基础试题
- 《现当代文学史》期末总复习试题库
- 高中历史第六单元现代世界的科技与文化单元测评岳麓版必修3(2)
- 五数上数小数的大小比较2
- 2016上海初三二模文言文汇编
- 人教版五年级品社下册《我们的国粹》导学案
- 高温涂料的生产配方大全
- 高三毕业典礼上的校长讲话稿
- 机电工程学院本科毕业设计(论文)正文撰写模板 - 图文
- 2015-2016学年高中数学 第一章 导数及其应用综合检测 新人教A版选修2-2
- 车辆系统动力学发展1
- 工厂供电课程设计
- 关于涵洞防水的补充交底
- 医院感染监测实施细则