一、绘制图像
如果让太空飞船进行太空可能要花费上亿美元,但是让我们的太空飞船显示在屏幕上只要调用一个简单的API函数,实际上,我们使用API函数是考虑了速度因素,正常情况下PaintPicture方法就足够了。然而,由于太空船将到处做曲线运动,我们将调用BitBlt这一个API函数,它并没有特别的地方,只是将两个图象融合成一个图象。使用一些聪明的"技巧",我们可以将太空飞船放入到一个充满星星的背景之中,并能让它到处移动。
好了,上面的介绍已经很充分了,让我们介绍一下BitBlt函数声明:
Declare Function BitBlt Lib "gdi32" _ (ByVal hDestDC As Long, ByVal x As Long, _ ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As _ Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long |
上面的声明虽然看上去很复杂,但实际使用中却相当容易。
无论什么时候,当
在Windows下绘制图象时,用于绘制的区域有大量的特性,包括尺寸、颜色和设备类型。所有这些信息都被
封装在一个称为"设备上下文"的对象中。尽管VB尽其所能来隐藏它们,因为它们只用在API函数中,但实际上所有可以用来绘制的物体都拥有设备上下文(下文将简称"DC"),包括打印机、图片框和窗体。所有的上述的对象都提供了指向DC的句柄,它可以通过对象的hDC属性来获取。在调用BitBlt这个API函数时所使用的 hDescDC 和 hSrcDC参数正是这个属性。
X和Y参数用来说明在目标区域进行绘制图象时的起始位置,nWidth和nHeight参数说明源图象的尺寸大小,xSrc和ySrc用来定义目地区域抓取源图象的尺寸大小。因为我们正在使用API函数,所以必须工作在像素模式下,所以只要使用图片框控件,就要将"scalemode"属性设置为3 - Pixels。
最后一个参数dwRop将带来各种填充、混合效果,它允许你按位(bit)为单位来操作,将源图象与目标图象融合在一起。它使用与PaintPicture方法相同的常量,这些常量可以在
帮助文件中查询。它们包括:vbSrcCopy,直接将源图象拷贝到目标区域;vbSrcInvert,我们将在后续程序中用到它,让太空船放入到布满星星的背景中。
下面让我们来看看如何使用这个API函数。
启动VB,并创建一个标准的EXE工程,在Form1窗体中放入两个尺寸相同的图片(
Picture)控件,在Picture1中载入你的宠物照片,或是你喜爱的
主题公园风景照,或是Windows的云彩背景图片。确定两个控件的尺寸足够容纳图象。另外,在窗体中放入两个按钮控件。将第一个按钮的"
caption"属性设置为"COPY",在这个按钮的
click事件中添加如下代码:
Private Sub Command1_Click() Picture1.ScaleMode = vbPixels Picture2.ScaleMode = vbPixels BitBlt Picture2.hDC, 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture1.hDC, 0, 0, vbSrcCopy End Sub |
将第二个按钮的"caption"属性设置为"Invert",在这个按钮的click事件中添加如下代码:
Private Sub Command2_Click() BitBlt Picture2.hDC, 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hDC, 0, 0, vbDstInvert End Sub |
现在,编译你的应用程序,试着点击这两个按钮观看代码所产生的效果。当点击命令按钮Button2时,图片是不是按位操作实现了反转,如果是,正是我所想提供的效果。
到目前为止我们已经做好了让飞船进入太空的准备。现在到了添加其他一些现实元素,如星星的时候了,我原来考虑制造具有火焰及3D效果的小球来代表星星,但它对于我们的着陆游戏来说有点显得过于专业,所以到现在我还是坚持使用黄色的小点来代表处它。
在游戏的开始,我们需要在容纳飞船的图片框架内绘制星星。所以,我们必须遍历图片框内的所有像素,并决定在某一个特定的点上是否有一个星星。正如你将在下面看到的一样,我们可以通过For...Next
loop循环来实现一个功能。VB提供了一个PSet函数来设置某一个像素点的颜色,但它的速度太慢,所以我们使用另外一个API函数,SetPixelV。这个函数声明如下:
Declare Function SetPixelV Lib "gdi32" Alias "SetPixelV" (ByVal hdc As Long, _ ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long |
这个函数实质上等同于SetPixel函数,但是它的速度更快,因为它不返回设置像素点的颜色。正如你所看到的,我们必须又一次使用图片框的hDC属性。x 和 y是像素点的坐标,它以像素为单位。crColor是将要设置的RGB颜色值。