Windows编程 GDI简单图形的绘制 简单实现锁帧效果

原创 2016年08月30日 00:31:50

版本:VS2015 语言:C++

 

快要到9月份了,天气渐渐凉了,没有空调的我终于渐渐看到了光明。

 

现在书的进度进入都最后一章的Windows编程,嘛,和作者的态度差不多,Windows编程实在是枯燥乏味,但是也是必须去了解一些基础的知识,不然看到别人的程序就懵逼了。

 

最后一章我分为两个章节来讨论,首先是GDI图形绘制(相比于使用GPU硬件加速的D3D肯定要慢)、锁帧效果,之后是作者做的游戏控制台程序,说不定我能玩出点花样来,现在还没有看。

 

好了,让我们进入正题吧。

 

点,所有图形的基础,想要绘制一个图形就得要知道怎么绘制一个点。让我们来看看代码(代码放在GameMain函数处,不清楚的请看一下我写的Windows编程第二节,即游戏循环框架的基本实现):

HDC hdc = GetDC(hwnd);	//获取图像设备表
int x = rand() % 400;	//随机x、y坐标
int y = rand() % 400;
COLORREF color = RGB(rand() % 255, rand() % 255, rand() % 255);	//随机来个颜色
SetPixel(hdc, x, y, color);	//画点!
Sleep(100);
ReleaseDC(hwnd, hdc);	//释放

画点很简单吧,但是点太小了吧,根本看不清啊,来个大点的:

HDC hdc = GetDC(hwnd);	//获取图像设备表
int x = rand() % 400;	//随机x、y坐标
int y = rand() % 400;
COLORREF color = RGB(rand() % 255, rand() % 255, rand() % 255);	//随机来个颜色
int size = 4;	//设置点的大小
for (int i = 0; i < size; ++i)
	for (int j = 0; j < size; ++j)
		SetPixel(hdc, x+i, y+j, color);	//画点!
Sleep(100);
ReleaseDC(hwnd, hdc);	//释放

效果:



嗯,很棒!有点了,然后就是要画线了,画线的话首先要学到一个画笔的系统,在画之前首先就要设置画笔,这跟画点有点不一样,画点什么都不用管,看代码:

int x = rand() % 400;	//随机x、y坐标
int y = rand() % 400;
int x2 = rand() % 400;	//随机x2、y2坐标
int y2 = rand() % 400;
COLORREF color = RGB(rand() % 255, rand() % 255, rand() % 255);	//随机来个颜色

HDC hdc = GetDC(hwnd);	//获取图像设备表
HPEN pen = CreatePen(PS_SOLID, 1, color);	//获取铅笔
SelectObject(hdc, pen);	//设置铅笔
			
MoveToEx(hdc, x, y, NULL);	//把点移动到初始点
LineTo(hdc, x2, y2);	//画线!

Sleep(100);

DeleteObject(pen);
ReleaseDC(hwnd, hdc);	//释放

效果:



以上就实现了画线的效果,需要注意的是画边框之类的线条结构,基本都是要设置HPEN铅笔的,而实心结构则需要设置画刷HBRUSH。

 

下面讲随机画矩形的示例,这边即用到了画笔画出矩形的边框,又用画刷填充矩形:

// 初始化坐标数据
int x = rand() % 400;	//随机x、y坐标
int y = rand() % 400;

// 设置绘图相关数据
HDC hdc = GetDC(hwnd);	//获取图像设备表

COLORREF color = RGB(rand() % 255, rand() % 255, rand() % 255);	//随机来个颜色
HPEN pen = CreatePen(PS_SOLID, 1, color);	//获取铅笔
SelectObject(hdc, pen);	//设置铅笔

color = RGB(rand() % 255, rand() % 255, rand() % 255);	//再来随个
HBRUSH brush = CreateSolidBrush(color);	//获取画刷
SelectObject(hdc, brush);	//设置画刷

//绘制
Rectangle(hdc, x, y, x + 10, y + 10);

Sleep(100);

//释放对象
DeleteObject(pen);
DeleteObject(brush);
ReleaseDC(hwnd, hdc);

非常好!这样我们就能随机绘制正方形了。细心的玩家可能注意到了,在设置铅笔和画刷的时候使用的函数都是一样的,都是SelectObject、DeleteObject。我想这个方法肯定不止用在这,否则也不会叫做Object了。具体我就不探究了。

 

什么,你想画圆?也很简单,之前不是学了画矩形嘛,在Windows中画圆其实就是绘制矩形的内切圆,参数是一模一样的,只需要把绘制矩形的代码写成:

Ellipse(hdc, x, y, x + 10, y + 10);

就是这种弧线锯齿很严重,非常想学抗锯齿的知识!

 

接下来是多边形,给大家一个画六边形的代码,具体更多有趣的玩法,请自己尝试尝试。

 

下面是代码:

POINT poly[6] = { {x + 10, 0 + y}, {x + 30, 0 + y}, {x + 40, 17.3 + y}, {x + 30, 34.6 + y}, {x + 10, 34.6 + y}, {x + 0, 17.3 + y} };	//六边形的坐标
Polygon(hdc, poly, 6);	//根据6个点进行绘制,注意点的顺序很有关系


把绘制矩形的代码替换成以上代码,就能获得一下效果:



其实想想看,关键绘制的代码就那么一两句,而且hdc、pen、brush之类的非常常用,所以真正编写的时候设置成全局的变量会比较舒服吧,这样实际的代码会非常的简洁,以后要改什么功能也不必关注这类初始化、销毁的细节。

 

最后作者问了一个问题,如果你绘制时点的顺序是混乱的,绘制多边形的时候很容易绘制出凹多边形,那么如何判断一个多边形是否是凸多边形呢?

 

我一开始的想法有点简单了,后来百度查了一下了解到了凸多边形的定义,就是任意两个临近的点画一条直线,所有其他的点都在直线的一侧就可以判断出是凸多边形了。

 

具体代码实现给大家讲一个思路,循环临近的所有两点,根据其他点的x坐标,算出临近两点画出直线对应的y坐标,这个y坐标是在直线上的,跟判断点的y坐标对比一下,看看其他的各点是否都大于(或都小于)y坐标。

 

最后讲一下实现锁帧的效果,当然也是GameMain处的代码:

DWORD start_time = GetTickCount();	//获取开始的时间
//画点画线的各种处理
while ((GetTickCount() - start_time) < 1000);// 延时代码

这里的代码就增强的Sleep的效果,没想到锁帧这么容易吧?

 

对了,突然想起来忘记比较重要的定时器了,嗯……简单介绍一下:

UNIT SetTimer(HWND hWnd,	//图形设备表
UINT nIDevent,	//定时器的id
UINT nElapse,	//延时的毫秒数
TIMERPROC lpTimerFunc);	//延时的回调函数,NULL的话默认WinProc处理

待定时完成,就会触发处理事件WinProc,事件的类型是WM_TIMER,然后根据参数wparam就能判断出定时器的id,进行相应的处理。

 

KillTimer(hwnd, timer)是删除定时器的函数。具体例子就不说了,其实跟cocos的schdule非常像。

 

简单却很重要,就是这个东西吧。



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

【Windows编程】系列第五篇:GDI图形绘制

 上两篇我们学习了文本字符输出以及Unicode编写程序,知道如何用常见Win32输出文本字符串,这一篇我们来学习Windows编程中另一个非常重要的部分GDI图形绘图。Windows的GD...

Windows编程 我与Direct的第一次 简单颜色显示的实现

版本:VS2015 语言:C++   最近简直忙死了。晚上抽空把博客写了。   这几天也是深深感觉到自己能力的不足,最近貌似要开3D项目了,比起在老代码上爬滚,还是想写自己的新代码啊。   ...

Windows编程 从消息窗口到基本窗口 游戏循环窗口框架的简单实现

版本:VS2015 语言:C++   本来想昨天写个消息窗口的内容,讲一些好玩的东西,不过没有时间了,就放到一起了。   今天正好把书的第二章看完了,感觉良好,Windows的编程确实难度要高...

C++实现俄罗斯方块源码分享(Windows编程),有图形界面

本程序在vs2013平台上编译通过,在Windows10系统中正常运行,包含暂停、结束、等级等功能。

windows编程(四)制作简单的全屏幕截屏软件

参考了网上别人写的例子程序,

Windows编程 基本资源的使用 如何在窗口中输出一些简单的文本

版本:VS2015      语言:C++   今天不知道为什么没什么工作,书看着看着第三章就结束了,Windows高级编程部分内容比较杂乱,东西也比较多,但是作者压缩得很好,把多数懂点都突出出来...

Windows编程 VC++6.0到VS2015 实例小游戏的简单移植 VS下常见错误的排查

版本:VS2015      语言:C++   今天开始进入游戏开发最底层的Windows程序开发!   新翻开这本《Windows游戏编程大师技巧》,感觉真的是棒极了,恨不得十年之前就能学到...

三. 简单绘图--Windows编程课程学习笔记

三. 简单绘图--Windows编程课程学习笔记

Windows编程(4)|SDK键盘鼠标消息的简单处理

先看一下键盘按键按下时的消息   鼠标消息   下面是我对键盘和鼠标的一个消息处理过程,这只是消息处理函数部分 //窗口过程函数的实现(消息处理函数) LRESULT CALLBAC...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)