前言
经过上一章的基础介绍,相信大家对EasyX图形库的安装、初始化以及基本绘图功能已经有了初步认识。本章我们将深入探讨EasyX中一个非常重要的交互功能 - 键盘映射。具体来说,我将详细讲解如何在EasyX程序中实现鼠标和键盘输入的处理,以及如何通过这些输入设备与绘图窗口进行交互。
1.对于资源的加载
很多人初次接触这个库时,最想实现的功能可能就是插入图片了。其实实现代码很简单,我只是按照学习顺序才把它放在了后面讲解。
图片的插入
IMAGE
是专门用于存储图像数据的类型名称。
使用 loadimage()
函数时需要注意:后两个参数用于指定画布尺寸,其中第二个参数需要传入图片的路径地址。
//一个插入进场图片的函数
void Insert_image()
{
IMAGE image;
loadimage(&image, _T(R"(.\image\1.bmp)"), 700, 800);
putimage(0, 0, &image);
}
效果如下:
图片加载过程中可能会出现黑屏现象
针对图片无法显示的问题,可采取以下解决方案:
-
验证图片文件是否完整无损
-
检查文件路径是否正确,建议将资源文件存放在项目目录内
-
尝试改用绝对路径定位文件
以上是基本的解决方案,如有其他有效方法欢迎补充完善
对于颜色的选择
在 EasyX 图形库中,颜色的使用非常灵活,支持多种表示方式。
1.预定颜色常量
EasyX 提供了一系列预定义的颜色常量,以EGERGB
或颜色英文名称命名,方便直接使用。
2.RGB 颜色值
通过RGB(r, g, b)
函数可以自定义颜色,参数范围为0~255
:
// 自定义颜色
setfillcolor(RGB(255, 128, 0)); // 橙色(红+绿混合)
setlinecolor(RGB(0, 192, 192)); // 亮青色
使用0xRRGGBB
格式直接表示颜色:
// 16进制颜色
setfillcolor(0xFF6600); // 橙色
setlinecolor(0x33CCFF); // 天蓝色
EasyX 从 2021 版开始支持 Alpha 通道(透明度),使用RGBA(r, g, b, a)
函数:
// 半透明红色(a=128表示50%透明度)
setfillcolor(RGBA(255, 0, 0, 128));
fillcircle(320, 240, 100);
实现界面与用户的交互
要实现这一功能,需要先理解阻塞函数和非阻塞函数的概念。只有掌握这个知识点,才能防止程序被挂起。如果出现画面卡死的情况,很可能就是因为这个原因。
阻塞函数:
阻塞函数是指在调用该函数时,当前线程会被挂起,直到该函数完成其操作并返回结果。在此期间,线程无法执行其他任务。
非阻塞函数:
非阻塞函数是指调用时不会挂起当前线程,而是立即返回的函数。若操作无法立即完成,函数会返回状态值表明结果暂不可用,线程可继续执行其他任务。
_kbhit(): 在 EasyX 中,_kbhit() 就是一个典型的非阻塞函数。它用于检测是否有按键被按下,但不会影响当前进程的运行:有按键按下时返回非零值,无按键时返回 0。
_getch():为了实际获取按键信息,我们需要配合使用 _getch() 函数。这个标准的阻塞函数会暂停程序运行,直到读取到控制台输入的字符(不显示在屏幕上)。通常的做法是将 _kbhit() 和 _getch() 配合使用。
initgraph(640, 480); // 初始化图形窗口
while (1) {
// 处理键盘输入
if (_kbhit()) {
char ch = _getch();
if (ch == 27) break; // ESC 键退出程序
printf("键盘输入: %c\n", ch);
}
// 处理鼠标输入
if (MouseHit()) { // 检查是否有鼠标消息
MOUSEMSG msg = GetMouseMsg(); // 获取鼠标消息
switch (msg.uMsg) {
case WM_LBUTTONDOWN: // 左键按下
printf("左键点击: (%d, %d)\n", msg.x, msg.y);
break;
case WM_RBUTTONDOWN: // 右键按下
printf("右键点击: (%d, %d)\n", msg.x, msg.y);
break;
case WM_MOUSEMOVE: // 鼠标移动
// 可以在此处添加鼠标移动处理逻辑
break;
// 其他鼠标消息...
}
}
// 程序的其他逻辑
Sleep(10); // 降低 CPU 使用率
}
closegraph(); // 关闭图形窗口
(实现动画效果需要在绘图函数中加入)
cleardevice();
EasyX最新版本中的_kbhit()和_getch()函数存在一个使用限制:需要将光标置于控制台窗口内才能正常接收输入消息。
作为替代方案,我们可以使用Windows API中的GetAsyncKeyState()函数来实现消息接收功能。
双缓冲机制
EasyX 中的双缓冲技术是解决动画绘制时画面闪烁问题的有效方案。其核心原理是在内存中预先完成整个画面的绘制,然后一次性输出到显示窗口,从而避免了逐帧绘制产生的闪烁问题。
主要应用场景包括:
- 动态动画效果(如移动物体、图形旋转等)
- 需要频繁刷新的界面(如游戏画面、实时数据可视化等)
使用方法:
BeginBatchDraw()
:开始双缓冲模式,后续绘图操作会在内存中进行。EndBatchDraw()
:结束双缓冲模式,并将内存中的画面一次性输出到窗口。FlushBatchDraw()
:在双缓冲期间强制刷新一次(用于需要即时显示的场景)。 例如下面是一个圆的移动:
#include <graphics.h>
#include <conio.h>
#include <windows.h>
int main() {
// 初始化图形窗口
initgraph(640, 480);
setbkcolor(WHITE); // 设置背景色为白色
cleardevice(); // 清空画布
int x = 50; // 圆的X坐标(初始位置)
int y = 240; // 圆的Y坐标
int radius = 30; // 圆的半径
// 开始双缓冲模式
BeginBatchDraw();
// 动画循环(按任意键退出)
while (!_kbhit()) {
// 1. 清除内存中的旧画面(背景色填充)
cleardevice();
// 2. 在内存中绘制新画面
setfillcolor(RED); // 设置填充色为红色
fillcircle(x, y, radius); // 绘制圆
// 3. 更新圆的位置(移动)
x++;
if (x > 640 + radius) { // 超出右边界后重置到左边
x = -radius;
}
// 4. 将内存中的画面一次性输出到窗口(刷新)
EndBatchDraw();
// 控制动画速度(延迟10毫秒)
Sleep(10);
}
// 结束双缓冲(可选,程序结束前会自动处理)
EndBatchDraw();
// 关闭图形窗口
closegraph();
return 0;
}
到这里,关于EasyX图形库的主要内容已经讲解完毕。虽然我们已经涵盖了EasyX的基本绘图函数、消息处理、动画实现等核心知识点,但可能还有一些高级功能未能详细展开,比如:
- 图像处理相关的特殊函数
- 多线程绘图优化技巧
- 与DirectX的交互使用
- 跨平台开发的注意
现在,你们完全可以着手开发一些有趣的小游戏了,比如:
- 经典的贪吃蛇游戏
- 简单的射击游戏
- 记忆匹配卡片游戏
- 拼图游戏
- 简易平台跳跃游戏
期待看到大家用EasyX创造的作品!在实际开发过程中遇到问题时,记得查阅官方文档或者返回查看相关章节。祝大家编程愉快!