当前位置: 首页 > news >正文

用Devc++与easyx一步一步做游戏[启动界面部分]-解决hover闪烁问题及优化

在之前的博文中《用Devc++与easyx一步一步做游戏[启动界面部分]-之按钮制作》,我们利用Devc++和easyx完成了游戏启动界面按钮的基本制作,实现了按钮的绘制以及鼠标悬停时的信息提示功能。然而,目前还存在一个问题,即鼠标移动时,提示文字会出现闪烁现象,有很多童鞋在阅读后都表示出了兴趣。这篇博文我们就来解决这个问题并对代码进行优化。

文章目录

    • 一、解决闪烁问题
      • 1. 问题分析
      • 2. 解决方案
    • 二、代码优化
      • 1. 坐标和尺寸管理
      • 2. 代码结构优化

一、解决闪烁问题

1. 问题分析

提示文字闪烁的原因在于,每次鼠标移动触发WM_MOUSEMOVE消息时,都会频繁地清除矩形区域并重新绘制文字。这导致画面不断刷新,从而产生闪烁感。为了解决这个问题,我们需要减少不必要的绘制操作。

2. 解决方案

我们可以通过记录当前鼠标悬停的按钮状态来判断是否需要更新提示文字。如果鼠标仍然悬停在同一个按钮上,就不需要重复清除和绘制。只有当鼠标从一个按钮移到另一个按钮时,才进行相应的操作。

在代码中,我们定义一个全局变量currentButtonIndex来记录当前鼠标悬停的按钮索引,初始值设为 -1,表示没有悬停在任何按钮上。

int currentButtonIndex = -1;

然后,修改消息循环中的WM_MOUSEMOVE处理逻辑:

ExMessage msg; 
while (true) {if (peekmessage(&msg, EM_MOUSE)) {switch (msg.message) {case WM_LBUTTONDOWN:break;    case WM_MOUSEMOVE:int newButtonIndex = -1;if (msg.x >= 220 && msg.x <= 220 + 170 && msg.y >= 50 && msg.y <= 50 + 50)newButtonIndex = 0;else if (msg.x >= 220 && msg.x <= 220 + 170 && msg.y >= 140 && msg.y <= 140 + 50)newButtonIndex = 1;else if (msg.x >= 220 && msg.x <= 220 + 170 && msg.y >= 230 && msg.y <= 230 + 50)newButtonIndex = 2;else if (msg.x >= 220 && msg.x <= 220 + 170 && msg.y >= 320 && msg.y <= 320 + 50)newButtonIndex = 3;if (newButtonIndex != currentButtonIndex) {// 清除之前的提示文字if (currentButtonIndex != -1) {RECT prevRect = {220, 420, 220 + 170, 420 + 30}; // 根据文字大小调整矩形区域clearrectangle(prevRect.left, prevRect.top, prevRect.right, prevRect.bottom);}currentButtonIndex = newButtonIndex;if (currentButtonIndex != -1) {tipInfo(tipInfoRect, title[currentButtonIndex]);}}break;    default:break;}}
}

通过上述代码,只有当鼠标悬停的按钮发生变化时,才会清除之前的提示文字并绘制新的提示文字,有效地解决了闪烁问题。

二、代码优化

1. 坐标和尺寸管理

之前的代码中,按钮的坐标和尺寸都是直接写在代码里,这样不利于修改和维护。我们可以将这些参数定义为常量或者结构体,方便统一管理。

// 定义按钮相关常量
const int BUTTON_WIDTH = 170;
const int BUTTON_HEIGHT = 50;
const int BUTTON_GAP = 40;
const int START_Y = 50;
const int TIP_X = 220;
const int TIP_Y = 420;

然后在绘制按钮和判断鼠标位置时使用这些常量:

// 绘制按钮
for(int i = 0; i < 4; i++) {int x = 220;int y = START_Y + i * (BUTTON_HEIGHT + BUTTON_GAP);button(x, y, title[i]);
}// 判断鼠标位置
if (msg.x >= TIP_X && msg.x <= TIP_X + BUTTON_WIDTH && msg.y >= START_Y && msg.y <= START_Y + BUTTON_HEIGHT)newButtonIndex = 0;
// 其他按钮判断类似,修改对应y坐标即可

2. 代码结构优化

随着功能的增加,代码逐渐变得复杂,我们可以进一步优化代码结构,将不同功能的代码封装到独立的函数中。例如,将消息循环部分封装到一个函数handleMouseMessages中:

void handleMouseMessages() {ExMessage msg; while (true) {if (peekmessage(&msg, EM_MOUSE)) {switch (msg.message) {case WM_LBUTTONDOWN:break;    case WM_MOUSEMOVE:int newButtonIndex = -1;// 判断鼠标位置逻辑不变//...if (newButtonIndex != currentButtonIndex) {// 清除和绘制逻辑不变//...}break;    default:break;}}}
}

main函数中调用这个函数:

int main(int argc, char** argv) {initgraph(640, 480);   setbkcolor(0x3B0000);cleardevice();// 绘制按钮for(int i = 0; i < 4; i++) {int x = 220;int y = START_Y + i * (BUTTON_HEIGHT + BUTTON_GAP);button(x, y, title[i]);}handleMouseMessages();getchar();closegraph();return 0;
}

通过上述优化,代码的可读性和可维护性都得到了显著提升。

到这里,游戏启动界面按钮的制作已经基本完成,解决了闪烁问题并对代码进行了优化。后续我们可以继续完善游戏启动界面的其他功能,如按钮点击事件的处理等。希望这篇博文能帮助大家更好地理解和运用Devc++与easyx进行游戏开发。

http://www.lryc.cn/news/527594.html

相关文章:

  • mysql 学习3 SQL语句--整体概述。SQL通用语法;DDL创建数据库,查看当前数据库是那个,删除数据库,使用数据库;查看当前数据库有哪些表
  • 【数据结构】_链表经典算法OJ:分割链表(力扣—中等)
  • k8s支持自定义field-selector spec.hostNetwork过滤
  • ICSE‘25 LLM Assistance for Memory Safety
  • 《十七》浏览器基础
  • TikTok 推出了一款 IDE,用于快速构建 AI 应用
  • 阅读springboot源码 记录
  • Linux之内存管理前世今生(一)
  • Beautiful Soup 入门指南:从零开始掌握网页解析
  • 网络通信---MCU移植LWIP
  • Go-并行编程新手指南
  • 基于Django的个人博客系统的设计与实现
  • Python爬虫获取custom-1688自定义API操作接口
  • kaggle-ISIC 2024 - 使用 3D-TBP 检测皮肤癌-学习笔记
  • 滤波电路汇总
  • 1.Template Method 模式
  • MySQL分表自动化创建的实现方案(存储过程、事件调度器)
  • 基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真
  • 计算机毕业设计【任务书】怎么写?
  • GRAPHARG——学习
  • 【Rust自学】15.6. RefCell与内部可变性:“摆脱”安全性限制
  • 14.模型,纹理,着色器
  • 【C语言分支与循环结构详解】
  • 新项目上传gitlab
  • qt-QtQuick笔记之常见项目类简要介绍
  • Continuous Batching 连续批处理
  • 海外问卷调查渠道查如何设置:最佳实践+示例
  • 把本地搭建的hexo博客部署到自己的服务器上
  • 初阶数据结构:链表(二)
  • postgresql根据主键ID字段分批删除表数据