Элегантная реализация мониторинга событий щелчка мыши EasyX

Элегантная реализация мониторинга событий щелчка мыши 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, высота и ширина излишне говорить. Прежде всего,

  1. clickAction Это указатель функции, который представляет собой действие, выполняемое после щелчка по элементу управления.
  2. receiveEvent - это функция, которая отвечает за уведомление элемента управления, где пользователь щелкнул
  3. 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 кнопок? Вставьте описание изображения сюда
Закончил писать, ускользнул ...

рекомендация

отblog.csdn.net/qq_36323419/article/details/115266521