http://216.5.163.53/DirectX4VB/Tutorials/DirectX7/DD_FileTypes.asp
通过对以前的学习,到目前为止,你应该只具备加载位图到绘图页上去的能力,的确,DDraw没有内建加载其它格式的图片文件到绘图页的功能,但这并不表明通过编程手段达不到,DDraw的这种局限是基于某种通用性考虑的,在一定意义上是一种优点,但是使用位图文件表明在分发程序时你将考虑位图庞大的体积,而这,是人们努力避免的,现在出现了一些压缩率很高的图片文件格式,在游戏程序中使用它们可达到可观的缩小游戏体积的效果.
举个例子,一张640*480*16大小的图片如果以位图文件格式保存它要占900kb的空间,如果保存为压缩比例比较高的.Jpg文件格式只占3.47kb大小的空间(是它最初体积的0.38%),如果以比较低的压缩比例把它存为.Jpg文件的话要占254kb的硬盘空间(大约是它压缩前的28%),而如果把它存为.Gif格式时,它经过压缩后只占312kb的空间(是它原来大小的35%).
正如你在上面看到的这些数字,它们表明,使用不同格式的文件格式可以在很大程度上降低文件大小,但有一点你要铭记在心,.Gif文件格式将只能使用256色深,而.Jpg格式的文件如果以较高的压缩比例来压缩的话,最后形成的3.47kb大小的文件图片质量将会很差.
在游戏中所有的涉及到择图的工作中,我的个人偏好是使用压缩比例低的Jpeg文件格式,28%压缩比例下的图片效果仍然是不错的,但是在游戏中对图片质量要求高的地方我仍然选择位图文件,比如在一些需要制作透明效果的场合下,根据权威的经验,因为精灵需要透明显示,所以它宜使用位图,除了精灵外,一些游戏中的小Logo,包括所有的需要透明显示的位图,最好都使用位图.
我上面所说的"小"的意思是指长宽尺寸都在250像素以下的图片,如果一张图片要全屏显示的话或这张图片将用作文字大背景,将它存为Jpg格式是一个很省资源的办法,因为它们在游戏中的尺寸是很大的,一些边幅上的阴影将不会对游戏整体效果产生明显的影响.
现在我们来看实际的代码,这篇文章将实现一个过程,这个过程的作用是自动加载Jpeg文件到绘图表面,这个过程将100%地正常工作,并且非常的容易,当然比起这个过程来还会有更快更好的方法,但是我发现它们当中的有些会运行不可靠并使问题复杂化,而我们接下来谈到的这个方法适用于你一开始就要加载大量的图片到内存中的情况,所以如果你的程序依赖于高效的图片载入和图片交换过程,以上的方法将会明显降低游戏运行速度.
Public Function CreateASurface(DirectdrawObject As DirectDraw7, DDSurface As DirectDrawSurface7, Width As Long, Height As Long, SourceFile As String) As Boolean
On Error GoTo errhandle:
Dim ddsdF As DDSURFACEDESC2
Dim Surfpic As Picture
ddsdF.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
ddsdF.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN And DDSCAPS_VIDEOMEMORY
ddsdF.lWidth = Width
ddsdF.lHeight = Height
Set Surfpic = LoadPicture(SourceFile)
SavePicture Surfpic, App.path & "\TempFile.Bmp"
Set DDSurface = DirectdrawObject.CreateSurfaceFromFile(App.path & "\TempFile.bmp", ddsdF)
Kill App.path & "\TempFile.Bmp"
Set Surfpic = Nothing
CreateASurface = True
Exit Function
errhandle:
CreateASurface = False
End Function
正如你看到的,以上的函数如果运行正确将返回True,函数体内的代码与通用的载入一个绘图页的过程十分相似,只是在它前面加入了一个转换过程,函数运用了一个VB变量(图片框)来装载图片文件,它将把这个图片按位图文件的格式保存到硬盘,于是这个位图文件可以直接地被加载到一个DDraw绘图页中,整个函数过程一完成的话,函数将从硬盘上删掉这个位图文件并清除图片框上的内容,此时这个位图在内存中的表现将不复存在.
这个函数的执行速度取决于图片的大小,我经过研究发现,函数从硬盘上加载一个640*480大小的图片仍然只花去了不到一秒的时间,这个数字当然这还要考虑我当时使用的硬盘的读入速度("不到一秒钟"是严格意义上的平均花费时间而不是其它特殊的情况).