有关服务器属性系统的思考

脑袋有点凌乱,需要整理


有关游戏属性与存储方式



游戏属性可以分成2类:静态属性、动态属性
1.静态属性:该属性对于属性所属的对象是不会随着游戏进行而变化的
2.动态属性:该属性在游戏的进行过程中会进行变化。动态属性又可以分成2个子属性。基础属性、衍生属性
a.基础属性:就是该属性的具体数值不能通过其他属性计算而得
b.衍生属性:该属性的具体数值通过其他属性就可以计算而得

举例说明:
客户端可以看到的力量随着等级变化而不同,同时可以通过分配额外的点数对于当前的力量进行加成。这里的力量就有着3个属性。
不同等级的力量值:静态属性
当前力量:基础属性
力量和其他属性计算出来的攻击力:衍生属性


属性的存储:
静态属性:配置文件
基础属性:数据库
衍生属性:初始化通过静态数据和基础数据计算而得。内存中存在

1.属性中存在各种不同状态下使用不同属性作为实际有效属性的情况。导致客户端和服务器写相同的逻辑代码去使得逻辑生效。
服务器可以在属性下发前进行逻辑判定。映射实际有效的属性。
通过属性进行是否可见的默认设定,决定实际需要下发的属性。则实际仅仅下发客户端有效属性。

2.其实属性在实际存储过程中不需要区分基础属性和衍生属性。因为处理流程上是完全一样的。都是仅仅需要Get、Modify、Set、OnPropertyChange 3.个操作
但是需要特别独立出来静态属性。因为静态属性是不会变化的。不需要同步。

4.不同类型属性之间的区别在于承载属性的内容不同以及OnPropertyChange的后续处理不同。Get、Modify、Set的逻辑应该是完全相同的。所以应该是这么一个关系。
class PropertyControllerInterface
{
public:
virtual void OnPropertyChange(_U16 iPropId, _S32 iOld, _S32 iNew) = 0;
virtual _S32 GetProperty(_U16 iPropId) = 0;
virtual bool ModifyProperty(_U16 iPropId, ModifyData modifyData) = 0;
virtual bool SetBaseProperty(_U16 iPropId, _S32 iBase) = 0;
}

class PropertyBase
{
public:
_S32 GetPropertyInternal(_U16 iPropId);
bool ModifyPropertyInternal(_U16 iPropId, ModifyData modifyData);
bool SetBasePropertyInternal(_U16 iPropId, _S32 iBase);


protected:
_U16 m_iPropIdBegin;
_U16 m_iPropIdEnd;
_S32* m_pProperty;
PropertyControllerInterface* m_pController;
}

class PropertyWarshipBase : class PropertyBase
{
public:
PropertyWarship()
{
m_pProperty = m_arPropertyData;
m_iPropIdBegin = XXBegin;
m_iPropIdEnd = XXEnd;
}

private:
_S32 m_arPropertyData[XX];
}


class PropertySubmarineExt : class PropertyBase
{
public:
PropertyWarship()
{
m_pProperty = m_arPropertyData;
m_iPropIdBegin = XXBegin;
m_iPropIdEnd = XXEnd;
}

private:
_S32 m_arPropertyData[XX];
}

class SRoomWarship : public PropertyControllerInterface
{
public:
PropertyWarship();
virtual ~PropertyWarship();


public:
virtual void OnPropertyChange(_U16 iPropId, _S32 iOld, _S32 iNew) = 0;
virtual _S32 GetProperty(_U16 iPropId) = 0;
virtual bool ModifyProperty(_U16 iPropId, ModifyData modifyData) = 0;
virtual bool SetBaseProperty(_U16 iPropId, _S32 iBase) = 0;

public:
_S32 m_arProperty;
}

4. 属性系统设计方案比较
属性系统功能比较简单,涉及存储、修改、同步三个方面。
存储是基础,方案也比较多。主要从扩展性、稳定性、性能(空间、时间)及方面考虑
a. 扩展性最好的,完全配置可驱动,性能最差。所有属性都是一个存储对象,所有个体都可以由任意可配置个属性组合。
class PropNode
{
public:
_U16 iPropid;
_S32 iPropVal;
ModifyProperty modifyData;
}

class PropBase
{
public:
_S32 GetPropertyInternal(_U16 iPropId);
bool ModifyPropertyInternal(_U16 iPropId, ModifyData modifyData);
bool SetBasePropertyInternal(_U16 iPropId, _S32 iBase);


protected:
Map<_U16, PropNode*> m_mapProp;
PropertyControllerInterface* m_pController;
}

class PropWarship : public PropBase
{
public:
PropWarship()
{
m_mapProp.insert(pair(XXid, pNode*)); 
}
}

class PropSubmarine : public PropWarship
{
}

b. 扩展性需要代码配合的。属性组合已经优化。根据不同对象属性分段、组合。
每个对象需要特殊代码进行实际修改接口的书写。
class PropertyBase
{
public:
_S32 GetPropertyInternal(_U16 iPropId);
bool ModifyPropertyInternal(_U16 iPropId, ModifyData modifyData);
bool SetBasePropertyInternal(_U16 iPropId, _S32 iBase);


protected:
_U16 m_iPropIdBegin;
_U16 m_iPropIdEnd;
_S32* m_pProperty;
PropertyControllerInterface* m_pController;
}

class PropertyWarshipBase : class PropertyBase
{
public:
PropertyWarship()
{
m_pProperty = m_arPropertyData;
m_iPropIdBegin = XXBegin;
m_iPropIdEnd = XXEnd;
}

private:
_S32 m_arPropertyData[XX];
}


class PropertySubmarineExt : class PropertyBase
{
public:
PropertyWarship()
{
m_pProperty = m_arPropertyData;
m_iPropIdBegin = XXBegin;
m_iPropIdEnd = XXEnd;
}

private:
_S32 m_arPropertyData[XX];
}

class SRoomWarship : public PropertyControllerInterface
{
public:
PropertyWarship();
virtual ~PropertyWarship();


public:
virtual void OnPropertyChange(_U16 iPropId, _S32 iOld, _S32 iNew) = 0;
virtual _S32 GetProperty(_U16 iPropId) =
virtual bool ModifyProperty(_U16 iPropId, ModifyData modifyData) = 0;
virtual bool SetBaseProperty(_U16 iPropId, _S32 iBase) = 0;

public:
_S32 m_arProperty;
}

c.合并子类属性。父类具有所有属性,只是没有效果。
对象最少,性能最好,但是空间使用最浪费。

class PropertyBase
{
public:
_S32 GetPropertyInternal(_U16 iPropId);
bool ModifyPropertyInternal(_U16 iPropId, ModifyData modifyData);
bool SetBasePropertyInternal(_U16 iPropId, _S32 iBase);


protected:
_U16 m_iPropIdBegin;
_U16 m_iPropIdEnd;
_S32* m_pProperty;
PropertyControllerInterface* m_pController;
}

class PropertyWarshipBase : class PropertyBase
{
public:
PropertyWarship()
{
m_pProperty = m_arPropertyData;
m_iPropIdBegin = XXBegin;
m_iPropIdEnd = XXEnd;
}

private:
_S32 m_arPropertyData[XX]; // 包括Warship,Submarine, CA
}


Modify这里基本上都是Interface接口实现。改变自身属性就可以了。但是舰船上需要增加一个额外的接口,以通过该接口实现修改说有部位的属性。
virtual void OnPropertyChange(_U16 iPropId, _S32 iOld, _S32 iNew) = 0;
virtual _S32 GetProperty(_U16 iPropId) = 0;
virtual bool ModifyProperty(_U16 iPropId, ModifyData modifyData) = 0;
virtual bool SetBaseProperty(_U16 iPropId, _S32 iBase) = 0;
virtual bool ModifyProperty(EffectType, PartType, _U16 iPropId, ModifyData modifyData) = 0;

对于修改处理则主要是两方面问题:
a. 进行属性修改后的逻辑处理: 比如物理库的的参数设定,属性映射处理
需要考虑属性逻辑关系,比如潜水艇的水面最大速度、水下一层最大速度和水下二层速度与当前最大速度
b. 进行与客户端同步
进行属性同步过滤

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值