一、声明:源代码改编自EasyX自带的说明文档中的示例代码《示例程序——鼠标操作》
该文档的下载链接:
EasyX说明文档https://docs.easyx.cn/download/zh-cn/EasyX_Help.zip?i=234wewe232321
如果你看不到该文档内容,可能是因为编码出现了问题,详见我的上一篇博客:自学EasyX(一):检测鼠标位置和行为-优快云博客
二、环境和代码变化
- 增加了一个ldsrc.cpp文件和其对应的ldsrc.h头文件,里面的函数用于加载资源
- 增加了一个inc.h头文件,用于引用标准库和easyX库的头文件
- 对应的task.json文件中的arg类也应该发生变化,如下图所示,这段话是指将该文件夹中的所有cpp后缀的文件都参与编译:
- 增加了自己绘制的扑克牌图片资源,是在以下免费的像素绘图网站中绘制的Pixilart - Free Online Art Community and Pixel Art Tool
- 在main中加入了功能:调用图片对象,并用鼠标将其拖动
三、源代码
3.1 inc.h文件
#ifndef __INC__
#define __INC__
// include basic headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// include easyX headers
#include <easyx.h>
#include <graphics.h>
#endif
3.2 ldsrc.cpp文件和ldsrc.h文件
ldsrc.h文件:定义了一个扑克牌结构体,因为我只画了红桃和黑桃两个花色,所以只需要一个bool来表示它的颜色
#ifndef __LDSRC__
#define __LDSRC__
#include "inc.h"
// 扑克牌结构体
struct PokerCard {
IMAGE* img; // 图片指针
int x; // X坐标
int y; // Y坐标
int width; // 宽度
int height; // 高度
bool isRedSuit; // true=红桃/方块, false=黑桃/梅花
int value; // 牌面值 (1-13, 1=A,11=J,12=Q,13=K)
};
PokerCard* loadPokerCard(const char* path, int x, int y, bool isRedSuit, int value);
#endif
ldsrc.cpp文件:创建一个新的扑克牌结构体对象,将对应的信息记录在这个对象中
#include "ldsrc.h"
// #include "inc.h"
// 加载扑克牌图片的函数
// 加载扑克牌图片
PokerCard* loadPokerCard(const char* path, int x, int y, bool isRedSuit, int value) {
PokerCard* card = new PokerCard();
// 加载图片
card->img = new IMAGE;
loadimage(card->img, path);
// 设置属性
card->x = x;
card->y = y;
card->width = card->img->getwidth();
card->height = card->img->getheight();
card->isRedSuit = isRedSuit;
card->value = value;
return card;
}
3.3 main.cpp函数
// 编译环境:Visual C++ 6.0~2022,EasyX_2023大暑版
// https://easyx.cn
//
#include "ldsrc.h"
int main() {
// 初始化图形窗口
initgraph(640, 480);
SetWindowText(GetHWnd(), TEXT("扑克牌鼠标互动"));
// 加载扑克牌 (黑桃2)
PokerCard* card = loadPokerCard("src\\poker\\hearts\\hrt-2.png",
100, 100,
TRUE, // 黑桃为false
2); // 牌面值3
// 启用双缓冲
BeginBatchDraw();
ExMessage m;
bool isDragging = false;
int offsetX = 0, offsetY = 0;
while (true) {
cleardevice();
// 绘制扑克牌
putimage(card->x, card->y, card->width, card->height, card->img, 0, 0);
// 显示牌信息
char info[128];
sprintf(info, "Value: %d | %s",
card->value,
card->isRedSuit ? "Red" : "Black");
outtextxy(10, 10, info);
// 获取消息
m = getmessage(EX_MOUSE | EX_KEY);
switch (m.message) {
case WM_LBUTTONDOWN:
// 检查是否点击了扑克牌
if (m.x >= card->x && m.x <= card->x + card->width &&
m.y >= card->y && m.y <= card->y + card->height) {
isDragging = true;
offsetX = m.x - card->x;
offsetY = m.y - card->y;
}
break;
case WM_MOUSEMOVE:
if (isDragging) {
// 移动扑克牌
card->x = m.x - offsetX;
card->y = m.y - offsetY;
}
break;
case WM_LBUTTONUP:
isDragging = false;
break;
case WM_KEYDOWN:
if (m.vkcode == VK_ESCAPE) {
// 释放资源并退出
delete card->img;
delete card;
EndBatchDraw();
closegraph();
return 0;
}
}
// 在左上角显示鼠标坐标
char coordText[32];
sprintf(coordText, "鼠标坐标:[%d,%d]", m.x, m.y);
// 设置文本背景为半透明和文本颜色
setbkmode(TRANSPARENT);
settextcolor(WHITE);
outtextxy(10, 30, coordText);
// 在左上角显示卡牌坐标
char cardPositionText[32];
sprintf(cardPositionText, "卡牌坐标:[%d,%d]", card->x, card->y);
outtextxy(10, 50, cardPositionText);
FlushBatchDraw();
}
EndBatchDraw();
closegraph();
return 0;
}
在屏幕中显示了卡牌信息、鼠标坐标、卡牌坐标的信息,但是easyX中的outtextxy函数虽然可以在屏幕上打印出字符串,但是却不能打印出\n的换行信息,只能在同一行中打印,因此打印卡牌坐标的这段被单独提出来了。
四、效果
在初始化结束后,得到这样的画面
在鼠标拖动后,可以得到看到在图片更改的同时,卡牌坐标也发生了改变