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クラスを作成してそれを継承し、draw関数を実装します。

//-----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が実行するのは、実装された描画関数を使用して長方形を描画することだけで、特別なことは何もありません。これが最もエキサイティングな瞬間です。メイン関数で描画しましょう。

#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のこのブランチにifがないことがわかります。
ここに画像の説明を挿入
試して
ここに画像の説明を挿入
みましょう左側のボタンをクリック
ここに画像の説明を挿入
すると青い⚪が生まれます。右側のボタンをクリックすると赤い⚪になります。
ここに画像の説明を挿入

コードが変更されたことは言うまでもありませんが、20個のボタンを試してみませんか?ここに画像の説明を挿入
書き終えて、すり抜けて...

おすすめ

転載: blog.csdn.net/qq_36323419/article/details/115266521