Donuts4 学习笔记(1)

为了更好的了解DX和游戏的架构,同时也为了练习Code Reading的能力(好官僚的口气),我打算把DX SDK中的Demo——donuts4(面包圈大战)仔细的读一遍。以前也没读过什么长的东西,还一直以为写东西才是根本。现在看来,读东西同样的重要。


文件构成

除了resource.h外,donuts4共有18个cpp/h文件。根据头文件里面的注释,首先对这些文件有一个大概的了解:

donuts.cpp/.h 是donuts4的主文件了。里面说,该游戏使用了Direct3D,DirectMusic,DirectSound和DirectInput。

StdAfx.cpp/.h 预编译头文件。

GameMenu.cpp/.h 用于显示游戏的菜单。(我怎么没看见游戏里面有菜单?!)

Profile.cpp/.h 用于读写INI文件。

FileWatch.cpp/.h 用于查看一些文件是否被修改了。(无法理解这个的作用……)

NotifyTool.cpp/.h 似乎是一个IDirectMusicTool的扩展。

3DModel.cpp/.h 一个类C3DModel的实现。应该是对3D模型的抽象吧。

DisplayObject.cpp/.h 类CDisplayObject的实现。

3DDisplayObject.cpp/.h 一个继承于CDisplayObject的类。不知道和C3DModel有什么联系。

3DDrawManager.cpp/.h 这个应该是用来画东东的Manager了。

InputManager.cpp/.h 管理Input的类。

HeightMap.cpp/.h 类CHeightMap的实现,应该是和Terrain相关的。

TerrainMesh.cpp/.h 似乎是Terrain里面的Mesh的抽象。

TerrainEngine.cpp/.h 地形引擎。

ParticleSystem.cpp/.h 粒子系统(也没看见哪用了……)。

Bullet.cpp/.h 子弹嘛,就是面包圈了……

EnemyShip.cpp/.h 敌人,就是那个紫色的东西。

PlayerShip.cpp/.h 自己的船,不过似乎不可见的样子(因为是第一视角)。


donuts.h中的类

donuts.h中只声明了两个类。一个是非常短小的C3DAudioPath类,一个是非常巨大的CMyApplication类。CMyApplication类光声明就用了160行……

我本以为donuts使用的应该是DX的Common Framework呢,但是似乎不是。CMyApplication并不是继承于CApplication的。但是类里面的结构和CApplication差不多,应该Common Framework的一个简化版或者是改进版。

donuts只使用了Common中的D3DFile,D3DFont以及一些Util。

另外,donuts.h还对一些Custom Vertex和相应的FVF做了声明。


程序的入口

donuts.cpp有96K这么大,2000多行,看着就头痛。

先找程序的入口WinMain吧。WinMain写在了很显眼的前面。除了设定随机种子以外,就是实例化CMyApplication了。可以看出app的使用分两步,第一步是Create(),第二步是Run()。这和D3DApp似乎也差不多,其实这种方法挺好的。

CMyApplication的构造函数就是对其所有需要init的内部成员都init一下。满眼的匈牙利阿……

Create()和Run()都不长,可以仔细看看。

Create()照例是声明一个窗口,然后把相应的属性存了下来。值得注意的是,在Create()中调用了OneTimeSceneInit(),就是说,游戏对象的初始化也是在Create()中完成的。

Run()中也是在意料之中的封装了一个Message Pump。有个有趣的地方,在取消息的时候,donuts采用的方法是:

if(active)
    msg = PeekMessage();
else
    msg = GetMessage();

旁边还写上了简单的说明:如果程序是active的话,就用Peek,这样可以用idle的时间来做render。如果不是的话,就用Get,这样可是避免eat掉CPU的时间。又学了一招。

如果没有msg在wait的话,就可以render了。render的代码很怪异:

if( m_bDisplayReady )
{
    if( m_pFileWatch->HaveFilesChanged( TRUE ) )
    {
        g_Profile.GetProfile( m_strProfilePath );
    }
    else
    {
        UpdateScene();
        RenderScene();
    }
}

也就是说,如果文件发生改变了的话,就要重新更新文件。它这里所说的文件应该就是ini文件了。不过…… 谁在玩游戏的时候会切出去更改配置文件?又或者游戏本身更改了配置文件(没见到Option阿)?迷惑ing……

不过可以看出,渲染分为两步UpdateScene()和RenderScene()。

另外,Create()中声明Window的时候,给定的MsgProc是StaticMsgProc()这个函数。而这个函数也仅仅是起到了一个转向的作用,把消息交给了app.MsgProc()来处理了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值