现在的位置: 首页 > 综合 > 正文

游戏开发新手入门之位图化图形4

2013年09月06日 ⁄ 综合 ⁄ 共 2863字 ⁄ 字号 评论关闭
颜色键

   颜色键使一个位图被拷贝到另一个位图上时,不使所有的象素都显现。例如:当你把一个精灵(游戏中会动的对象一般都称作精灵)拷贝到地图上(背景上)时,这个精灵位图一般不会是一个精灵形状的位图,它通常都是一个矩形位图,位图里包含你所需要的精灵(除非你的精灵就是一个矩形机器人):

   游戏中,地图是先于精灵显示的,那么精灵走到树后时,还应有相应被遮挡的部分,这个先不讨论,下一节再说。现在,对我们更重要的是,如果不应用颜色键,这个精灵将永远带着这个黑色底框,这是绝对不能容忍的。

   为了解决这个问题,我们使用源颜色键。这个源颜色键告诉你精灵矩形的哪些颜色将不被拷贝(当然我们是让黑色不被拷了)。一个颜色键由两个值组成:一个低位颜色值,一个高位颜色值。当一个颜色键被申请使用时,在两个值之间的颜色,包括这两个值的颜色都将不会被拷贝。在DirectX中有一个结构用来处理它,叫作DDCOLORKEY,看看吧:

typedef struct _DDCOLORKEY{
DWORD dwColorSpaceLowValue;
DWORD dwColorSpaceHighValue;
} DDCOLORKEY, FAR* LPDDCOLORKEY;

   很简单的结构,我就不解释了。我将展示给你使用了颜色键之后的效果。我使用颜色键的高位和低位两个值仅仅把黑色包括在它们之间。因此,黑色是唯一不会被拷贝的颜色。

   好多了,是不是?这就是我们想得到的结果!现在,在我告诉你怎样建立和使用颜色键之前,我还有说一说目标颜色键,尽管我们的确我们不常用到它(我们常用的是源颜色键)。鉴于源颜色键定义了哪些颜色键不能被拷贝,目标颜色键定义了哪些颜色不能被写入(覆盖)。听起来很怪异,是不是?我也有同感。举个实例你就明白了。当你要把A位图拷贝到B位图的下面,意思就是把A位图作为背景,例如由于某种理由,需要把一个文本框拷贝到空的后缓冲区,然后再把背景画面拷贝到这个后缓冲区,但你又不能覆盖先前的文本框。因此,在后缓冲区里除了文本框的那些黑色的部分才能被写入象素。

   我也不清楚你什么时候需要处理这种情况,但是你的确可能用到(一旦你用到了,可千万要告诉我哦,我一直没有遇到这种情况呢^_^)。现在,你已经知道什么是颜色键了,让我们看看怎样使用它们吧!

  置颜色键

   在DirectDraw中有两种方法使用颜色键。第一种,你可以链接一个颜色键(或者两个,如果你同时使用源和目标颜色键)到表面,然后在位块传输时定义DDBLT_KEYSRC,DDBLT_KEYDEST,DDBLTFAST_SRCCOLORKEY或DDBLTFAST_DESTCOLORKEY标志,具体使用哪个标志,取决于你使用哪个位块传输函数和使用哪种颜色键。第二种,你可以创建一个颜色键,然后通过DDBLTFX结构传送给位块传输操作。当你不断地需要使用颜色键时,我向你推荐第一种方法;反之,当你偶然要使用一次颜色键,就用第二种方法吧!

   你可以把颜色键链接到已经建立好了的表面,也可以在建立表面的同时建立颜色键。两种方法我都将详细告诉你。假设你工作在16-bit显示模式下,是565象素格式,你要在后缓冲区使用一个仅包含黑色的源颜色键。如果你的后缓冲区已经建立好了,你就可以简单建立一个DDCOLORKEY结构,然后把它传递给IDirectDrawSurface7::SetColorKey()函数,如下所示:

HRESULT SetColorKey(
  DWORD dwFlags,
  LPDDCOLORKEY lpDDColorKey
);

   记住要用FAILED()宏检测这个函数的返回值,保证一切都在计划之中。函数的参数很简单:

   ※ DWORD dwFlags:决定所使用颜色键类型的标志。以下三个是你将用到的:

   · DDCKEY_COLORSPACE:该结构包含一个颜色范围,如果结构包含的是单独的颜色键则不作设置。

   · DDCKEY_DESTBLT:该结构指定颜色键或者颜色范围作为用于位块传输操作的目标颜色键。

   · DDCKEY_SRCBLT:该结构指定颜色键或者颜色范围作为用于覆盖操作的颜色键。

   ※ LPDDCOLORKEY lpDDColorKey:这是指向DDCOLORKEY结构的指针。

   就这么多。你可以根据你所需要使用的颜色键适当地定义位块传输的标志。注意,一个颜色键链接到表面,并不意味着你每一次必须使用它。如果你只定义了DDBLT-WAIT或DDBLTFAST_WAIT标志,颜色键将被忽略。下面是设置颜色键的方法:

DDCOLORKEY ckey;
ckey.dwColorSpaceLowValue = RGB_16BIT565(0, 0, 0); // or we could just say '0'
ckey.dwColorSpaceHighValue = RGB_16BIT565(0, 0, 0);
if (FAILED(lpddsBack->SetColorKey(DDCKEY_SRCBLT, &ckey)))
{
  // error-handling code here
}

   如果你要为已经建立的颜色键链接一个表面,有几件事情你需要做。首先,当你定义DDSURFACEDESC2结构的有效成员时,你需要使dwFlags成员包含DDSD_CKSRCBLT或者DDSD_CKDESTBLT标志,具体使用哪个标志,取决于你要使用哪种颜色键。回头再看看DDSURFACEDESC2结构,它包含两种DDCOLORKEY结构。一种称为ddcdCKSrcBlt,另一种称为ddcdCKDestBlt,填写适当的结构来创建表面。你就需要干这么多!以下是关于640×480大小的离屏表面的实例代码:

// set up surface description structure
INIT_DXSTRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
ddsd.dwWidth = 640; // width of the surface
ddsd.dwHeight = 480; // and its height
ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = RGB_16BIT(0,0,0); // color key low value
ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = RGB_16BIT(0,0,0); // color key high value
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; // type of surface

// now create the surface
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpddsBack, NULL)))
{
// error-handling code here
}

   关于颜色键的部分到此结束。现在我们可以进行本章最后一项了——剪切。

抱歉!评论已关闭.