学习笔记:图形化与C++多线程

引言

  计算导论与程序设计课的期末作业是分别设计OJ版本与图形化版本的扫雷游戏。截止到目前已经完成OJ版项目的开发,对于图形化版本也已经基本实现了基础的游戏功能。因此想要浅谈一下最近学习到的新技能。
  由于课程设计作业的查重要求,我不会具体描写部分代码功能的具体实现。记录开发过程与程序源代码的Github仓库将会在所有作业完成截止后设置为开放。 当然,我相信不会有人来看我的垃圾代码的

图形化界面

  由于本人能力有限,因此在开发时选择了较为简单的EasyX进行开发。官方文档可以在这里查看

我们可以看到,对于最基本的程序框架来说:

1
2
3
4
5
6
7
8
9
10
11
#include <graphics.h>   // 引用图形库头文件
#include <conio.h>
int main()
{
initgraph(640, 480); // 创建绘图窗口,大小为 640x480 像素
/****
进行其它操作
*****/
closegraph(); // 关闭绘图窗口
return 0;
}

由于其对于窗口的操作是单图层覆盖的模式,因此需要留意写入造成的影响与写入前后的擦除

对于背景的操作

使用setbkcolor(0xE7EFDE)设置背景颜色为0xE7EFDE(16进制颜色)
使用setbkmode(TRANSPARENT)设置图案填充和文字输出时的背景模式为透明(默认为用当前背景色填充,在其它图像上输出时会有覆盖)
使用cleardevice()清楚屏幕所有绘制

使用clearrectangle(left,top,right,bottom)以上下左右位置清除长方形区域的绘制

输出图像

1
2
3
4
5
6
7
setlinecolor(0x332300);  //设置线条颜色
setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 2); //设置线条绘制模式为 线形为实线 端点为平坦

rectangle(left,top,right,bottom); //以上下左右位置坐标画长方形(无填充)

setfillcolor(WHITE); //设置填充颜色
fillrectangle(left,top,right,bottom); //绘制有填充的矩形

输出文字

1
2
3
4
TCHAR start[] = _T("开始游戏");
settextstyle(30 , 0, _T("微软雅黑")); //设置当前字体为高 30 像素的“微软雅黑”
settextcolor(BLACK); //设置输出文字颜色
outtextxy(x , y , start); //在(x,y)坐标输出自适应字符集start记录的字符串

以整形数字输出

1
2
3
4
5
6
7
void printnum(int x, int y, int printnum)//在x,y位置输出数字'printnum'
{
TCHAR s[8];
_stprintf_s(s, _T("%d"), printnum);
outtextxy(x, y, s);
return;
}

读取鼠标操作

1
2
3
4
5
6
ExMessage m;    // 定义消息变量
while(true)
{
m = getmessage(EX_MOUSE | EX_KEY); // 获取一条鼠标或按键消息
//识别对应鼠标或按键,以及对应的操作
}

ExMessage这个结构体用于保存鼠标消息

  • 示例(声明ExMessage m;):

    鼠标左键按下m.lbutton == true
    鼠标的 x 坐标m.x

    或者使用message获取消息标识
    m.message == WM_LBUTTONDOWN 左键按下消息
    m.message == WM_LBUTTONUP 左键弹起消息

C++实现多线程

以C++多线程实现计时器操作为例:

函数本体:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <thread>   //多线程
#include <chrono> //计时器

void printusetime()
{
long long minutes = 0;
long long seconds = 0;

while (true)
{
std::this_thread::sleep_for(std::chrono::seconds(1)); //等待1秒
seconds++;

if (seconds >= 60)
{
minutes ++;
seconds = 0;
}

if (!timecontinue)
break;
}
return;
}

其中,timecontinuebool类型的全局变量,用于在外部控制此线程结束的标识

在主函数当中,使用std::thread timecutdown(printusetime)开启该进程,使用timecutdown.join()函数等待子线程结束后,主线程才会继续执行并退出