您的位置:首页 > 理论基础 > 数据结构算法

游戏程序设计--真实案例分析(一)

2008-10-23 14:45 375 查看
案例:

战斗模式类似 国王的恩赐 , 有 世界场景 和战斗场景。 当碰到世界场景的 怪物之后 , 切换到战斗场景进行战斗。如何处理2个场景的怪物的属性,使它们能够正确的显示。

 

问题存在的理由:

1、世界场景 和 战斗场景 的怪物 在表现层上是一致的, 但是在数据层上是不一致的。 战斗场景的 怪物在属性数据上将更加详细和特殊, 而世界场景上的怪物也不能只是具有表现层ID,需要一部分 属性数据用来显示信息(UI)。

2、由于 我们 给策划提供的 Execl 导出工具 不提供 导出子表的功能, 而且 世界场景怪物 和 战斗场景怪物 的属性 是相交 而不是 子集的关系(具体属性实例大家参考第1条自行想象..想象)。

3、显示 生物模型 是一个相对独立的模块,它需要传递3D表现参数,而不关系 这些参数是 来自世界场景对象 或者 战斗场景对象, 或者火星对象。

 

问题核心分析:

无疑 两种属性数据结构都包含了 3D表现  相关的 数据信息。

而且在这里我们只是希望从这些重叠部分中提取 3D表现 相关的数据信息。

所以我们需要解决的问题是 如何从 2个相似 的怪物属性数据中 提取重叠的 3D表现部分。

推广后可以得到问题的本质: 如何从 相交的 数据对象中 提取重叠的数据。

 

解决方案分析:

在看到 问题存在理由1 的时候,基本上就可以确定“将公共属性提出来,作为基类 怪物属性,然后派生 世界场景怪物属性, 和 战斗场景怪物属性” 的解决方案。

再考虑 第2条理由之后, 为了配合上述方案,需要更改导出表。但再仔细考虑,其实我们只需要一个能够作为公共属性的子表,而不在意其来源。 (子任务一)

再将 子任务一 的因素加进来考虑 , 进行分析,有2个解决方案

方案一 : 基于 扩展 Execl 导出工具

1、扩展 Execl 导出工具 , 使之支持 属性项的自由组合导出(最高级别) 或者 导出子表(最低级别)。

2、修改怪物属性类 的结构, 使之 满足需求。

 

方案二: 不修改Execl ,完全由程序解决。
该方案本质上来说就是 由程序这头从 代码上解决问题。

 

比较两者的花费:

方案一 影响到了 2个部门, 对策划来说,工作流程受到了影响, 最显著的特征就是 增加了策划  在产出数据时的 工作量(选择哪些是公共的)。对程序来说,需要扩展导出工具(这个工作量还是有一些的)。

方案二 影响一个部门(其实就是偶 囧),时间2小时-1天(视该属性涉及到的接口 ,包括 Server 和 Client 之间的通信)。

 

比较两者的优势:

方案一 完善了导出工具
方案二 时间成本小, 出效果快

 

在这里 我倾向于第2种方案, 因为有个前提:进度进度进度 囧囧。

 

OK。关于第2个方案,我的实现是:
struct 3D表现数据 // 表现层关心的数据
{
        A;
        B;
};

class IMonsterAttribute // 搜集数据的接口层
{
public:
        virtual 3D表现数据 getData() const = 0;
        virtual void                setData( const 3D表现数据& ) = 0;
};

// 数据来源一: 世界场景怪物属性, 给它套个接口,并实现。
class WorldMonsterAttribute : public IMonsterAttribute
{
public:
        各种数据;
        A;
        B;
        C;
        E;
public:
        3D表现数据 getData() const
        {
                3D表现数据 data;
                data.A = A;
                data.B = B;
                return data;
        }
        void setData( const 3D表现数据&  data) 
        {
                A = data.A;
                B = data.B;
        }
};

// 数据来源二: 战斗场景怪物属性, 给它套个接口,并实现。
class BattleMonsterAttribute : public IMonsterAttribute
{
public:
        各种数据;
        A;
        B;
        F;
        G;
public: // 接口实现(略)
};

class Monster
{
public:
        void load( const IMonsterAttribute* pData)
       {
                if( pData == NULL)
                        return;
                3D表现数据 data;
                pData->getData(data);
                // OK, 在这里我们得到了关心的数据,可以做任何事了:
                ShowBody( data.A);
                ShowWeapon( data.B);
                ShowAss( data.Ass);
                PlayAction( data.KickAss);
       }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息