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クラスを作成してそれを継承し、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個のボタンを試してみませんか?
書き終えて、すり抜けて...