科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件DirectDraw之C#入门攻略

DirectDraw之C#入门攻略

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

DirectX本身为游戏开发的一套SDK,其本身原来仅仅是用来与OpenGL,3DFX竞争的一套用于视频游戏开发的SDK

作者:林敏 来源:aspcn 2007年11月14日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
由于我们使用的是BMP位图文件也就是一个DIB文件,它的头文件包含了调色板以及其他的一系列属性,dDDesc1已经被设置过了,所以就不用再来设置了。RECT是用于控制显示区域的结构体。Blt就是我们用来在surface之间转换数据的方法,也就是画图的方法,其实与之类似的还有Flip,Flip方法使用一个缓冲层来避免过多在Primary上的切换以换取效率,具体方法还是看一下在线帮助,这里就不作介绍了。BltFast的第一个参数和第二个参数用于控制IMAGE出现的顶点坐标(屏幕坐标系,单位长度为1个像素),RECT控制的是IMAGE是图片的哪一部分图片,所以这里IMAGE所指定的是整幅图片,也就是说我们可以局部的显示图片。运行的结果如下图;


  可以看到我们所绘制的图片并不再frm的区域里面。这是由于PrimarySurface代表的是整个
可见区域,所以我们以0,0为起始绘图自然不能保证在frm内,这个时候我们需要用另一个blt方法blt;代码如下:

dx.GetWindowRect(this.Handle.ToInt32(),ref rectSec);
dDsurface.Blt(ref rectSec,dDsurfaceSec,ref rect,DxVBLib.CONST_DDBLTFLAGS.DDBLT_WAIT);

  rectSec就将图片限制在form所在的区域。效果如下:

  这一次图片的显示区域已经被限制到窗体上了,可是还有一点问题,窗体上方的控制条被覆盖掉了。这一次我们加入Clipper来限制图片绘制的边界。代码如下:

dDclipper=dDraw.CreateClipper(0);
dDclipper.SetHWnd(this.Handle.ToInt32());
dDsurface.SetClipper(dDclipper);

  Clipper取得的边界是form的句柄传递的,所以Clipper所覆盖的区域就是form的区域,这回我们可以看到正确的显示了;


  将代码整理如下

private void draw()
{
dDraw=dx.DirectDrawCreate("");
DxVBLib.DirectDrawClipper dDclipper;
dDraw. SetCooperativeLevel(this.Handle.ToInt32(),DxVBLib.CONST_DDSCLFLAGS.DDSCL_NORMAL);
DxVBLib.RECT rect,rectSec=new DxVBLib.RECT();
DxVBLib.DirectDrawSurface7 dDsurface;
DxVBLib.DirectDrawSurface7 dDsurfaceSec;
dDDesc.lFlags=DxVBLib.CONST_DDSURFACEDESCFLAGS.DDSD_CAPS;
dDDesc.ddsCaps.lCaps=DxVBLib.CONST_DDSURFACECAPSFLAGS.DDSCAPS_PRIMARYSURFACE;
dDsurface=dDraw.CreateSurface(ref dDDesc);
dDclipper=dDraw.CreateClipper(0);
dDclipper.SetHWnd(this.Handle.ToInt32());
dDsurface.SetClipper(dDclipper);
dDsurfaceSec=dDraw.CreateSurfaceFromFile("c:\\3.bmp",ref dDDesc1);
dx.GetWindowRect(this.Handle.ToInt32(),ref rectSec);
rect.Top=0;
rect.Left=0;
rect.Right=dDDesc1.lWidth;
rect.Bottom= dDDesc1.lHeight;
dDsurface.Blt(ref rectSec,dDsurfaceSec,ref rect,DxVBLib.CONST_DDBLTFLAGS.DDBLT_WAIT);
}

  现在只要在Form_Paint()和Form_Resize()中加入this.draw()任意改变窗体大小也可以正确显示图片了。接下来我们要在我们的Frm上来显示我们的角色了;这样我们还需要一个Surface,用来存放我们将要显示的角色。角色运动是由很多的图片连续播放的道德,一般我们都习惯于将这些图片全部都做到一个文件里面(如下图),需要哪个角色就显示那个区域就可以了。

  代码实现如下:

dDsurfaceActor=dDraw.CreateSurfaceFromFile("c:\\actorMove.bmp",ref dDDesc2);
rect.Top=0;
rect.Left=0;
rect.Bottom=dDDesc2.lHeight;
rect.Right=140;//Actormove.bmp每个动作之间的距离是140;显示的是第一个动作;
rectSec.Top+=60;
rectSec.Left+=30;
rectSec.Bottom-=(rect.Bottom-rect.Top)/2;
rectSec.Right-=(rect.Right-rect.Left)/2;
dDsurface.Blt(ref rectSec,dDsurfaceActor,ref rect,DxVBLib.CONST_DDBLTFLAGS.DDBLT_WAIT);

  我们看到的角色只是实际图片的一部分


  由于原图本身背景是黑色的,blt的时候就连角色一起画进去了。这个时候我们需要用到colorKey来屏蔽我们不需要的背景色。代码段如下:

DxVBLib.DDCOLORKEY dDcolorKey=new DxVBLib.DDCOLORKEY();
dDcolorKey.high=20; file://被屏蔽
dDcolorKey.low=0; file://的颜色介于这两者之间
dDsurfaceActor.SetColorKey(DxVBLib.CONST_DDCKEYFLAGS.DDCKEY_SRCBLT,ref dDcolorKey);
dDsurface.Blt(ref rectSec,dDsurfaceActor,ref rect, DxVBLib.CONST_DDBLTFLAGS.DDBLT_WAIT |DxVBLib.CONST_DDBLTFLAGS.DDBLT_KEYSRC);

  这会就可以看到正确的人物了。

  到这里DirectDraw的工作就只是剩下键盘的响应函数就已经基本实现了一个简单的游戏地图引擎了,是不是也并不是很难?至于键盘相应函数原理很简单,只要在键盘按下的时候刷新form然后按顺序显示人物图标同时rect的值随之改变就可以了。要是有兴趣的话可以自己试试看。DirectDraw绘图的速度很快,除了做游戏外还可以用来播放AVI甚至是MEPG文件或者是屏保,只要搭配相应的文件转换和解码模块使用就可以。好了,关于DirectDraw的介绍就道这里了。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章