Abattoirville 的冒险





5.00/5 (5投票s)
一款基于迷宫的游戏。
![]() |
![]() |
要运行此游戏,您需要 DirectX 8。尽管我没有使用任何 DirectX 8 的功能。您可以修改 Dinput 相关的代码,使用旧版本的 DirectX。游戏运行在 1024x768 分辨率下。
要编译此程序,您需要 VC++ 6 和 DirectX8 SDK。如果您遇到问题,请致电微软支持。
现在是关于有趣的编码部分。我只将在此讨论两个类。其他一些类在 DirectX 8 SDK 和 Advanced 3D Game programming 书籍中有介绍。
CMaze 类
此类负责读取文本文件并显示迷宫。构造函数接收将用于显示线条的纹理名称。
CMaze(char* pszTextureBMP);
通过调用 `LoadMaze` 方法加载文本文件。迷宫文本文件的格式如下:
(Name) (Number of Horizontal lines) (Vertical Coord) (Horiz Coord Start) (Horiz Coord End) (Vertical Coord) (Horiz Coord Start) (Horiz Coord End) . . (Number of Vertical Lines) (Horiz Coord) (Vert Coord Start) (Vert Coord End) (Horiz Coord) (Vert Coord Start) (Vert Coord End) . . (Number of Deploy points) (Deploy Point X) (Deploy Point Y) (Deploy Point X) (Deploy Point Y) . .
*(名称)* 是您可以为该关卡起的任何名称,它将显示在我的游戏底部。水平线和垂直线是在游戏中显示的用于构成迷宫的线条。部署点是敌人或食物可能出现的点。
纹理的尺寸决定了您为迷宫类提供的线条宽度。如果您调用 `DisplayGrid` 方法,您将看到迷宫屏幕是如何划分的。如果部署位置是 1,1,则实际屏幕位置是 `(1 * WidthOfTtexture, 1 * HeightOfTexture)`。要查看部署位置,您需要调用 `DisplayDeployRects` 并传入您的精灵尺寸,以便它可以为您绘制一个矩形。
`IsHit` 方法接收一个矩形,如果它与迷宫中的任何线条发生碰撞,则返回 true。线条实际上是一个矩形,其尺寸由纹理尺寸决定。
`GetPathFindingArray` 接收一个数组,并根据是否存在线条来填充 1 或 0。这对于创建表示迷宫的数组很有用,以便可以使用寻路算法。此函数在此游戏中未使用,尽管如果您将其与寻路算法结合使用,则可以使此游戏非常困难。
CSprite 类
这是游戏中 J 最有趣的类。它负责精灵的动画和移动。您可以通过调用来创建一个精灵:
void CSprite::CreateSprite(CSurface** ppSurface, long nType,long nHeight, long nWidth)
Surface 包含精灵的图像,Type 是用户定义的数据,您为其提供精灵的尺寸。精灵可以有不同的状态,例如向左行走或向右行走。您使用所有不同的状态调用 `AddState`,这些状态是给定精灵拥有的。
void CSprite::AddState(long nState, POINT ptFrame, long nNoOfFrames, long nDelay, RECT* prcBound, LPTSTR pszSound, bool bLoopSound)
*nState* 是您标识此状态的方式。稍后,您将使用此数字调用 `SetState` 来将精灵设置为此状态。
`ptFrame` 是 Surface 上包含此状态第一个图像的点。我们在这里不需要尺寸,因为它们对于精灵是固定的,并且在创建精灵时已提供。
*nNoOfFrames* 是此状态的帧数。例如,如果向左行走有三个动画图像,则 `nNoOfFrames` 将是 3。
*nDelay* 是动画更改的速率。 *nDelay* 是一个时间单位,该单位由 `update` 被调用的频率决定。您可以将该单位视为游戏脉冲。您的游戏可能每秒有 60 个脉冲,这完全取决于您的主游戏循环调用精灵的 `update` 方法的频率。
*prcBound* 是用于碰撞检测的边界矩形。当您调用 `IsHit` 时,如果给定的矩形与边界矩形相交,则表示发生碰撞。
每种状态还可以关联一个声音。
`void CSprite::EnableBorder(bool bDraw = false)` 显示精灵的边框和边界矩形。这对于调试很有用。
struct SMovement { long m_dx,m_dy; long m_nMoveDelay; long m_nCurrMoveDelay; bool (*m_pfnCollision)(RECT& rcRect); long m_nInvulnerable; long m_nPathFindDelay; long m_nCurrPathFindDelay; void (*m_pfnFindPath)(CSprite* pSprite); } m_Movement;
此结构控制移动。
*m_dx* 和 *m_dy* 是精灵移动的速率和方向。它调用 `m_pfnCollision` 指向的函数来查看新位置是否为空。如果发生碰撞,则调用 `m_pfnFindPath` 指向的函数来获取新的移动方向。
碰撞检测和寻路函数的原型是
bool fnCollision(RECT& rcRect); void fnFindPath(CSprite* pSprite);
*m_nInvulnerable* 是精灵在不被杀死之前应该延迟的时间,在此期间精灵会在显示中闪烁。
*m_nPathFindDelay* 是调用寻路函数来更新移动方向的速率。
如果您需要 Update 自动移动精灵,则 `fnCollision` 和 `fnFindPath` 应指向某个函数。如果无法知道给定位置是否有效,则移动精灵没有意义。 `Update` 应该在每个游戏循环中为所有精灵调用。这负责更新精灵的位置和动画。
通过调用 `SetState(ST_KILL)` 来杀死精灵,这会立即调用 `m_pfnKill` 指向的函数。此函数是可选的。原型是
bool fnKill(CSprite* pSprite);
如果 `fnKill` 返回 false,则状态不会设置为 KILL,并且 `SetState` 返回。在此游戏中,当玩家碰到门时,此函数用于进入下一关。
如果 Kill 继续,则它会显示死亡动画,一旦完成,它将调用 `m_pfnDead` 指向的函数,其原型是
void fnDead(CSprite* pSprite);
您可以使用此函数来更新分数、创建新敌人等。
最后
void CSprite::Draw(LPDIRECTDRAWSURFACE7 pdds)
将精灵绘制到给定的 Surface 上。
如果您通过重用此代码创建了一些很棒的游戏,请告诉我。
历史
2001 年 8 月 1 日
- “选择屏幕”显示游戏控件。
- 修复了 CSprite 中的内存泄漏问题。
- dsutil.cpp 中的内存泄漏已由微软修复。他们将在下一个 SDK 版本中推出此修复。