|
STM32F769I-DISCO评测【6】——简单的模拟打地鼠游戏
[复制链接]
本帖最后由 xinmeng_wit 于 2016-12-27 13:32 编辑
这一篇我就分享一下我的基于STM32F769I-DISCO的打地鼠游戏,其实不能称作一个游戏,只是简单的模拟一下打地鼠的功能。
需要用到的资源有:
一、LCD;
二、触摸屏;
三、定时器;
四、LED。
打地鼠游戏相信各位大神小时候都玩过,就是每次冒出一个地鼠,需要去敲击冒出来的地鼠,如果敲中了则得分+1,没敲中则不得分,最后看总分,每一关会设定一个时间,关卡越大,地鼠出现的频率越快,难度越大。
功能描述:
1、游戏也是用关卡的方式,一关比一关难(地鼠出现的频率逐渐增加);
2、能显示得分和关卡数,每击中一个加一分,不击或未击中则不得分,同时也不减分;
3、游戏设置有一个暂停键和一个退出键,游戏过程中按下暂停键则游戏暂停,同时按键会变为开始键,若再按下开始键则游戏继续,同时屏幕下方会有文字提示目前所处的状态。若按下退出键则直接退出游戏,同时屏幕也会有相应的提示信息。
4、每关结束后,屏幕会显示当前的得分和关卡数,同时有2个按键,一个按键是“进入下一关”,另一个按键是“退出”,如进入下一关则游戏继续,若退出则游戏中止直接退出。
5、目前没有关卡限制,理论上可以一直玩下去,但是后面地鼠速度太快,完全击不中。
关于程序代码:
工程是直接在HAL库的例程里做的修改,没有单独自己建工程,选用的工程是BSP的工程,因为里面已经包含的lcd和触摸屏的代码,修改起来容易很多。工程路径:..\STM32_FW_F7_V1.5.0\Projects\STM32F769I-Discovery\Examples\BSP\MDK-ARM
下面只介绍一下主要的代码:
主函数:
- int main(void)
- {
- uint8_t lcd_status = LCD_OK;
-
- /* Configure the MPU attributes as Write Through */
- MPU_Config();
- /* Enable the CPU Cache */
- CPU_CACHE_Enable();
- HAL_Init();
-
- /* Configure the system clock to 200 MHz */
- SystemClock_Config();
-
- BSP_LED_Init(LED_GREEN);
- BSP_LED_Init(LED_RED);
-
- /* Configure the Tamper push-button in GPIO Mode */
- BSP_PB_Init(BUTTON_WAKEUP, BUTTON_MODE_GPIO);
- /* Initialize the LCD */
- lcd_status = BSP_LCD_Init();
- while(lcd_status != LCD_OK);
-
- BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS);
-
- BSP_LCD_Clear(LCD_COLOR_WHITE);
- Display_DemoDescription();
- HAL_Delay(1000);
- BSP_LCD_Clear(LCD_COLOR_WHITE);//清屏
-
- BSP_LCD_DisplayStringAt(17*7+17*7, 240+24, (uint8_t *)"score:00", LEFT_MODE);//显示游戏得分
- BSP_LCD_DisplayStringAt(17*7+17*8+17*9, 240+24, (uint8_t *)"round:1", LEFT_MODE);//显示游戏局数
-
- BSP_LCD_SetTextColor(LCD_COLOR_CYAN);
- BSP_LCD_DrawRect(17*7-7+17*8, 240+24-8+30+24*2, 100 , 40);//start按键
- BSP_LCD_FillRect(17*7-7+17*8, 240+24-8+30+24*2, 100 , 40);//start按键填充
-
- BSP_LCD_DrawRect(17*7-7+17*10+17*8, 240+24-8+30+24*2, 100 , 40);//exit按键
- BSP_LCD_FillRect(17*7-7+17*10+17*8, 240+24-8+30+24*2, 100 , 40);//exit按键填充
-
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_CYAN);
- BSP_LCD_DisplayStringAt(17*7+17*8, 240+24+30+24*2, (uint8_t *)"PAUSE", LEFT_MODE);//显示暂停按键85*24
- BSP_LCD_DisplayStringAt(17*7-7+17*10+7+17*8, 240+24-8+30+24*2+8, (uint8_t *)"EXIT", LEFT_MODE);//显示退出按键85*24
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt(17*3, 460, (uint8_t *)"Please press the button "PAUSE" to pause!", LEFT_MODE);//显示提示信息
- TIM3_Init(20000-1,10800-1);//初始化定时器3
- while (1)
- {
- Touchscreen_demo1();//触摸屏函数
- if(timer_count==0)
- {
- BSP_LCD_Clear(LCD_COLOR_WHITE);//清屏
- BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);//设置文本颜色
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);//设置背景颜色
- BSP_LCD_DisplayStringAt((BSP_LCD_GetXSize()-17*8)/2, 24*7, (uint8_t *)"score:", LEFT_MODE);//显示得分
- des_score[0]=score/10+'0';
- des_score[1]=score%10+'0';
- des_score[2]='\0';
- BSP_LCD_DisplayStringAt((BSP_LCD_GetXSize()-17*8)/2+17*6, 24*7,des_score, LEFT_MODE);//显示具体得分
- BSP_LCD_DisplayStringAt((BSP_LCD_GetXSize()-17*7)/2, 24*9, (uint8_t *)"round:", LEFT_MODE);//显示游戏局数
- des_score[0]=game_round%10+'0';
- des_score[1]='\0';
-
- BSP_LCD_DisplayStringAt((BSP_LCD_GetXSize()-17*7)/2+17*6, 24*9,des_score , LEFT_MODE);//显示具体局数
- BSP_LCD_SetTextColor(LCD_COLOR_CYAN);
- BSP_LCD_SetBackColor(LCD_COLOR_CYAN);
- BSP_LCD_DrawRect(17*7-7+17*3, 240+24-8+30+24*2, 204 , 40);//next round按键
- BSP_LCD_FillRect(17*7-7+17*3, 240+24-8+30+24*2, 204 , 40);//next round按键填充
- BSP_LCD_DrawRect(17*7-7+17*10+17*8, 240+24-8+30+24*2, 100 , 40);//exit按键
- BSP_LCD_FillRect(17*7-7+17*10+17*8, 240+24-8+30+24*2, 100 , 40);//exit按键填充
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_CYAN);
- BSP_LCD_DisplayStringAt(17*7-7+17*4, 240+24+30+24*2, (uint8_t *)"NEXT ROUND", LEFT_MODE);//85*24
- BSP_LCD_DisplayStringAt(17*7-7+17*10+7+17*8, 240+24-8+30+24*2+8, (uint8_t *)"EXIT", LEFT_MODE);//85*24
- timer_count=-1;
- ts_flag=-1;
- last_ts_flag=-2;
- }
-
- }
- }
复制代码
主函数主要是对相关资源的初始化,然后是显示一些相关的信息,如得分和关卡数,还有就是按键的绘制,另外地鼠图标我是直接使用的st的logo,while(1)循环里主要是触摸屏扫描和显示相关信息。
再看看Touchscreen_demo1()函数,这个是触摸屏扫描处理函数,按键的操作都是在这里面处理的。
- void Touchscreen_demo1(void)
- {
- uint16_t x1, y1;
- uint8_t state = 0;
- uint8_t exitTsUseCase = 0;
- uint32_t ts_status = TS_OK;
- /* Reset touch data information */
- BSP_TEST_APPLI_ASSERT(BSP_TS_ResetTouchData(&TS_State));
- /* Touchscreen initialization */
- ts_status = BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
- if(ts_status == TS_OK)
- {
- /* Display touch screen demo description */
- //Touchscreen_SetHint_Demo(TOUCHSCREEN_DEMO_1);
- //Touchscreen_DrawBackground_Circles(state);
- // while (exitTsUseCase == 0)
- // {
- if (ts_status == TS_OK)
- {
- /* Check in polling mode in touch screen the touch status and coordinates */
- /* of touches if touch occurred */
- ts_status = BSP_TS_GetState(&TS_State);
- if(TS_State.touchDetected)
- {
- /* One or dual touch have been detected */
- /* Only take into account the first touch so far */
- /* Get X and Y position of the first touch post calibrated */
- x1 = TS_State.touchX[0];
- y1 = TS_State.touchY[0];
- if(timer_count!=-1)
- {
- if((y1>65)&&(y1<65+80))
- {
- if((x1>num*100)&&(x1<num*100+80))
- {
- if(pause==0)//非暂停
- {
- if(ts_flag!=last_ts_flag)
- {
- score++;
- des_score[0]=score/10+'0';
- des_score[1]=score%10+'0';
- des_score[2]='\0';
- BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt(17*7+17*7+17*6, 240+24,des_score, LEFT_MODE);
- BSP_LCD_DisplayStringAt((BSP_LCD_GetXSize()-13*17)/2, 170, (uint8_t *)"Good,score +1", LEFT_MODE);
- last_ts_flag=ts_flag;
- }
- }
-
- }
- }
- else if((y1>240+24+30+24*2)&&(y1<240+24+30+24*2+40))
- {
- if((x1>17*7-7+17*8)&&(x1<17*7-7+17*8+100))
- {
- if(start!=last_start)
- {
- if(start==0)
- {
- start=1;//开始标志
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_CYAN);
- BSP_LCD_DisplayStringAt(17*7+17*8, 240+24+30+24*2, (uint8_t *)"PAUSE", LEFT_MODE);//85*24
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt(17*3, 460, (uint8_t *)"Please press the button "PAUSE" to pause! ", LEFT_MODE);//85*24
- //HAL_TIM_Base_Start_IT(&TIM3_Handler);
- pause=0;
- }
- else
- {
- start=0;//暂停标志
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_CYAN);
- BSP_LCD_DisplayStringAt(17*7+17*8, 240+24+30+24*2, (uint8_t *)"START", LEFT_MODE);//85*24
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt(17*3, 460, (uint8_t *)"Please press the button "START" to restart!", LEFT_MODE);//85*24
- //HAL_TIM_Base_Stop_IT(&TIM3_Handler);
- pause=1;
- }
- last_start=start;
-
- }
- }
- if((x1>17*7-7+17*10+17*6)&&(x1<17*7-7+17*10+17*6+100))
- {
- BSP_LCD_Clear(LCD_COLOR_WHITE);//清屏
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt(17*2, 240, (uint8_t *)"Please press the button "reset" to restart!", LEFT_MODE);//85*24
- pause=1;
- }
- }
- }
- else
- {
- if(last_ts_flag!=ts_flag)
- {
- if((y1>240+24-8+30+24*2)&&(y1<240+24-8+30+24*2+40))
- {
- if((x1>17*7-7+17*3)&&(x1<17*7-7+17*3+204))
- {
- Timer_Count-=3000;
- timer_count=10;
- pause=0;
- game_round++;
- BSP_LCD_Clear(LCD_COLOR_WHITE);//清屏
- BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt(17*7+17*7, 240+24, (uint8_t *)"score:", LEFT_MODE);
- des_score[0]=score/10+'0';
- des_score[1]=score%10+'0';
- des_score[2]='\0';
- //BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
- BSP_LCD_DisplayStringAt(17*7+17*7+17*6, 240+24,des_score, LEFT_MODE);
- BSP_LCD_DisplayStringAt(17*7+17*8+17*9, 240+24, (uint8_t *)"round:", LEFT_MODE);
- des_score[0]=game_round%10+'0';
- des_score[1]='\0';
- //BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
- BSP_LCD_DisplayStringAt(17*7+17*8+17*9+17*6, 240+24,des_score, LEFT_MODE);
- BSP_LCD_SetTextColor(LCD_COLOR_CYAN);
- BSP_LCD_DrawRect(17*7-7+17*8, 240+24-8+30+24*2, 100 , 40);//start按键
- BSP_LCD_FillRect(17*7-7+17*8, 240+24-8+30+24*2, 100 , 40);//start按键填充
- BSP_LCD_DrawRect(17*7-7+17*10+17*8, 240+24-8+30+24*2, 100 , 40);//exit按键
- BSP_LCD_FillRect(17*7-7+17*10+17*8, 240+24-8+30+24*2, 100 , 40);//exit按键填充
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_CYAN);
- BSP_LCD_DisplayStringAt(17*7+17*8, 240+24+30+24*2, (uint8_t *)"PAUSE", LEFT_MODE);//85*24
- BSP_LCD_DisplayStringAt(17*7-7+17*10+7+17*8, 240+24-8+30+24*2+8, (uint8_t *)"EXIT", LEFT_MODE);//85*24
- TIM3_Init(Timer_Count-1,10800-1);
- last_ts_flag=ts_flag;
- }
- if((x1>17*7-7+17*10+17*8)&&(x1<17*7-7+17*10+17*8+100))
- {
- BSP_LCD_Clear(LCD_COLOR_WHITE);//清屏
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt(17*2, 240, (uint8_t *)"Please press the button "reset" to restart!", LEFT_MODE);//85*24
- pause=1;
- }
- }
- }
- }
- } /* of if(TS_State.TouchDetected) */
- } /* of if (ts_status == TS_OK) */
- /* Wait for a key button press to switch to next test case of BSP validation application */
- /* Otherwise stay in the test */
- // exitTsUseCase = CheckForUserInput();
- // HAL_Delay(20);
- // } /* of while (exitTsUseCase == 0) */
- } /* of if(status == TS_OK) */
- }
复制代码
都有相应的注释,语句都没有封装成函数,可能看起来比较乱,后面再修改升级。
另外,还要说一下非常关键的函数,rand()函数,地鼠的出现是随机的,rand()函数就是产生随机数的函数,rand()%8就是生成0~7的随机数,通过随机数来决定地鼠出现的位置。
随机数的产生是在定时器的中断函数里被调用的::
- //定时器3中断服务函数调用
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if(htim==(&TIM3_Handler))
- {
-
- if(pause==0)
- {
- if(timer_count>0)//控制每局的地鼠个数
- {
- BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
- BSP_LCD_FillRect(num*100, 65, 80, 80);
- num=rand()%8;
- while(num==ts_flag)
- {
- num=rand()%8;
- }
-
- ts_flag=num;
- BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
- BSP_LCD_DisplayStringAt((BSP_LCD_GetXSize()-13*17)/2, 170, (uint8_t *)" ", LEFT_MODE);
- BSP_LCD_DrawBitmap(num*100, 65, (uint8_t *)stlogo);
- timer_count--;
- }
-
- if(timer_count==0)
- {
- timer_count=0;
- BSP_LCD_SetTextColor(LCD_COLOR_RED);
- BSP_LCD_DisplayStringAt((BSP_LCD_GetXSize()-13*17)/2, 170, (uint8_t *)"game over", LEFT_MODE);
- }
-
- }
- last_start=-1;
- }
- }
复制代码
核心的代码就是这些,下面上几张图片看看效果:
视频:
点击此处,查看STM32F769I开发板官方资源。
|
|