Элегантная реализация мониторинга событий щелчка мыши EasyX
В последнее время школьная программа требует использования EasyX для реализации небольшой игры или небольшого приложения. Но будь то игра или приложение, неизбежно отслеживание щелчков мыши, определение места щелчка мыши и соответствующая реакция.
Да, это очень простой сценарий, и его несложно реализовать. Обратитесь к примерам, приведенным школой, и к некоторым реализациям, найденным в Интернете, чтобы справиться с этим, основной код выглядит следующим образом:
if (msg.uMsg==WM_LBUTTONDOWN) // 如果点左键
{
if((msg.x>110 && msg.x<360) && (msg.y>240 && msg.y<310))// 点击菜单1
choose='1';
if((msg.x>110 && msg.x<398) && (msg.y>325 && msg.y<390))// 点击菜单2
choose='2';
if((msg.x>110 && msg.x<458) && (msg.y>410 && msg.y<475))// 点击菜单3
choose='3';
if((msg.x>110 && msg.x<332) && (msg.y>500 && msg.y<550))// 点击菜单4
choose='4';
}
Когда я впервые посмотрел, а это, не так ли? Просто напишите это так? ?
Тогда я могу написать 17 таких карточек только для Дудичжу? (Это можно упростить с помощью цикла, но у меня все еще есть куча кнопок, распределенных по всему миру), и использование if таким образом определенно не в моем стиле. Итак, я лег спать, в конце концов, у меня все во сне.
Не делай этого, возьми нож обратно ... Перестань спать, перестань спать, никаких сложных задач, только смелые жертвы современного колледжа! Сделайте это ...
Во-первых, мы абстрагируем общие черты всех "вещей", на которые можно щелкнуть. Во-первых, по нему можно щелкнуть и нарисовать (поскольку его можно рисовать, он должен иметь координаты x, y, длину и ширину. ) Такой класс абстрагируется нами.
class Clickable
{
public:
int x;
int y;
int height;
int width;
void(*clickAction)();
void receiveEvent(int cx, int cy);
virtual void draw() = 0;
private:
bool isClickMe(int cx, int cy);
};
Я считаю, что x, y, высота и ширина излишне говорить. Прежде всего,
- clickAction Это указатель функции, который представляет собой действие, выполняемое после щелчка по элементу управления.
- receiveEvent - это функция, которая отвечает за уведомление элемента управления, где пользователь щелкнул
- isClickMe - это закрытая функция, которая в основном отвечает за оценку того, нажимает ли пользователь на элемент управления.
Конкретная реализация выглядит следующим образом:
void Clickable::receiveEvent(int cx, int cy)
{
if (isClickMe(cx, cy))
{
clickAction();
}
}
bool Clickable::isClickMe(int cx, int cy)
{
return cx >= x && cy >= y && x + width >= cx && y + height >= cy;
}
Затем мы создаем класс Button, чтобы унаследовать его и реализовать функцию рисования.
//-----Button.h----
#include "Clickable.h"
#include <graphics.h> // 引用图形库头文件
#include <conio.h>
class Button: public Clickable
{
public:
Button(int x, int y, int height, int width);
void draw() override;
};
//------Button.cpp----
#include "Button.h"
Button::Button(int x, int y, int height, int width)
{
this->x = x;
this->y = y;
this->height = height;
this->width = width;
}
void Button::draw()
{
fillrectangle(x, y,x + width, y + height);
}
Как видите, Button только рисует прямоугольник с реализованной функцией рисования, ничего особенного. Наступает самый захватывающий момент, давайте нарисуем его в функции main! ! !
#include "Button.h"
using namespace std;
//bt点击事件
void bt_clickAction() {
setfillcolor(BLUE);
fillcircle(100, 300, 25);
}
//bt2点击事件
void bt2_clickAction() {
setfillcolor(RED);
fillcircle(400, 300, 25);
}
int main()
{
initgraph(640, 480);//初始化画布
//创建两个Button 对象
Button bt = Button(100, 100, 25, 60);
Button bt2 = Button(400, 100, 25, 60);
//为他们设置点击事件
bt.clickAction = bt_clickAction;
bt2.clickAction = bt2_clickAction;
//把他们绘制到屏幕上
bt.draw();
bt2.draw();
MOUSEMSG m; // 定义鼠标消息
while (true)
{
// 获取一条鼠标消息
m = GetMouseMsg();
switch (m.uMsg)
{
case WM_LBUTTONDOWN://按鼠标左键分发事件
bt.receiveEvent(m.x, m.y);
bt2.receiveEvent(m.x, m.y);
break;
case WM_RBUTTONUP:
return 0; // 按鼠标右键退出程序
}
}
// 关闭图形窗口
closegraph();
}
Приведенные выше комментарии к коду очень ясны и также решают проблему, которую мы начали (проблема, если катастрофа). Вы можете видеть, что у меня нет if в этой ветке WM_LBUTTONDOWN. Давайте
проверим это.
Когда я нажимаю кнопку слева,
появляется синий значок. Когда я нажимаю кнопку справа, он становится красным
Не говоря уже о том, что код изменился, но не попробуете ли вы 20 кнопок?
Закончил писать, ускользнул ...