基于EasyX库的画板(熟悉EasyX库的函数)
程序员文章站
2022-04-07 12:37:30
...
EasyX库介绍
下载链接:下载传送门
以下是官网的介绍:
该库提供使用的函数:官网说明
程序演示
项目介绍
画点线实现
//获取鼠标横纵坐标
x = point.x;
y = point.y;
getimage(&img, 98, 58, 960, 800);
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x > 96 && point.y > 56) {
setlinestyle(0, 2);
line(x, y, point.x, point.y);
}
if (!GetAsyncKeyState(VK_LBUTTON))
break;
画矩形实现
//实现策略:获取单击后的坐标作为起点直角汇点的坐标
//松开后获取的坐标作为起点直角对角汇点的坐标
getimage(&img, 98, 58, 960, 800);
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x > 96 && point.y > 56) {
x1 = point.x;
y1 = point.y;
rectangle(x, y, x1, y1);
}
Sleep(20);
setc(8);
rectangle(x, y, x1, y1);
setc(colour);
if (!GetAsyncKeyState(VK_LBUTTON)){
getimage(&img, 98, 58, 960, 800);
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x > 96 && point.y > 56) {
setlinestyle(0, 2);
line(x, y, point.x, y);
line(x, y, x, point.y);
line(x, point.y, point.x, point.y);
line(point.x, y, point.x, point.y);
}
break;
}
画圆实现
//实现策略:获取单击后的坐标作为圆心
//松开后获取的坐标与到圆心坐标的距离作为圆的半径
getimage(&img, 98, 58, 960, 800);
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x > 96 && point.y > 56) {
x1 = point.x;
y1 = point.y;
setlinestyle(0, 2);
far circle(x, y, (int)sqrt((x1 - x)*(x1 - x) + (y1 - y)*(y1 - y)));
}
Sleep(20);
setc(8);
setlinestyle(0, 2);
far circle(x, y, (int)sqrt((x1 - x)*(x1 - x) + (y1 - y)*(y1 - y)));
setc(colour);
if (!GetAsyncKeyState(VK_LBUTTON)){
getimage(&img, 98, 58, 960, 800);
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (point.x > 96 && point.y > 56) {
setlinestyle(0, 2);
far circle(x, y, (int)sqrt((point.x - x)*(point.x - x) + (point.y - y)*(point.y - y)));
}
break;
}
橡皮擦实现
//本功能实现比较简陋,使用的方法是将绘图颜色调回和背景板颜色一样
//接着将绘图函数的画线的粗细参数调大一些
setc(8);
getimage(&img, 98, 58, 960, 800);
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
x = point.x;
y = point.y;
if (point.x > 96 && point.y > 56) {
setlinestyle(0, 16);
line(x, y, point.x, point.y);
}
setlinestyle(0, 2);
if (!GetAsyncKeyState(VK_LBUTTON))
break;
填充功能实现
//EasyX库自带了填充函数,读取一下鼠标位置进行
getimage(&img, 96, 56, 960, 800);
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
x = point.x;
y = point.y;
if (point.x > 96 && point.y > 56) {
setlinestyle(0, 2);
setfc(colour);
setc(colour);
setfillstyle(BS_SOLID);
floodfill(point.x, point.y, BLACK);
}
添加窗口实现(创建子进程)
void StartClone(int nCloneID)
{
// 提取用于当前可执行文件的文件名
TCHAR szFilename[MAX_PATH];
GetModuleFileName(NULL, szFilename, MAX_PATH);
//printf("%s", szFilename);
// 格式化用于子进程的命令行
TCHAR szCmdLine[MAX_PATH]="DrawingBoard_Process";
//并通知其EXE文件名和克隆ID
//sprintf(szCmdLine, "\"%s\" %d", szFilename, nCloneID);
// 用于子进程的STARTUPINFO结构
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si); // 必须是本结构的大小
si.dwFlags = STARTF_USESHOWWINDOW; // 指定wShowWindow成员有效
si.wShowWindow = TRUE; // 此成员设为TRUE的话则显示新建进程的主窗口
// 返回的用于子进程的进程信息
PROCESS_INFORMATION pi;
// 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质
BOOL bCreateOK = CreateProcess(
szFilename, // 产生这个EXE的应用程序的名称
szCmdLine, // 命令行参数,告诉其行为像一个子进程的标志
NULL, // 缺省的进程安全性
NULL, // 缺省的线程安全性
FALSE, // 不继承句柄
CREATE_NEW_CONSOLE, // 使用新的控制台
NULL, // 新的环境
NULL, // 当前目录
&si, // 启动信息
&pi); // 返回的进程信息
// 对子进程释放
if (bCreateOK)
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
}
PS:
1、按钮选择响应策略:在选择颜色或绘图功能后,使用特别颜色在按钮周围绘制一个矩形显示已选择的相应功能。按横向功能栏上,只要鼠标移到相应位置,使用灰黑色加深按钮颜色表示移到相应位置。
2、画圆和画矩形的残留图像处理:使用保留上次绘图坐标,当移动后,在擦出上次画矩形,从而达到变拖拽变画图的目的。
不足
1、没用应用面向对象的方法,在画出的图形没有相应数据的保存(如画圆不保存其圆心和半径的数据),自始至终都相当于一个画面描绘,没有独立的图形对象。因此,在画完后不能撤销,不能对原图形选中修改。
对应解决方案:使用面向对象的方法,然后做好相应的数据保存,建立对象栈结构来保存图形对象数据。
2、在画圆或画矩形的时候,由于上述处理策略,所以会影响原本所绘图形。如下图:
3、橡皮擦和绘图的线条大小不能进行调节
结语
如果如果您刚开始学 C 语言,想快速上手图形和游戏编程,可以尝试使用EasyX库。
想学习的话,可以参考一下这位作者的专栏:https://www.zhihu.com/column/c2game
作品链接:传送门