导言:嵌入式系统课设,设计打地鼠游戏。
问题描述
- 地鼠从设置好的地鼠洞里面随机冒出来
- 用手按触摸屏实现打地鼠,打中则计分
- 时间到后统计游戏分数
- 可以设定游戏时间和难度
系统设计
使用LCD触摸例程进行修改,在 BASIC_Touch.c 文件中增加需要的部分。
设置时间为60秒,并绘制难度按钮,分为 Easy、Medium 和 Hard 三等。
绘制按钮
定义按钮 ID
#define ID_BUTTON_EASY 0
#define ID_BUTTON_MEDIUM 1
#define ID_BUTTON_HARD 2
#define ID_BUTTON_RESET 3
定义按钮句柄
BUTTON_Handle Button_easy;
BUTTON_Handle Button_medium;
BUTTON_Handle Button_hard;
BUTTON_Handle Button_reset;
初始化
select = 0; // 选择控制符
reset = 0; // 重置控制符
timecount = 600000;
time = 60; // 倒计时
GUI_Clear();
GUI_DispStringAt("Select mode", 60, 60);
//简单
Button_easy = BUTTON_CreateEx(button_x, button_y, button_length, button_width, 0, WM_CF_SHOW, 0, ID_BUTTON_EASY);
BUTTON_SetText(Button_easy, "Easy");
//正常
Button_medium = BUTTON_CreateEx(button_x + span, button_y, button_length, button_width, 0, WM_CF_SHOW, 0, ID_BUTTON_MEDIUM);
BUTTON_SetText(Button_medium, "Medium");
//困难
Button_hard = BUTTON_CreateEx(button_x + 2 * span, button_y, button_length, button_width, 0, WM_CF_SHOW, 0, ID_BUTTON_HARD);
BUTTON_SetText(Button_hard, "Hard");
GUI_Exec();
如果难度为Easy,地鼠出现的时间为 2秒,Medium难度出现的时间为 1.5秒,Hard难度的出现时间为 0.8秒。
if (State.x < button_x + button_length && State.x > button_x && State.y < button_y + button_width && State.y > button_y) {
mode = 2000; // 2秒刷新一次
select = 1;
WM_DeleteWindow(Button_easy);
WM_DeleteWindow(Button_medium);
WM_DeleteWindow(Button_hard);
} else if (State.x < button_x + span + button_length && State.x > button_x + span && State.y < button_y + button_width && State.y > button_y){
mode = 1500; // 1.5秒刷新一次
select = 2;
WM_DeleteWindow(Button_easy);
WM_DeleteWindow(Button_medium);
WM_DeleteWindow(Button_hard);
} else if (State.x < button_x + 2 * span + button_length && State.x > button_x + 2 * span && State.y < button_y + button_width && State.y > button_y){
mode = 800; // 0.8秒刷新一次
select = 3;
WM_DeleteWindow(Button_easy);
WM_DeleteWindow(Button_medium);
WM_DeleteWindow(Button_hard);
}
绘制图片
使用系统提供的工具 Bitmap Converter 进行位图的转换,生成一个包含图像信息的c文件。
游戏主体
在LCD屏幕范围内随机选择 x 和 y 坐标,并在相应位置绘制地鼠图像。
点击使用循环的方式,当点击位置在地鼠出现的范围内时,count++,得分加1,并进入下一轮循环,重新刷新地鼠出现的位置,直到游戏时间结束。
右下角设置Replay按钮,当点击按钮时,得分清零,并重新进入选择难度的界面。
int x = rand() % 340; // 随机产生 X 坐标
int y = rand() % 230; // 随机产生 Y 坐标
GUI_DrawBitmapEx(&bmimage, x, y, 0, 0, 2000, 2000); // 在指定位置画出图像
for(int i = 0; i < mode; i++){
timecount--;
GUI_X_Delay(1);
GUI_TOUCH_GetState(&State);
if (timecount % 1000 == 0){
time--;
GUI_DispDecAt(time, score_x + 40, score_y + 30, 3);
}
if (State.Pressed == 1 &&
State.x < x + size + 10 &&
State.x > x - 10 &&
State.y < y + size + 10 &&
State.y > y - 10) { //点击到地鼠
count++; // 得分增加
GUI_Exec();
break;
} else if(State.Pressed == 1 &&
State.x < 400 + button_length &&
State.x > 400 &&
State.y < 220 + button_width &&
State.y > 220){ //点击到 Replay 按钮
reset = 1; // 重置标志设置
count = 0; // 得分置零
WM_DeleteWindow(Button_reset);
GUI_Exec();
break;
}
}
踩坑分析
-
绘制按钮时只能使用 BUTTON_CreateEx() 函数
-
没找到调用按钮回调函数的方法,使用了判断按钮位置的方法判断是否按下按钮
-
企图用外部中断按钮实现重置,按下后直接死机,回调函数也不执行,最后采用虚拟按钮实现功能
-
使用完按钮后需要使用 WM_DeleteWindow() 函数删除,否则会留下残留
成果展示
函数附录
BUTTON_CreateEx
BUTTON_Handle BUTTON_CreateEx(int x0, int y0,
int xsize, int ysize,
WM_HWIN hParent, int WinFlags,
int ExFlags, int Id);
在指定位置创建指定尺寸的 BUTTON 小工具。
参数 | 描述 |
---|---|
x0 | 小工具最左侧的像素 (在父坐标中)。 |
y0 | 小工具最顶端的像素 (在父坐标中)。 |
xsize | 小工具的水平尺寸 (以像素为单位)。 |
ysize | 小工具的垂直尺寸 (以像素为单位)。 |
hParent | 父窗口的句柄。如果为 0,则 BUTTON 小工具将是桌面 (顶级窗口)的子项。 |
WinFlags | 窗口创建标记。为了使小工具立即可见,通常为 WM_CF_SHOW (有关可用参数值的列表,请参阅“窗口管理器 (WM)”(第 289 页)一章中的 WM_CreateWindow())。 |
ExFlags | 未使用,保留供日后使用。 |
Id | 小工具的窗口 ID。 |
WM_DeleteWindow
void WM_DeleteWindow(WM_HWIN hWin);
删除指定窗口。
参数 | 描述 |
---|---|
hWin | 窗口句柄。 |
GUI_DispStringAt()
void GUI_DispStringAt(const char GUI_FAR * s, int x, int y);
在当前窗口的指定位置处,使用当前字体显示作为参数的字符串。
参数 | 描述 |
---|---|
s | 显示的字符串。 |
x | 要写入的客户端窗口 X 位置 (单位:像素)。 |
y | 要写入的客户端窗口 Y 位置 (单位:像素)。 |
GUI_DispDecAt()
void GUI_DispDecAt(I32 v, I16P x, I16P y, U8 Len);
在当前窗口的指定位置处,使用当前字体显示指定字符数的十进制数值。
参数 | 描述 |
---|---|
V | 显示的数值。最小值为 -2147483648 (= -2^31)。最大值为 2147483647 (= 2^31 -1)。 |
x | 要写入的客户端窗口 X 位置 (单位:像素)。 |
y | 要写入的客户端窗口 Y 位置 (单位:像素)。 |
Len | 显示的位数 (最大为 10)。 |
GUI_Clear()
void GUI_Clear(void);
清除当前窗口。
GUI_X_Delay()
void GUI_X_Delay(int Period)
在指定时间后 (单位:毫秒)返回。
参数 | 描述 |
---|---|
Period | 以毫秒表示的时间。 |