RPG游戏开发日志7:道具拾取与存放

本项目同步上传于github和coding上,国内读者可以通过在coding下载项目。
也欢迎你加入我的UE4学习交流QQ群:872537977。如果你喜欢我写的文章,也希望你点赞、收藏、转发。谢谢!
如果你喜欢我写的文章,也希望你点赞、收藏、转发。谢谢!
如果你想参与到这个项目的开发中来,唯一的要求是像我一样编写开发日志让更多的人看到并学习。
github地址:https://github.com/Liweimin0512/uRPG
coding地址:https://git.dev.tencent.com/JeremyBrett/uRPG.git
这一期我们实现道具的拾取和存放

需求分析

上一期中我们设计了一个掉落物的列表。这一期我们继续处理当列表中的道具被点击后,将道具保存到玩家的背包中的操作。
我们首先制作一个极简的背包,它不需要通过主界面的图标跳转到专属的界面。而只是在主界面下方的一排“快捷栏”。因为其实现的原理是一致的。希望小伙伴们能举一反三吧。
首先,我们依然要客串策划的工作。策划同学突然灵光一闪,觉得道具和掉落物应该是一一对应的,而掉落物的参数是可配置的。

DropData与Item的对应关系

通过思考,我们对这部分代码进行了重构。首先是我们创建了一个DropData的结构体如下图所示,默认值就设置成之间的掉落物本来该有的值:
iDropData

这里设置比较简单,掉落物的模型、特效及拾取半径都是可以配置的。

然后我们在原有的ItemData中引用这个结构体,如下图所示:
ItemData中引用

构建Bp_master_DropBase

我们在Bp_master_DropBase中,首先将相关变量都勾选成“可编辑实例”和“在生成时显示”。并且编写蓝图的构建脚本如下图所示:
Bp_master_DropBase的构建脚本

构建脚本,顾名思义就是在蓝图构建时调用的(大概),总之是比BeginPlay事件要早。

当玩家进出凋落物的拾取范围呢?依然是调用玩家角色身上的UpdateDropItemList方法。
调用UpdateDropItemList
这个方法的实现目前看依然很尴尬,只是做了一个传话筒,但是我们这么写的目的是为了搭出架子来,在之后的修改中会更方便。
UpdateDropItemList的实现

Drop函数的重构

再次改写Drop函数,其实是因为Bp_master_DropBase这个蓝图本身做了调整,它除开存放本身外显的一些参数外,还存放了一个s_ItemState的结构体变量:
s_ItemState

这个结构体很常用,是保存玩家所拥有的道具及道具数量的简单结构体。
Drop函数的改变
可以看出Drop函数的改变主要来自于ItemState简单了许多,只需要传入道具Id和数量即可。而Drop相关的参数,也是通过查询ItemList表格获取到的。

UMG_PickupList的处理

UMG_PickupList主要是UpdateListView这个函数的实现,这也是目前比较关键的一步。首先,我们根据Add?判断是添加还是移除元素从ItemStatList这个集合中,同时对PickupListView进行一次清理操作
ItemStatList操作

然后我们遍历ItemStatList中的元素,逐个添加到PickupListView中
添加操作
由于这部分都是对上一期中代码的重构,因此不详细介绍思路了就。

UMG_ItemInventory

上文的内容,都是对过往代码的重构,从这里开始,才进入本篇文章的主题。首先,我们创建一个主界面控件——快捷栏控件。它长这样:
UMG_ItemInventory的设计

如果你细心观察,会发现其实这个Weiget只使用了一个HorizontalBox组件,如何实现?这就要引出PreConstruct这个事件了,他有点类似于蓝图的构造脚本。在编辑器中就可以展现事件中所进行的修改。我这里进行的修改很简单
PreConstruct
创建了10个UMG_Item并将其添加到HorizontalBox组件上,同时,为了进行逻辑上的记录,还将其保存在一个名为ItemIndex的map中
ItemIndex
至于UMG_Item这个Weiget呢,相信你已经猜出来了。
UMG_Item

它由背景图片,道具图片和道具数量三部分组成,并且默认情况下(没有道具时)道具图标、道具数量都是隐藏的,只显示背景图片。(ps:写到这里突然感觉实现方式有问题,懒得改了,下期再说)

OnItemClicked事件

ListView很重要的一个事件,就是当列表中的某一项被点击时候调用的OnItemClicked事件。我们这里要用这个事件,当点击时,将掉落物添加到背包中并从拾取物列表中移除。
OnItemClicked

这里我们并没有直接处理,而是将操作权交给了Controller。不过,还是将干掉掉落物的操作直接在这里实现了。(似乎也是不合理的部分,之后优化吧。)

那么Controller怎么操作的呢?他首先通知Character做相应的操作(SetItemValue),然后通知主界面做相应操作(UpdateItemInventory)
F_Pickup

而UpdateItemInventory顾名思义,就是更新一下背包。这个函数可以再每次打开背包的时候调用,这里因为是直接显示在快捷栏中,因此当捡起道具时候就应该直接显式调用一次。
UpdateItemInventory
首先就是遍历ItemMap,然后根据其中存储的ItemID通过查表将道具图标和数量显示出来,需要注意的是,图标和数量的控件默认都是隐藏的,这里需要将其设置为显示的。

至此,将道具存放到背包中的功能就算是完成了。

下期预告

在之后的一段时间,我想研究一下任务系统的实现。至于道具系统更深入的开发,就留给任务系统之后来做。
或者说是制作一个简易的任务系统,然后补充这些基础系统的文档后。再重构更为精巧的技能、任务和道具系统。

你可能感兴趣的:(RPG游戏开发日志7:道具拾取与存放)