RPG游戏开发日志2:生命值与魔法值

本项目同步上传于github和coding上,国内读者可以通过在coding下载项目,注意本套开发日志同步的是Tutorial分支,其他分支内容可能与日志内容不符。请注意

github地址:https://github.com/Liweimin0512/uRPG

coding地址:https://git.dev.tencent.com/JeremyBrett/uRPG.git

今天我们来搞定角色的生命值和魔法值,在此之前我们要解释一个重要的概念——组件。

基于组件的游戏开发

也许你听过“组合大于继承”(没听过就先去听一下),简单来讲就是在游戏开发中描述一个游戏物体有什么比描述它是什么更合理。

那么这里我想把生命值和魔法值做成组件,因为游戏中除了玩家角色,游戏中的NPC、怪物甚至是一些“可交互物”都是有生命值的概念的。

起先,我想将生命值、魔法值作为两个组件。但更深入的分析,我将这两个数值抽象成一种叫做“状态”的组件,这个组件本身负责维护角色的各种状态数值,比如这里讲的生命值和魔法值。如果我们要开发一款类《饥荒》游戏,则这里的状态就可以是生命值、饥饿值和san值。

闲话少说,我们开始操作。

准备工作

首先我们先新建一个枚举蓝图,取名为E_Stats,有三个值,分别如下图所示:

E_Stats

然后我们创建一个结构体,保存最大、最小值、当前值和回复时间、恢复速度等,取名为s_StateData。如下图所示:

s_StateData

组件:BpC_StateManager

然后我们创建一个组件,也就是今天的主角:BpC_StateManager。这个组件负责储存、管理其所在Actor上的所有State,并在需要的时候通过事件调度器完成回调,这个我们会在之后讲到。

正如上文所说,我们需要储存状态,所以这里我们新建一个Map类型的变量,取名为StatDatas:

StatDatas

这个组件需要几个函数,我们一个一个新建

首先是GetStateData,很简单,获取状态数据:

GetStateData

其次就是设置状态数据,SetStateData:

SetStateData

这里调用了UpdateStat这个事件调度器,这个我们在之后讲。此外,为了方便设置当前值,这里还写了一个函数ModifyStat:

ModifyStat( 左)

这个函数需要传入状态类型、更改的值。先将这两个值作为局部变量存储起来(主要为了代码的整洁)。然后判断当前Animated?是否为真。为真则直接返回。否则:

ModifyStat( 左)

通过SetStatData设置状态数据,设置的方式就是先获取当前值,然后加上传入的值,并且保证在最大、最小值之间(Clamp)。

部分状态可能需要自动回复,这部分我的做法是创建一个自定义事件,Actor调用这个事件,就会通过SetTimerByFuncitonName节点来周期性调用状态恢复函数,具体代码如下图所示:

SetupStatRegenerations左

首先便利StatDatas,其中的项。先判断RateValue和RegenValue都不为零。然后:

SetupStatRegenerations右

RateValue就是SetTimerByFuncitonName调用的时间,具体的函数名依据StatType确认,然后调用上文中编写的SetStatData函数即可。

Actor

首先就是给Bp_CharacterBase这个Actor添加BpC_StateManager组件,并设置组件的值如下图所示:

BpC_StateManager数据

如果你跟着一步步操作到现在,应该已经意识到StatType中“/”的作用,这里就不再多说了。

还记得上文中所说的事件调度器么?这里我们要在Bp_CharacterBase中调用它。就在BeginPlay事件中,添加如下节点:

绑定事件到UpdateStat

上图代码的含义,就是其BpC_StateManager组件调用UpdateStat状态时候,也会调用下方的SetupStaBar函数,这里之所以如此实现,是因为不同的Actor对于UpdateState事件的处理方式是不同的,比如主角是要显示在主界面UI上,而怪物则是显示在头顶版血条上。

并且需要注意的就是,在最后调用BpC_StateManager的SetupStatRegeneration事件。

现在我们需要让状态变化的结果显示在UI上,创建一个Weiget,并取名W_Main。添加两个ProgressBar。就可以关掉了。

在Bp_CharacterBase中创建W_Main并添加到ViewPort上:

创建 W_Main

虽然UE4为我们提供了关于ProgessBar中很多参数很方便的绑定,但这并不是我们学习的重点。仔细思考发现,我们并不需要每帧检测State数值的变化,而只需要在UpdateState时候更改ProgessBar上的显示即可,所以函数SetupStatBar的实现如下图所示:

SetupStatBar

Debug

又到了愉快的Debug时间,这次的Debug方式依然简单,在Bp_CharacterBase的事件图表中添加如下事件:

debug

然后运行游戏,试着改变Mana,然后将StatType修改为Health试试。好的,搞定,完美!

下集预告

之后的几期,我们将陆续开发一个可扩展的技能系统。这个技能系统尽可能地由数据驱动,但我并不会直接创造一个这样的系统,而是由最“笨”的方法不断改进、重构,最终得到的,这个过程也将记录下来,可以更好地和同学们分享。那我们下期再见!

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

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,470评论 1 11
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,205评论 0 4
  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,419评论 1 33
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,096评论 0 21
  • 持久化 当我们在集群系统中,一台机器向另一台机器发送一段数据,负责接收的机器在接收数据前突然宕机,就会造成数据丢失...
    mango_knight阅读 4,497评论 0 4