转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> VB.NET程序 >> 正文
GIFs, JPGs和DirectInput Mouse在用VB做游戏的运用         ★★★★

GIFs, JPGs和DirectInput Mouse在用VB做游戏的运用

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1373 更新时间:2009/4/23 16:38:15

由于时间仓促,翻译的不是很好,希望大家能够将就看看。

 

将 GIFs, JPGs文件加载到表面
作者: W-Buffer
相对而言,不是很难,我们并不需要解码器来得到JPG的每一个字节,或任何类似于次的,相反,我们将用一个图片框来打开一个图片,然后再将其传到表面,但首先我门需要声明API函数:
Public 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
Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Public Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Public Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Public Declare Function StretchBlt Lib "gdi32" (ByVal hdc 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 nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
现在我们要为加载图片作好准备
Dim Pict1 As StdPicture
Set Pict1 = LoadPicture("MyPict.jpg")
创造表面:
Dim TDesc As DDSurfaceDesc2
TDesc.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
TDesc.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
TDesc.lHeight = CLng((Pict1.Height * 0.001) * 567 / Screen.TwipsPerPixelY)
TDesc.lWidth = CLng((TPict.Width * 0.001) * 567 / Screen.TwipsPerPixelX)
Set Surf = DDraw.CreateSurface(TDesc)
Dim SurfDC As Long, PictDC As Long
SurfDC = Surf.GetDC
PictDC = CreateCompatibleDC(0)
SelectObject Pict1.Handle, PictDC
我们将使用Dcs和Bitblt或StretchBlt来把Pic1复制到表面
只复制成一样大小:
BitBlt SurfDC, 0, 0, TDesc.lWidth, TDesc.lHeight, PictDC, 0, 0, vbSrcCopy

现在复制并且改变图片大小
StretchBlt SurfDC, 0, 0, StretchWidth, StretchHeight, PictDC, 0, 0, TDesc.lWidth, TDesc.lWidth, vbSrcCopy
释放DC:
Surf.ReleaseDC SurfDC
DelecteDC PictDC
Set Pict1 = Nothing

下一步该怎么作呢?下载SurfUtil。Bas,我将利用这一技巧来创造并加载图片
注意:有时StretchBlt不能正常显示GIF,那就是我添加了BitBlt这个函数的原因

.
特殊效果
你会懒的不想利用C/C++或汇编来创造一个动态连接库,并用那个动态连接库来完成特殊效果吗?
就让blitter(我不认识,也查不出来,可能是glitter,闪光)光栅操作(ROP)为你工作!
我的格言是让最小的努力为你带来最大的报酬!
在Vb中有不少可使用的ROP常数:
vbSrcPaint -逻辑或操作,源和目标图片,做一个模拟的Alpha混合效果。
vbSrcAnd - 逻辑与操作,灰度效果。
vbSrcInvert - 逻辑异或操作。
vbSrcErase - 翻转目标图片,然后再和源图片进行逻辑与操作
vbSrcCopy - 把原图片直接复制到目标图片上,在圆满的替换掉?(replacing it completely)
vbDstInvert -翻转目标图片,全部忽略原图片。
vbNotSrcCopy -翻转源图片,然后在直接复制到目标上,又是圆满的替换掉?(replacing it completely)
vbNotSrcErase - 对源图片和目标图片进行逻辑或操作,在翻转。
现在我们利用这些ROP有两个执行销毁的方法。我们能够使用APIBitBlt这个函数,,也可以使用DirectX的BltFx函数,只有用户的显卡能够使用硬件来支持ROP而不是软件模拟ROP,BltFx才能够工作,否则BltFx将会失败!无论怎样,BltFx失败时,API的BitBlt还是能够调用,在软件中,一切就绪时,BitBlt就决不会失败!
(深思熟虑:当使用BltFx时,它可以完美的将表面放到显存以使其借助显卡的Blitter(和上面的一样,不认识也查不出来)来快速访问,而当另外使用API函数BitBlt时,它却完美的将其置放到系统内存,否则数据将会被从显存中修改后带来,然后它将回到显存,没有效率啊!)
容易的知道确认用户的显卡是否硬件支持特殊的ROP是件很好的事,我写了一个简单的函数来确认:
Private Function TestROP(ByRef surfBack As DirectDrawSurface7, lngROP As Long) As Boolean

Dim objBltFx As DDBLTFX
Dim rectTemp As RECT
Dim surfTemp As DirectDrawSurface7
Dim udtDDSD As DDSURFACEDESC2

''''创造一个临时的表面
udtDDSD.lFlags = DDSD_HEIGHT Or DDSD_WIDTH
udtDDSD.lHeight = 1
udtDDSD.lWidth = 1
Set surfTemp = mdd.CreateSurface(udtDDSD)

''''设置BltFx的ROP操作代码
objBltFx.lROP = lngROP

''''源和目标矩形
rectTemp.Right = 1
rectTemp.Bottom = 1

''''测试BltFx 的能力
If surfBack.BltFx(rectTemp, surfTemp, rectTemp, DDBLT_ROP Or DDBLT_WAIT, objBltFx) <> 0 Then
TestROP = False
Else
TestROP = True
End If

End Function
简单的传递这个函数 一个参考到你的当前后备缓存和你感兴趣的ROP常数,它将把用户硬件是否支持特殊的ROP告诉你给你,它执行一个BltFx 的blit例子并且测试错误然后返回错误。
(注:这一段如果你懂就可不必看我写的,有一些英文短语不容易翻译成中文)
Simply pass this function a reference to your current backbuffer and the ROP constant you''''re interested in and it will inform you of the user''''s hardware capabilities. It does this by performing a sample BltFx blit and examining the error code returned.
现在我门知道如果我们希望的ROP已经被支持,我们就能往下继续并且执行我们的blit,如果ROP以被支持,我们也能像这样使用BltFx:


objBltFx.lROP = lngROP
msurfBack.BltFx rectDest, surfDisplay, rectSource, DDBLT_ROP Or DDBLT_WAIT, objBltFx
objBltFx的定义类型是DDBLTFX,必须和我们希望执行(被储存在lngROP中)的ROP一起被加载。一次,我们有我们的DDBLTFX类型填充,我们就能使用后备缓存的BltFx方法,传递源和目标矩形、我们期望的表面、一点常数(DDBLT_ROP和DDBLT_WAIT)和objBltFx,常数DDBLT_ROP是必须的,它将通知BltFx我们想使用DDBLTFX结构的成员lROP。If we''''re forced to use the BitBlt API, it can be handled in this fashion:


''''锁主表面的DCs
lngDestDC = msurfBack.GetDC
lngSrcDC = surfDisplay.GetDC

''''Do the fancy old-fashioned blit
BitBlt lngDestDC, intX, intY, intWidth, intHeight, lngSrcDC, 0, 0, lngROP

''''释放DCs
surfDisplay.ReleaseDC lngSrcDC
msurfBack.ReleaseDC lngDestDC
首先我们需要得到源(被blitte的表面,和上文的blitter有关,可能是DirectX的专有名词)和目标(后备缓存)的DC,一旦我们全部拥有,我们把它们作为BitBlt的参数,再和妖怪定义(?sprite的确是妖怪)和我们期望的ROP(lngROP)向前,然后必须释放DC,以免电脑当掉。
(First we need to acquire the source (surface to be blitted) and destination (backbuffer) DCs. Once we have them, we feed this data into the BitBlt call, along with our sprite dimensions and the ROP we desire (lngROP). Afterward we MUST release the DCs, lest we freeze the computer)

现在你得到了它!一点魔法般的函数,能让你在你的程序或游戏中使用这些漂亮的光栅,把源代码下载下来,来看看所有不同的ROP的效果吧!
So there you have it! A few magic little functions and you can employ nifty raster operations in your games and programs. Download the source to see all of the different ROPs in action.

推荐的DirectInput Mouse处理
这里有很多你看起来比较熟悉的东东,那时因为我学到的大部分关于在DirectX7中使用鼠标是来自Lucky的DirectInput教程,我仅仅超过教程的一点点,在这个教程中你间看到如何“剪下”鼠标当它正从屏幕上离开的时候,怎样将“Hot Spots”(关于Hot Spots请参考人民邮电出版社的《Visual Basic 6.0 和Windows API 讲座第十五章597页》)添加到鼠标的指针上,把鼠标指针放到DX的表面上的确很好,它首先能帮你阅读Lucky的DirectInput教程,如果你还没有,我不想解释你在这里能学到什么。

你将注意到当你在Windows中移动鼠标时,你将会注意到你把它只能移到底部或右部,直到坐标只剩一个像素(鼠标的X,Y坐标只剩一个像素)。如果你试着去在DX中用鼠标指针的任何一部分来画你的鼠标指针(甚至是不显示的部分),当 离开屏幕/DX表面时,似乎要忽略那条线,那是因为你不能在表面外画任何东东,不可能发生这种情况。所以我们需要把我们看不到,在屏幕外的部分剪下来。

事实上,在Windows中,你若真的做了以上多提到的,将会隐藏你鼠标的“Hot Spot”,你的鼠标指针同样会停止上下左右的移动,其实,HotSpot就是你鼠标指针在Windows上的一个像素,你的鼠标指针对Windows而言,不是32×32像素,它只是一个单一的像素,Windows仅仅将其围绕这那个像素来画鼠标指针,以使你看起来像个鼠标指针,仅仅看起来像,如果你的鼠标的HotSpot大小是32×32像素,那么你将会更有可能同时点击不止一个的按钮,如果按钮都彼此很近,那么换而言之,一个HotSpot就是鼠标指针中最重要的一个像素,其余的就当是陪衬,例如箭头,钢笔的顶端,或改变窗体大小的指针的中间就是它的HotSpot。

OK,让我们试着从一个鼠标指针中得到HotSpot。
你将需要这些变量和声明:
 

''''检测和剪切鼠标
Declare Function IntersectRect Lib "user32" (lpDestRect As RECT, lpSrc1Rect As RECT, lpSrc2Rect As RECT) As Long

''''声明为DirectX7的变量!
Global DXMouse As New DirectX7
''''The DirectInput object! DOUBLE-DUH!
Global DXMouseInput As DirectInput
''''Input Device object we''''ll use for the mouse
Global DXMouseInputDev As DirectInputDevice
''''Mouse state type
Global DXMouseState As DIMOUSESTATE


''''鼠标移动的速度
Global Const MOUSE_SPEED = 1
''''鼠标能移动的矩形范围
Global Mouse_Rect As RECT
''''鼠标指针的X(横)坐标
Global DXMouseX As Integer
''''鼠标指针的Y(纵) 坐标
Global DXMouseY As Integer
''''鼠标左键是否被按下?
Global DXLeftMouseButton As Boolean
''''鼠标右键是否被按下?
Global DXRightMouseButton As Boolean

''''鼠标HotSpot所在的矩形On Mouse Hot Spot Rectangle
Global HotSpot_Rect As RECT
''''鼠标的HotSpot X坐标
Global DXMouseHotX As Integer
''''鼠标的HotSpot Y 坐标
Global DXMouseHotY
''''是否显示鼠标
Global DXMouseVisible As Boolean

那些就是Lucky对源文件教程的评价,我可不想抄袭Lucky的,就像我前文所说的“我所学到的大部分是关于DirectX7鼠标是来自Lucky的DirectInput教程”,我做了少许关于变量名的改变是因为他的变量名并没有是我感觉到什么。

现在,4个新的东东分别是HotSpot_Rect,DXMouseHotX,DXMouseHotY,和DXMouseVisible。

HotSpot_Rect 就是让我们每每改变RECT时让我们直到的东东:当HotSpot在屏幕上时,他只会有一个像素那么大。
DXMouseHotX和DXMouseHotY是鼠标指针上HotSpot的X 和Y坐标:最左边的顶端被定义为(1,1)
DXMouseVisible仅仅是一个告诉我们如果我们准备将鼠标画到屏幕上的布尔值,因为有时我们并不想这样做
Now comes the Initialization Sub. Again this is the exact same thing in Lucky''''s Source, but I changed the variable names so we can all understand them.
现在有个初始化的过程,这和Lucky的源代码一样准确(其实就是一样),但是我改变了变量名,所以我们能够更容易的懂得。
Sub Initialize()
''''如果我们不能正常的初始化,逮住错误
On Error Resume Next

''''创造一个DirectInput部件
Set DXMouseInput = DXMouse.DirectInputCreate()
''''将鼠标作为diMouse设备来跟踪
Set DXMouseInputDev = DXMouseInput.CreateDevice("GUID_SysMouse")
''''得到鼠标输入设备的唯一性,但只有在前景模式时才有效
 
DXMouseInputDev.SetCommonDataFormat DIFORMAT_MOUSE
DXMouseInputDev.SetCooperativeLevel frmMain.hWnd, DISCL_FOREGROUND Or DISCL_EXCLUSIVE
DXMouseInputDev.Acquire

''''初始化鼠标的变量
DXMouseX = 0
DXMouseY = 0
DXLeftMouseButton = False
DXRightMouseButton = False

End Sub

在此我不想解释任何事,你将必须看看Lucky的教程和源代码来为你自己解释
现在,给新的材料加点旧的材料
Sub DXMouseRefresh()
''''刷新鼠标变量
''''得到当前鼠标的状态
DXMouseInputDev.GetDeviceStateMouse DXMouseState

''''强制跟踪不如重新跟踪
If Err.Number <> 0 Then DXMouseInputDev.Acquire

''''如果失败,退出此过程
If Err.Number <> 0 Then Exit Sub
On Error GoTo 0

''''根据HotSpot支持来校准鼠标X坐标
DXMouseX = DXMouseX + DXMouseState.x * MOUSE_SPEED
If DXMouseX < 0 Then DXMouseX = 0
If DXMouseX > 640 - DXMouseHotX Then DXMouseX = 640 - DXMouseHotX

''''根据HotSpot支持来校准鼠标Y坐标
DXMouseY = DXMouseY + DXMouseState.y * MOUSE_SPEED
If DXMouseY < 0 Then DXMouseY = 0
If DXMouseY > 480 - DXMouseHotY Then DXMouseY = 480 - DXMouseHotY

''''检测鼠标左键状态
If DXMouseState.buttons(0) <> 0 Then DXLeftMouseButton = True
If DXMouseState.buttons(0) = 0 Then DXLeftMouseButton = False

''''检测鼠标右键状态
If DXMouseState.buttons(1) <> 0 Then DXRightMouseButton = True
If DXMouseState.buttons(1) = 0 Then DXRightMouseButton = False

''''如果鼠标的图标移出表面外,使它不能显示
''''所以,当鼠标靠近边缘时校准鼠标的位置
If DXMouseX <= 608 Then
Let Mouse_Rect.Righ

[1] [2]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台