十六、背包系统设计(尝试分析的一些思考)

尝试用面向数据的思维来分析,但本人对面向数据的理解还不够深刻,因此这里只是一些思考。

功能描述:

  1. 有不同类型(法术、武器、药水)和数量的道具槽,道具需装备到槽内才能使用。
  2. 支持同种道具的堆叠 ,如在一个药水道具槽内装备100瓶生命回复药。
  3. 在背包中保存获取的道具,容量无限,可随时从背包中装备到道具槽内,或从道具槽中卸下

其实,严格来讲,道具槽感觉不应该划分在背包系统中,而是自己的一套。这里就先这样吧。

定义数据


背包

“我”现在是背包,不管其他所有的系统,为了完成职能,“我”需要知道哪些信息?

  • 我要把什么道具放进背包? -------> item type( item name)
  • 背包里同种道具的数量是多少? ----------> int
  • 一种道具最大堆叠多少? --------------> int
  • 道具是否在背包内/怎么将道具放进、取出背包?------------> bool / ......

数据用来记录游戏任一时刻的状态。考虑某一时刻背包的状态:

  • 有哪些道具?-----------------> array/list/......
  • 每个道具的数量是多少?---------------->int

考虑数据之间的关联性,我们可以得到一张表:

道具类型 背包中当前拥有的数量 背包中可容纳的最大数量
生命回复药 1 10
战斧 1 1
火球术 1 1

为了区分每一条记录,我们要选取主键(必须唯一)。

方案一、

struct ItemData
{
    ItemType type;
    int itemCount;
    int itemMaxCount;
}
Array<ItemData> or List<ItemData> inventory; 

以前的我大概很快就会想到并决定这样的数据布局,当与外部系统交互时,就是struct ItemData的引用满天飞了。
此时的主键是:道具类型 + 背包中当前拥有的数量 + 背包中可容纳的最大数量

方案二、

struct ItemData
{
    int itemCount;
    int itemMaxCount;
}
Map<ItemType, ItemData> inventory;

此时的主键是:道具类型


道具槽

按照上面的思路,“我”现在变成道具槽了,要知道的信息:

  • 道具槽的类型? -----> slot type
  • 道具槽是否被装备? -----> bool
  • 装备了什么道具? -----> item Type

那如果要有一堆道具槽要管理,那么我们就要为槽添加主key。

道具槽类型 是否被装备 装备的道具类型
药水 生命回复药
武器 战斧
法术 火球术
药水
法术

仔细看一上表,你会发现是否被装备这一列是冗余的,于是:

道具槽类型 装备的道具
药水 生命回复药
武器 战斧
法术 火球术
药水
法术

从上表中可以发现,主键只能是:道具槽类型 + 装备的道具

方案一:

struct ItemSlot
{
    SlotType slotType;
    ItemType itemType;
}
TArray<ItemSlot> slots;

当我们要确定slot的唯一性时,是以struct ItemSlot为单元比较了。

方案二:
甲:我不想用Array,我想用Map!!!
乙:OK。不过要加一个表项。

道具槽类型 索引 装备的道具
药水 0 生命回复药
药水 1
法术 0 火球术
法术 1
武器 0 战斧

主键为:道具槽类型 + 索引

struct ItemSlot
{
  SlotType slotType;
  int slotNumber;
}

Map<ItemSlot,ItemType> slots;

背包 + 道具槽 + ......

这里我们很容易发现ItemType是两个系统都有的数据,因此可以借此将两个系统的数据关联起来。

如果要UI显示背包中的道具,很明显我们缺少图标资源。所以ItemType还要和图标资源建立联系。但要注意的是背包的运作并不要关心图标资源。

对于不同数据的关联:在ECS中,可利用entity来为不同的Component Data建立起逻辑关联;在面向对象编程中,我们通常定义一个大的Item类(确立了data的关联性:同属于一个类实例),然后将其传入不同系统,尽管系统只关注其中的一部分数据。

ActionRPG的背包系统


看过之前code部分的同学,应该很容易就能理解。ActionRPG的背包系统是一个很典型的面向对象设计。

  • 有一个较大的ItemType类(会用这个类中数据的系统有:UI、资源管理、GAS、背包等等)
  • 背包的数据容器放在PlayerController的子类中,交互方法一部分放在接口Interface中,由PlayerController的子类实现,另一部直接声明为public方法。.
  • 其他系统(比如UI)与背包系统的交互的方法为绑定delegate,也就是消息传递。(因为PlayerController的实例是可以从全局访问到的,因此获取delegate的方法放在接口中)
/** Gets the delegate for inventory item changes */
    virtual FOnInventoryItemChangedNative& GetInventoryItemChangedDelegate() = 0;

    /** Gets the delegate for inventory slot changes */
    virtual FOnSlottedItemChangedNative& GetSlottedItemChangedDelegate() = 0;

    /** Gets the delegate for when the inventory loads */
    virtual FOnInventoryLoadedNative& GetInventoryLoadedDelegate() = 0;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351