在即使战略游戏中两军对战时,程式在每一帧都要根据上一帧每个战斗单位的位置和该战斗单位移动的目的、到该目的之间的障碍物的位置连同一定的路径算法确定在当前帧该战斗单位的新位置;更有要取得在上一帧时该战斗单位的生命值和所受的打击次数及强度,以确定该战斗单位的生命值。
通过阅读ProcessInput()函数的代码,我想您一定已理解了刷新游戏单元的概念。而从上面的两个例子中,您也一定发现用例程的方法很难实现这两类游戏的需要。我们不可能对每一颗子弹,每一个战斗单位进行操作,而且我们并不知道游戏者会一次发射多少颗子弹也不知道游戏者会造多少个战斗单位。我们应该怎么办呢?
考虑到每一个战斗单位(或每一颗子弹)都有相似(或相同)的属性,那么我们能够采用结构数组来储存每一个战斗单位的位置和状态。这个办法好象可行!但是仔细想想,我们又碰到了上面谈到的问题我们并不知道游戏者会一次发射多少颗子弹也不知道游戏者会造多少个战斗单位。当然我们能够采用Age of Empire的方式----限制单位的数量(我并不是说Age of Empire采用的是这种办法)。但是这意味什么呢!意味着,假如我们限定数量为50的话,在游戏者只有一个士兵时,电脑却需要为这个士兵分配50倍的内存!而且游戏者还不一定造出50个士兵。显然这并不是个好办法!
我们应该怎么办呢?链表!链表能满足我们的需要。
class Node
{
file://双向链表的指针。
Node* Next;
Node* Pre;
file://节点数据。
NODE_DATA data;
...
};
链表是一种结构体的集合。在链表中的每一个结构体都包含了一个元素或指针,他指向链表中的另一个结构体。这个指针用作两个结构体之间的联系。这个概念和数组有些相似,但他允许链表的动态增长。现在的游戏中凡是碰到这种问题的一般都是采用链表的。关于链表的更多的信息请阅读有关的资料。
第六节 画游戏单元
画游戏单位的作用是在每一桢往屏幕上画游戏单位的图象。
这就是本例程中画游戏单元的主函数:
/*
* NewGameFrame
*/
int NewGameFrame( void )
{
file://这里是配置游戏单元的位置:
SetSpriteX( hFox, 0, P_AUTOMATIC );
SetSpriteY( hFox, 0, P_AUTOMATIC );
SetPlaneVelX( hBackground, GetSpriteVelX(hFox), P_ABSOLUTE );
SetPlaneVelX( hMidground, GetSpriteVelX(hFox), P_ABSOLUTE );
SetPlaneVelX( hForeground, GetSpriteVelX(hFox), P_ABSOLUTE );
SetPlaneX( hBackground, 0, P_AUTOMATIC );
SetPlaneX( hMidground, 0, P_AUTOMATIC );
SetPlaneX( hForeground, 0, P_AUTOMATIC );
SetSpriteX( hBear, 0, P_AUTOMATIC );
SetSpriteX( hApple, 0, P_AUTOMATIC );
SetSpriteY( hApple, 0, P_AUTOMATIC );
file://将游戏单元的图像贴到BackBuffer上:
if( bTransDest )
{
gfxFillBack( dwColorKey );
DisplayFrameRate();
DisplaySprite( hBuffer, hApple, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hBear, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hFox, GetPlaneX(hForeground) );
DisplayPlane( hBuffer, hForeground );
DisplayPlane( hBuffer, hMidground );
DisplayPlane( hBuffer, hBackground );
}
else
{
DisplayPlane( hBuffer, hBackground );
DisplayPlane( hBuffer, hMidground );
DisplayPlane( hBuffer, hForeground );
DisplaySprite( hBuffer, hFox, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hBear, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hApple, GetPlaneX(hForeground) );
DisplayFrameRate();
}
file://更新前景:
gfxSwapBuffers();
return 0;
} /* NewGameFrame */
画游戏单元的顺序为:
1。清BackBuffer;
这是清BackBuffer的函数:
/*
* gfxFillBack
*/
void gfxFillBack( DWORD dwColor )
{
DDBLTFX ddbltfx;
ddbltfx.dwSize = sizeof( ddbltfx );
ddbltfx.dwFillColor = dwColor;
IDirectDrawSurface_Blt(
lpBackBuffer, // dest surface
NULL, // dest rect
NULL, // src surface
NULL, // src rect
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
} /* gfxFillBack */
2。检查游戏单元图像的Surface是否丢失;
这是检查游戏单元图像的Surface是否丢失的函数:
/*
* gfxRestoreAll
*
* restore the art when one or more surfaces are lost
*/
BOOL gfxRestoreAll()
{
GFX_BITMAP *curr;
HWND hwndF = GetForegroundWindow();
Splash();
for( curr = lpVRAM; curr != NULL; curr = curr->link)
{
if (curr->lpSurface &&
(fForceRestore || IDirectDrawSurface_IsLost(curr->lpSurface) == DDERR_SURFACELOST))
{
if( !gfxRestore(curr) )
{
Msg( "gfxRestoreAll: ************ Restore FAILED!" );
return FALSE;
}
}
}
DDClear();
fForceRestore = FALSE;
return TRUE;
} /* gfxRestoreAll */
3。将游戏单元的图像画到BackBuffer中;
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




