WIN32简单的透明效果制作
上一次我们已经说了位图的显示方法,而今天我们就上次的内容继续,怎样在背景图的基础之上在显示一个物体,并将二者融为一体。
其实这种特效对于任意一张图片可能并不好办,但对于做游戏用的特殊图片就简单得很,只需要大家熟悉位运算的基本操作即可。因为每张图片上的像素点都是由二进制组成,只需要我们让它们之间进行简单的组合就能产生不可思议的效果。
对于上次介绍的函数BitBlt(),不知道大家还能记住多少,但是我们必须熟练的掌握它,特别是它的最后一个参数,下边我将它的最后一个参数所能取的值排列出来:
| Raster值 | 说明 |
| BLACKNESS | 将来源位图转换成黑色 |
| DSTINVERT | 将目的地DC做“NOT”运算 |
| MERGECOPY | 将选择的笔刷与来源位图做“AND”运算 |
| MERGEPAINT | 先将来源位图做“NOT”运算,再与目的地DC做“OR”运算 |
| NOTSRCCOPY | 将来源位图做“NOT”运算 |
| NOTSRCERASE | 先将来源位图与目的地DC做“OR”运算,再将其做“NOT”运算 |
| PATCOPY | 将选择的笔刷贴到目的地DC上 |
| PATINVERT | 将目的地DC与选择的笔刷做“XOR”运算 |
| PATPAINT | 先将来源位图做“NOT”运算,再与笔刷做“OR”运算,最后再与目的地DC做“OR”运算 |
| SRCAND | 将来源位图与目的地DC做“AND”运算 |
| SRCCOPY | 将来源位图贴到目的地DC上 |
| SRCERASE | 先将目的地DC做“NOT”运算,再与来源位图做“AND”运算 |
| SRCINVERT | 将来源位图与目的地DC做“XOR”运算 |
| SRCPAINT | 将来源位图与目的地DC做“OR”运算 |
| WHITENESS | 将来源位图转换成白色 |
有了上面的表格,我们就可以按照所给的操作进行我们想要的结果。具体原理如下:
上边运行结果具体【代码下载】。
WIN32简单的绘制位图背景
位图属于GDI的对象之一,在一套游戏开发过程中,常常需要运用大量的位图来构造游戏的画面,这一次,我们就介绍一下窗口绘制位图的基本方式。
在一个游戏中,使用的位图数量是很多的,因此都会将位图存成文件,等到程序需要时再将文件加载到窗口中。将位图从文件加载到绘制窗口可以分为以下几步
1.从文件中加载位图对象。
2.建立一个与窗口DC兼容的内存DC。
3.内存DC使用相应的位图建立位图对象。
4.将内存DC的内容粘贴到窗口DC中,完成显示图像的操作。
5.释放相应的DC。
以上就是所需要的大致步骤,接下来一步步说明如何操作:
第一步:加载位图
要从文件中加载位图常用的是LoadImage()函数。
HANDLE LoadImage(HINSTANCE 来源实体, LPCTSTR 名称, UINT 位图类型, int 加载宽度, int 加载高度,UINT 加载方式);
第二步:建立与窗口DC兼容的内存DC
建立兼容的内存DC可以运用CreateCompatibleDC()函数。
第三步:选用位图对象
内存DC选用位图对象的方法和选用画笔画刷的方法一样吗可以调用函数SelectObject()来实现。
第四步:贴图
把内存DC中的位图复制到显示DC上,这一操作被称为“贴图”。这一操作的函数是BitBlt(),它很重要。
BOOL BitBlt(HDC 目的DC, int 目的DC的X坐标, int 目的DC的Y坐标,int 贴到目的DC的宽度,int 贴到目的DC的高度,HDC 来源DC,int 来源DC的X坐标, int 来源DC的Y坐标, DWORD 贴图方式);
第五步:释放资源
没申请一个DC都要释放相应的资源,内存DC也不例外,释放可以用函数DeleteDC(HDC DC名称);
经过上边的步骤,显示一张位图其实是很简单的,这里我就不具体编码了,只是提供一个例子代码,仅供参考。【源码下载】
运行结果:
WIN32实现简单动画的方法
简单的动画实现其实原理很简单,可以说是简单的不可思议。首先,我要说的是游戏中播放动画的方法主要有两种:一种是直接播放影片文件;另一种则是游戏进行时利用连续贴图的方式,制作动画效果。事实上游戏程序本身几乎都是以循环的方式不断地在游戏窗口中进行窗口重绘的操作,即使画面没有任何的变化,这个重绘的操作还是在不断的进行着,一直到玩家选择结束游戏为止。
动画简单的说就是会动的画。在这里我们只是简单的演示一下基本程序框架,所以我们选择了一组又连续动作并且背景为白色的6张图片。【图片下载】
接下来我们介绍一下在制作简单动画所需要的API:
Windows API函数SetTimer()函数可以为窗口建立一个定时器,并且每隔一段时间就会发出WM_TIMER消息,此函数的使用语句如下:UINT SetTimer( HWND,UINT,UINT,TIMERPROC);
SetTimer()函数的第1个参数是接收定时器消息的窗口,第2个参数是定时器的代号,第3个参数是定时器发出WM_TIMER消息的时间间隔,以千分之一秒为单位,也就是说将这个参数设为1000时,每间隔1秒发送一个WM_TIMER消息,第4个参数则是用来设定由系统调用处理WM_TIMER消息的响应函数,如果不用响应函数处理WM_TIMER消息,则此参数为NULL。
我们建立定时器之后要在程序关闭后停用定时器,否则会占用资源,相应的API为:
BOOL KillTimer(int 定时器代号);
定时器介绍完我们可以简单的通过上次的windows简单框架加入相应的代码即可。只需要加上定时器API,再加上相应的相应消息的地方加上绘图程序即可!不过在这里的绘图程序并不是我们常见的GDI,而是用以个贴图API循环完成的。这个API是BitBlt()函数,相应的方法,大家可以到网上查找,具体方法,我会在以后的博客中详细说明!
程序运行结果:
【程序代码】
C++PrimerPlus中文第五版总结(一)
C语言和当前最主流的语言一样,在最初面世时也是过程性语言,这意味着他强调的是算法编程方面。在算法方面,个人觉得C语言远比C++有优势,因为强调的是模块化,每一块都能通过代码来完全的展现数据之间的内在联系。那是一种思想的罗列,是一种算法的内在表现。在ACM中,C语言编程之所以远远的多于C++可能就是在这里。
C的一个原则就是自顶向下设计,在C语言中,其理念是将大型程序分解成小型的、便于管理的任务,这个过程将一直持续下去,直到将程序划分为小型的、易于编程的模块,它鼓励程序员开发程序单元(函数)来表示人物模块。结构化编程技反映了过程性编程的思想,根据执行的操作来构思一个程序。再剖析一个问题时,C语言能够很好的将问题的过程描述出来,这就是它的优势。它能够分析问题,来根据问题中的每一个内在动作构造相应的动态模块,再根据每个模块内在的联系,将问题描述出来,加以运用。这像什么呢?就像是一个未来战士中的液态机器人,他能够模拟任何他接触过的人类,今后,你没有必要在对原来那个人加以关心,只需要命令这个模仿后的液体机器人,他能够充分的表现出他模仿的那个人的性格和反映。而模仿一个人的难易程度就像是C语言描述算法过程的难易。这就是我目前的理解。
OOP提供了一种新方法。与强调算法的过程性编程不同的是OOP强调的是数据。OOP不想过程性编程那样试图使问题满足语言的过程性方法,而是试图让语言来满足问题的要求,其理念使设计与问题的本质特性相对应的数据格式。在C++中,就是一种规范,它描述了一种新型的数据结构,对象就是根据这种规范构造的特定的数据结构。OOP编程并不仅仅是数据和方法合并为类,它还有更多的高级功能。例如,OOP有助于创建可重用代码,这将减少大量的工作,信息隐藏可以保护数据,多态让您能够为操作符和函数创建多个定义,继承让您能够使用旧类派生新类。OOP引入了很多新的概念,使用的编程方法不同于过程性编程。他不是将重点放在任务上,而是放在表示概念上。
通用编程是C++支持的另一种编程模式。术语“通用”指的是创建独立于类型的代码。它与OOP的目标不同。OOP强调的是编程的数据方面,而通用编程强调的是算法方面。
预备知识总结于2010年8月17日 21:47:45
简单windows程序搭建
本篇文章主要是试着构建一个简单的windows应用程序,从大局着手,来简要介绍一个windows程序构建的过程,为今后的windows程序设计打下基础。
因为是游戏学习,所以我们介绍的应用程序并不会包含菜单和核按钮等窗口组建。在这里我们运用VC6.0来编写应用程序,虽然有些老,但他确实很普及,对于学习编程足以。
建立一个windows应用程序并不像控制台程序那样只有一个main函数就可以的搞定一切。这是因为window是图形操作系统,不管是显示什么,它都是以图像的形式展现在我们的眼前,而DOS确实字符型操作系统,所以windows程序设计比控制台程序麻烦得多!
windows程序设计抛弃了传统DOS程序的构建方法,引进了一种事件驱动的新方法,而该方法主要是基于消息的。我们对一个windows程序的操作,会直接被操作系统所感知,将我们的行为操作包装成一个个的消息,然后将他们投递到该应用程序的消息队列,而该程序就从消息队列中取出消息并进行相应响应,在这个处理过程中,操作系统也会给应用程序“发送消息”,所谓的“发送消息”,实际上就是操作系统调用程序中一个专门负责消息处理的函数,这个函数称为窗口过程。
大概介绍一下原理,我们接下来就建立一个简单的应用程序框架,发放如下:
- 建立WinMain主函数。他相当于C程序中的main函数,是整个程序运行的起始位置。
- 定义一个函数。其中包含所要建立窗口的相关信息,并向系统注册。在这里的MyRegisterClass函数就是进行定义和注册窗口类别的函数。
- 建立一个初始化函数。这个函数的作用是构建一个程序窗口的主要信息,如窗口标题、窗口样式之类的。最后显示更新窗口。在这里的InitInstance就是实现以上内容。
- 进入消息循环。
- 编写窗口过程函数。
一个windows应用程序的构建虽然麻烦,但思路很清晰,唯一新手所面对的麻烦就是一些自定义的宏和一些不知所云的系统函数和函数类型。不过这些都不是麻烦事,只学查一查MSDN就好。
程序运行结果如下:
留下源码,以供参考!【源码下载】
HDOJ 1029 – Ignatius and the Princess IV
【题目大意】HDOJ 1029 – Ignatius and the Princess IV
这道题的大概意思就是给你一批数,让你输出它们中特殊的那个。什么是特殊的?只要出现的次数至少为(n+1)/2个,它就算是特殊的。
【题目总结】
这道题目是一道水题,就是让你找出出现次数最多的那个!为什么这么说呢?
很简单,因为每批数都是奇数个,也就是说如果有一个数,它的个数大于(n+1)/2个,那么就可以肯定,剩下的数的个数没有一个超过(n+1)/2个,题目中每次输入都有输出,也就是说每次的测试数据都是有一个特殊的数,它的个数大与(n+1)/2个,并且它的个数是这批数中最多的。
既然知道只输出一个数,那么接下来就很简单了,我们可以这样做:
首先,输入。定义一个全局变量的整形数组,用来存放这批数。
其次,计算。将这批数进行排序,然后运用类似ZOJ 2478中的技巧,算出那个数的个数大于(n+1)/2个。
最后,输出。如果有直接输出+break。
通过上述方法成功AC,程序运行时间为140MS。【源码下载】
【综上所述】
总觉的这道题目有简单方法,等找到再说。


