登录
<
>

今日新帖:1 | 帖子数:2004 | 会员数:1.1万

欢迎新会员:
  • 3165419
  • user2VPGpA
  • 情若能自控 、
  • userWoqP25
  • 小城一家
搜索

【从零开始的角色扮演】中级教程

楼主
  • 主题

    70

  • 帖子

    151

  • 精华

    7

+加好友 查看TA的游戏
  • L0
  • 2

发表于:2020-4-20 16:18:07 楼主

大人,来艾兰岛论坛喝口茶聊聊天吧,可直接WeGame登录哦~

您需要登录才可以下载或查看。 登录

x
本帖最后由 芝士冕 于 2020-4-20 16:25 编辑

角色扮演中级第一期:怪物刷新系统和随机掉落
        艾兰岛的岛民们大家好,欢迎来到从零开始系统。在初级视频中,我们已经制作了一个简单的剧情游戏,,那么从本期开始,我们的角色扮演中级视频将会在初级的内容上,对游戏内容继续拓展,实现更多的游戏功能。中级视频共分为四期。
其中第一期实现的功能为:怪物的随机掉落,怪物在随机位置刷新。在第一期中大家可以学习到本地变量、随机数、事件侦听器、实体标签、时间触发器、数组的用法。
                        
        第二期实现的功能为:玩家的经验值、玩家等级以及其对应的UI。在第二期中可以学习到实体储存、HUD、数组、数据库等用法。
                        
第三期实现的功能为:游戏中的任务系统,对话任务、打怪任务、收集物品任务。并且我们能学习到自定义窗口、对背包物品的操作、堆叠设置、数组操作等用法。
                        
而在中级的最后一期中实现的功能为:玩家的技能系统以及对应的法力值、冷却时间。在这一期中,我们能学习到实体存储、粒子特效、向量计算、动画指令、时间戳的使用。
                        
        那么接下来,我们就来看一下中级的第一期内容吧
1、 视频展示
接着我们先来看一下我们中级第一期的内容吧。和初级一样,我们依旧面对着这些山贼,接着我们上去攻击他们。
                        
        击杀了第一个山贼,掉落出了一双皮甲鞋。
                        
我们拾取好,并且装备起来,接着去打山贼。这回掉落了一条皮皮甲裤。居然和之前不一样?
                        
        我们打着打着,这边怎么又刷新出了这么多山贼,这可怎么打呀。
                        
        不过以我们的武力,依旧还是击杀了山贼首领,并且回来交接了任务。现在我们来学习一下怎么制作出视频中的游戏吧。
                        
2、 怪物随机掉落
首先,我们先来制作怪物的随机掉落。我们依据什么时候做什么事情的原则,先来分析一下这个事件的整个过程。当我们击败怪物时,需要判断是否有掉落物,以及掉落物的类型。如果没有则事件结束,而如果有掉落物,则根据判断掉落对应的掉落物。
                        
2.1随机数        
接着,我们建立一张表。通过我们可以设立一个随机数,而随机数的取值范围为0~1,当随机数处于下列区间的时候,则掉落对应的物品,而当随机数≥0.8且小于等于1时,则没有物品掉落。
                        
        接着,我们打开在初级中编程的NPC,在被击败时,在NPC的位置生成了一把铁剑。
                        
        所以击败时的事件已经有了,生成的逻辑也有了,我们只需要修改一下条件即可按照上边的表格,我们需要有四种情况,分别生成皮甲、皮裤、皮靴、军刀。所以我们需要有更多的条件,我们拖出如果语句,点击该语句,并且点击加号。这样就能添加新的条件语句。
                        
        我们需要皮甲、皮裤、皮靴、军刀以及无掉落五种情况,但是无掉落的情况不需要执行任何语句,所以我们只需要四个就够了。
                        
接着我们需要一个取值在0-1中间的随机数,打开数字,找到random指令,该指令可以在0-1之前取到一个随机值,当随机值小于0.2时,则生成皮甲。接着要如何制作随机数≥0.2小于0.4呢?
                        
2.2随机数
我们点击逻辑,将或语句拖出放入第二个否则如果中,不过该语句默认的是或,意思是左右两边的空格中只需要满足一个条件就可以执行下边的条件。我们点击下拉按键,修改为与。这样需要满足左右两边两个条件,这才能执行下边的逻辑。
                        
        我们将皮甲裤的条件填入其中。
                        
        但是这里似乎好像有什么问题,在执行的过程中,先执行第一个随机数,次数会随机一个数字,而执行到第二条随机数时,又会随机出另一个数字。当到第三条随机数时,出现的数字又不一样了。那么我们要如何解决这个问题呢?
                        
2.3本地变量
其实,我们只需要调用随机数一次,并将其用变量保存起来。然后每次将这个变量放入条件中,就可以解决这个问题了。不过这里的随机数不需要再其他地方使用,所以我们只需要用本地变量即可。
本地变量有固定的使用范围。比如在同一个脚本中,有两个事件。那么第一个事件中本地变量,就不能在第二个事件中使用。
                        
而同一个事件中,本地变量的使用也有限制。假如本地变量放在带有结尾的指令中,就像如果这样的指令。
                        
那么本地变量会这种指令执行结束时删除掉。这就使得,指令中的本地变量无法在外面使用。
                        
        我们点击变量,修改变量名为随机数,并且将随机数填入下边的条件中,替换随机数指令。
                        
接着再将下边的两个条件也补上。
                        
这样就制作好了随机掉落,不过这里还有这么多NPC,难道要每个NPC都编程过去吗?那样可太麻烦了。
                        
2.***侦听器
        在游戏中,有一个游戏逻辑对象,可以侦听游戏中的所有事件发生,这就是事件侦听器。首先我们将其名字修改为[事件侦听器]击败怪物。
                        
接着我们继续看事件侦听器的选项。第一个侦听的选项,这边选择的是事件的大类型,比如实体受伤、击败事件,都在两个实体间的交互。玩家攻击、闪避、跳跃这些的事件都在玩家动作中。我们要选择的是击败时,所以选择第一个就可以了。
                        
        接着我们看触发对象,触发对象就是事件中的主动方,比如我们这里的击败时,那触发对象就是击杀怪物的人。而在这里,当击败事件发生时,满足了我们选择的触发对象要求时,对应事件侦听器中的击败时才能触发,而我们只需要怪物死亡时就掉落物品,不需要触发对象满足什么条件,所以我们使用任何事物。
                        
        然后是目标对象,这个就是事件中被击败的一方需要满足这里选择的条件时,该事件才会触发。而我们这边能触发的是这边所有的山贼,那么我们要如何只监听这些山贼呢?我们看到下拉行中各条都比较好理解。而我们呢,则使用第七条,有标签的实体。
                        
那么问题又来了,标签是什么?我们继续打开游戏逻辑菜单,找到实体标签放入地图中。实体标签,如名字所说,这就是给实体打上一个标签,用来区分实体。比如我们这里需要区分山贼,所以,我们就先把标签名字修改为[实体标签]山贼。
                        
接着,我们按住ctrl键一个个选中山贼,并使用左侧的吸管选中刚刚放置的标签。
                        
我们再打开标签看一下,发现实体栏中多了很多NPC,这就是成功将这些NPC打上标签了。
                        
接着,在事件侦听器中,使用吸管选中这个标签,这样就能侦听所有有标签的实体,被击败的事件了。最后,我们还要再事件栏中,找到击败时指令。
                        
        现在我们需要把刚刚在NPC中写入的逻辑,复制到事件侦听器中,我们打开NPC的脚本编辑页面。先使用一个自定义指令,将所有的指令放入其中,并且选中函数,按下ctrl+C。
                        
        打开事件侦听器,按下ctrl+V,即可将函数复制到事件侦听器中。
                        
        然后将指令接入击败时下边,并且将原有的此对象修改为目标实体。
                        
        这样就完成随机掉落的系统啦。
3、 怪物随机刷新
在刚刚的游戏演示中,我们杀死怪物后,怪物会不断的刷新出来,我们完全打不完。这其中的原理,其实就是每隔五秒时间,在随机位置生成一个山贼。所以我们首先需要一个能每隔5秒时间执行一次的触发器,正好,编辑器中的时间触发器就是这个作用。
                        
3.1时间触发器
        我们打开游戏逻辑菜单,并且将一个时间触发器放入地图中,并且将名字修改为[时间触发器]刷新山贼。接着来看一下时间触发器可以修改的属性。
                        
        首先是开启,当勾选时,进入游戏该触发器就是执行状态,而关闭后,触发器就暂时不会起作用。接着是时间,代表的时候是每次执行指令想隔的时间。
                        
接下来是类型,默认选择的是持续的真实时间秒数,而其他的持续的游戏时间,则是代表已游戏中的时间为准,每经过上述游戏时间才会执行一次。
                        
最后一栏的为额外执行次数,就是如名字所说,该触发器额外能执行的次数,当填入1时,能多执行一次,填入为-1时,执行次数为无限次。
3.2实体模板
        接着我们打开时间触发器的脚本编辑界面。我们需要在这里生成一个山贼实体,同时还要贴上一个刚刚随机掉落系统中的实体标签。首先我们先将时间触发器中的执行事件,触发时拖入脚本页面。
                        
        接着我们先搜索标签指令并且将其放置在触发时下边,第一个空实体需要放入对应的山贼,第二个标签只需要选择好随机掉落系统中的标签。但是在这里的山贼是刚刚生成出来的,我们没法通过吸管进行选择。那要如何放入刚刚生成的山贼呢?
                        
我们先搜索生成指令,而搜索结果中,有许多条生成指令。
                        
        我们注意指令头部的形状,其中方形的,都能获取到使用该指令生成出的实体。而其中需要选择容器的指令是在一些容器和玩家背包内生成指令,所以我们也不选择这些。
                        
        通过筛选我们就剩下两条指令,其中实体类型用于生成默认实体库中的实体,这样生成出的NPC没有装备,也无法攻击玩家。所以我们只能使用生成实体模板。
                        
        同时使用该指令时,我们需要使用实体模板这个游戏逻辑,这个逻辑可以将我们的修改过的实体存入模板中,然后通过生成实体模板的逻辑生成出对应的实体。我们打开游戏逻辑菜单,并将其放入地图中。我们先修改名字为[实体模板]山贼。
                        
        接着是实体栏,这里可以使用吸管选择我们想要存入的实体。我们先放置一个新的NPC,并且添加装备,并给NPC添加上初级中的AI行为。
                        
        回到时间触发器的编辑界面,使用生成实体模板中的吸管选择刚刚设置好的实体模板。并且将该指令接入添加标签指令中,接着我们要选择生成的位置。
                        
        我们再次打开游戏逻辑菜单,在地图中需要的位置放入一个参照点,这个逻辑就如命名所说,只是一个参照作用。
                        
        我们在掉落系统中使用了获取实**置指令获取到死亡NPC的位置,而这里,我们需要使用获取逻辑位置的指令,获取到参照点的位置。我们指令放入刚刚的指令块中,并且使用吸管选择刚刚放入的参照点。
                        
        现在,我们可以开启游戏测试一下。我们发现有两个问题。首先是所有NPC刷新在一个位置。并且全挤在一起。第二个问题是这样的NPC刷新没有数量上限,会一直刷新着。
                        
3.3限制刷新数量
        首先我们来解决第二个问题,限制NPC的刷新数量。我们打开时间触发器的脚本编辑界面,点击游戏逻辑、实体标签,将获取实体计数指令拖入编辑界面,该指令可以获取到选择的标签下一共有几个实体。我们将其选择好山贼标签。
                        
        接着使用逻辑判断语句,当标签下的实体数小于5时,才会执行生成实体逻辑。这样就解决的NPC无限刷新的问题。
                        
3.4随机位置刷新
        接着,我们要解决所有NPC都刷新在一个位置的问题。这个问题其实也不难解决,我们只需要在地图中多放入几个参照点,生成时,在多个参照点中随机选择一个即可。
                        
        不过,如果要按照之前制作随机掉落时的方法,那样可太麻烦了。我现在来教大家一个更简单的方式,我们打开游戏逻辑菜单,放入游戏逻辑标签。这个逻辑对象和实体标签的用法差不多,只不过实体标签是针对实体的,而游戏逻辑标签是针对游戏逻辑。我们将参照点都打上游戏逻辑标签。
                        
        我们打开时间触发器的脚本编辑界面。点击游戏逻辑、逻辑标签,这里有一条和其他不一样的指令,获取逻辑对象指令。
                        
我们看到这个指令的前端有两个凸起。我们刚刚使用的获取实体计数能获得一个变量,而获取逻辑对象指令能获得一个数组。那么什么是数组呢?如果把变量比作一个房间,那么数组就像拥有很多房间的楼层。除了能够在楼层的房间中保存对象,还能根据房间号找到里面的东西。而使用该指令获取到标签下的东西时,就如标签面板
                        
当我们使用该指令获取到标签下的东西时,就如标签面板所示。这些游戏逻辑都按照顺序放置在数组中。这样我们通过这个指令即可获取到所有的参照点。
                        
        接着我点击数组,找到随机数组指令。这条指令可以从数组中随机抽出一个对象,我们将获取游戏逻辑对象指令放入其中,这样我们就可以通过这两条指令获取随机的参照点。
                        
        最后将其接入获取位置中,就完成了这个随机刷新山贼的系统啦。
                        
4、 作业
修改了本期的掉落系统,本期掉落系统中,最多只可能会掉落一件装备,如果修改成最多能同时掉落四种装备。并且每件装备的掉落概率都为30%。
                        



版主
  • 主题

    70

  • 帖子

    151

  • 精华

    7

+加好友 查看TA的游戏
  • L0
  • 2

发表于:2020-4-20 16:26:49 沙发

中级教程第二期

角色扮演中级第二期:玩家等级系统
        艾兰岛的岛民们大家好,欢迎来到从零开始系统。在中级第一期的教学中,我们已经学会了使用随机数制作怪物的随机掉落和随机刷新。现在我们就来看看我们第二期中将会学习到的游戏内容吧。
        我们在出生时身上就携带了一把武器,在物品栏上方有一条经验条,左上角有写着我们的等级。
                        
我们在击杀山贼时,玩家上方会跳出增加经验值的数字,同时下边的经验栏的进度条也增加了一部分。
                        
        我们继续击杀山贼,当经验值足够时,我们们身上跳出升级的特效,同时左上角的等级UI也变化成了2级。下方的经验值进度条也被重置,并且从头开始累积了。
                        
        经验值和等级可是角色扮演游戏中很关键的系统,我们现在来看看要怎么样制作出这个系统吧。
        首先我们先来看一下本期可以学习到内容吧,首先是制作玩家的经验值系统以及对应的HUD,接着是制作玩家的等级系统。
                        
1、经验值和等级HUD
首先我们来学习如何制作经验值系统吧。
                        
我们先来制作我们看到的HUD,打开游戏逻辑,找到自定义HUD并将其放置在地图中,修改名字为[自定义HUD]玩家属性面板。接着往下看,有一行“对新玩家可见”,勾选该行,所有新进入的玩家都可以立刻看到这个HUD中包含的东西。而我们的游戏中,在玩家一进入游戏后就可以看到这个HUD,所以我们可以勾选上该选项。
                        
在点击属性最下方的编辑布局按键后,进入了UI界面,我们可以看到这边右上角有三个控件,分别是节点、图片文本。其中节点可以放置于界面部件中间,方便梳理整个部件间关系。图片控件,可以在UI中插入图片,起到修饰的作用。文本框,可以在UI中放入文字,起到说明的作用。
                        
此外,节点、图片和文字之间可以相互包含,我们把这种包含关系称为父子关系。例如空节点1中包含图案2,那么空节点1就是图案2的父;图案2就是空节点1的子。类似的还有图案4和文本4之间、文本4和图案5之间。
                        
如果上面的父UI不显示,那么里面的包含的部件都不显示。例如把空节点1关闭掉,空节点的子内容都不会显示。
                        
        首先我们先制作玩家的等级UI,我们使用文本控件制作玩家等级UI,同时修改其位置和宽高。为了格式统一,我们修改水平对齐为向左对齐。
                        
        目前文本的颜色为白色,似乎和现在的UI不太符合,我们将其修改为橙色,同时修改其中的默认文本为Lv:1。
                        
        接着我们继续制作经验值的HUD。我们先放置一个节点在物品栏上方。同时修改名字、位置、宽高。
                        
        接着我们先选择放置的节点,然后点击图片按键。这样就可以在节点下放置一个子图片UI。
                        
        接着我们不需要像之前调整节点那样去调整UI的大小。我们点击位置转换属性,我们先点击左侧的位置转换属性,然后选择第一行第四个平铺,这里的各个按键都能修改UI对于上一级UI的位置方式,比如我们使用的这个,就是完全和父UI的大小一致。
                        
        接着点击图案,并且选择边框。这是这个边框样式有点奇怪,我们再点击类型,将其修改为切片。这样就把这个HUD调整正常了。
                        
        最后再修改颜色为黑色。
                        
        我们在框中先放置一个文本框,将文本修改为EXP:
                        
        然后放置一个经验栏的外框。
                        
        接着我们需要制作经验值的填充条,我们依旧使用图片控件来制作,放置后,修改好对应的位置,并将类型修改为填充,这时会多出来一个拖动条,我们拖动填充拖动条就可以控制这个图片的长度,不过我们在进入游戏时,经验值为0,所以我们将填充量修改为0。
                        
                        
        经验值填充条制作好了。不过这么长的填充条,很难直观的看到进度到底到达了多少了。所以我们再给这个UI加上一些刻度。我们依旧使用图片控件,将其作为经验条的子UI,并且使用渐变图案,同时使用左对齐格式,修改位置为整个经验条长度的1/10处。
                        
接着我们选择制作好的第一条标识,按下CTRL+C,接着选中经验条,按下CTRL+V。接着修改位置X,这样就可以制作好第二个刻度。
                        
        我们接着复制粘贴处剩下的刻度。这样就完成了这个HUD。
                        
2、经验值系统
        制作好了HUD,接下来我们要来制作经验值系统了。
                        
        首先,我们先来想一想这个系统中,需要一些什么数据?我们再来看一下游戏中的画面,可以看到左上角需要有记录等级,下边需要经验值进度条的百分比,而百分比则需要计算当前经验值/本次升级需要的经验值。所以,我们一共需要三个变量来记录这个三个值。
                        
        这三个变量,我们都是要对于玩家来记录的,那有什么办法可以记录在玩家身上呢?使用全局存储吗?使用全局存储记录变量,就相当于在整个游戏内都能用这三个变量。只有一个玩家的时候,这样一个全局储存对应一个玩家并不会出现什么问题。
                        
但是此时如果出现了第二个玩家呢?这样第二个玩家将会和第一个玩家共用同一个全局存储,当玩家1获得100点经验值时,玩家2也会获得100点经验值。很明显,这样子是不对的。
                        
        在游戏中,还有一个存储数据的游戏逻辑,就是实体存储。那么,实体存储有是什么东西呢?他和全局储存又有什么区别呢?
2.1实体储存
                        

我们就拿钱包来打个比方,如果把实体比做一个人,那么实体存储就是他的钱包。它与全局存储的区别在于:

全局存储就好像是丢在地上的钱包,玩家A拿钱包里的钱去购买东西,钱包里的钱会减少;玩家B也去拿里面的钱去买东西,钱包里的钱同样会减少。

                        

而使用实体存储,就好像玩家有各自的钱包,花钱的时候都花的是自己的。

                        

如果玩家A想花玩家B的钱,就需要先找到玩家B,再从B的钱包取钱。

                        

所以在考虑到多人游戏的情况下,我们可以将团队共享资源写在全局存储中,而玩家间相互独立的资源就推荐大家写在实体存储中。

        介绍完了实体储存,我们接下来就来学习怎么使用它制作经验值系统吧。首先,我们先修改他的名字为[实体存储]玩家经验值,
                        
接着点开脚本编辑界面,创建三个变量,这些似乎和全局储存的用法没有什么区别。
                        
        我们在刚刚的游戏中,当我们击杀山贼时,我们头顶会跳出一个增加经验值的数字,下边的经验值的填充条也增加了一段。
                        
        这个逻辑还是比较简单的吗,我们先不去考虑升级的问题,还是依据“什么时刻做什么事情的逻辑”来分析这个事件。首先是我们击败怪物时,然后获得对应的经验值,接着显示经验值文字,最后修改经验值UI。
                        
        这样就很明显了,首先是击败怪物。在中级第一期的怪物随机掉落中,我们就通过事件侦听器来获取了击败怪物的事件。不过那个逻辑是针对山贼的掉落,所以,我们再放置一个新的事件侦听器,并给予对应的标签,这样所有被贴上标签的实体,都可以被这个侦听器获取到。我们设置好侦听的属性,并且将山贼们贴上这个标签。
                        
        不过大家不要忘了我们还有后来通过时间触发器生成的山贼。打开时间触发器,我们现在要将生成的山贼实体添加上两个标签,一个是刚刚放置的标签,一个是掉落系统中的山贼标签。我们先使用本地变量,存储山贼的实体,然后再将变量中的山贼拖入添加标签的语句中。
                        
                        
        接着我们就要开始制作玩家获取经验值的具体逻辑了。首先第一步就是获取经验值。
                        
        这一步很简单,我们打开事件侦听器,点击变量、实体储存,找到设置目前经验值变量将其放入击败时下方。
                        
我们发现这几个变量时候和刚刚在实体存储中看到的不太一样,当在实体存储内部时,我们不需要填入一个实体,而在实体存储外时,则需要填入一个实体。我这就来告诉大家为什么。我们拿等级来说,当从外部要查找玩家的等级时,我们肯定先要确定是哪一个玩家,然后才能知道这个玩家的等级,而当我们自己要查看自己的等级时,那很明显,被查看的人就是自己,自然就可以不用去找了。
                        
        好了,回到刚刚的逻辑中,我们击败怪物时,设置玩家的经验值增加,所以设置玩家经验=目前经验值+获得经验值。而这里需要填入实体,就是获得经验值的玩家,那就是击败怪物的触发实体,所以我们将触发实体填入其中。
                        
        接着是获取的经验值,这里我们就随便填入一个数字,比如就是被击败实体的最大生命值,这样我们击败越强大的怪物时,也能获得更多的经验值。
                        
        接着我们还要制作玩家获得经验值时,头顶跳出的文字。我们点击游戏,显示文本,这里有两条指令可以在游戏中显示跳动文字,其中一条是只有指定玩家可见,另一条是所有玩家可见。而这里的我们只需要获得经验值的玩家可以看到即可。所以选择第二条指令。
                        
接着我们来看一看这条指令,第一个空格选择的是在哪个实体上方显示文本。我们肯定是要在获得经验的玩家头顶显示,所以这里也填入触发实体。
                        
第二个填入显示的文本,我们肯定是要显示我们获得的经验值,所以直接填入怪物的最大生命值就可以了,第三个时颜色,这个就看个人喜好了,我们这里就设置成橙色吧。接着是时间,淡入淡入淡出。文本动画我们选择上,这个大家可以都试一下。渲染一切则代表的是文字是否可以被实体遮挡,选择为假时,则会被文字遮挡,为真时则不会。接着是字体大小,这个可以按照需求来修改。而自定义图像则是在显示的文本之前添加一个图像。最后一个则是对应显示的玩家,只有这里填入的玩家才能看个这条指令显示的文字。当然这里也是填入触发实体。
                        
        接着我们点击测试游戏,去测试一下我们刚刚编写的逻辑,我们进入游戏,击杀山贼。结果左下角跳出了一堆错误,头顶也没有跳出经验值的图标。这是什么原因呢?
                        
        原来实体储存在使用前,我们还需要先使用指令添加存储才可以使用。那么我们需要在什么时候添加储存呢?在事件侦听器中吗?那样不是每击败一个实体,就会添加一次储存了?而且,玩家应该是在进入游戏时,就应该拥有经验值。所以我们在进入游戏的时候,给玩家添加上经验值的储存。
                        
2.2玩家角色
        这里要给大家介绍一个新逻辑,玩家角色。这个逻辑相当于是玩家可以选择的英雄,我们可以放置多个供玩家选择,不过我们这里只需要一个即可。
                        
我们打开脚本编辑界面,在事件中找到玩家出生时事件,这个事件会在玩家出生时执行,所以我们只需要在玩家出生时给玩家添加存储就可以了。其中玩家自然是出生的玩家,而存储则选择我们刚刚放置的那个存储。
                        
                        
        除了添加存储,我们还需要设置一下玩家出生时的等级、经验值和最大经验值。其中等级自然设置为1,当前经验值设置为0,最大经验值就暂时设置为300。
                        
同时我们还要设置一下玩家左上角的等级UI。点击游戏逻辑、自定义UI。找到获取部件指令和设置文本指令。其中文本指令可以设置指定部件的文本,第一个空格需要通过另一条获取部件指令获取,第二个空格则填入我们要修改的结果,比如这里我们填入LV:1
                        
        而获取部件指令,首先第一个空格先选择我们需要的修改UI逻辑,第二个空格选择我们要修改的UI部件,而这里就是等级。第三个空格处填入玩家。接着再将其接入设置文本逻辑中。
                        
                        
2.3自定义指令
制作完成后,这样一大块的逻辑指令看起来十分杂乱,如果我们以后还要在这个出生时事件下边添加新东西时,那看起来就太难受了。所以我们可以将它稍微整理一下。
                        
现在,我来教大家使用自定义指令来优化一下自己的界面吧。我们点击左边的自定义指令,选择此找到第一个函数并拖出。此时我们发现在“此”的拓展栏最下方,多出了一条指令,名字为函数。
                        
我们点击函数,修改名字为初始化玩家经验值系统,对应的指令名被修改为了玩家复活。
                        
我们将左边的一大串指令拖入自定义指令中,并且将自定义指令单独拖出放在初始化玩家经验值系统时下方,这样是不是感觉玩家出生时下方清爽了很多呢?这个好处当然不止如此,这个我们后边还会说到的。我们再来看右侧的所有玩家,发现这边的玩家都变为了红色,这是因为这里的玩家参数来源于事件下边,自定义指令中没法获取到事件中的玩家,所以这样会发生错误,那要如何解决呢?
                        
我们点击自定义函数“初始化玩家经验值系统”,在名称处输入出生玩家,并且点击添加。
                        
这时,自定义指令就多了一个空格,我们将玩家出生事件中的玩家拖入空格中,这样在玩家出生时下边使用自定义指令“初始化玩家经验值系统”时,刚刚创建的参数“出生玩家”就是玩家出生时下边的玩家啦。我们再用出生玩家将红色的玩家替换。
                        
        这样就完成了这个初始化。为了方便我们的测试,我们回到玩家角色的属性界面下,给玩家添加上一把武器。然后再进入游戏测试一下吧。
                        
        这次我们进入游戏以后,击败山贼,头顶就跳出了经验值的数字,而且左下角也没有再弹出红字报错了。
                        
2.4动态修改UI
不过,我们下边的UI还是没有改变。现在我们就来制作修改UI的长度吧。我们回到事件侦听器中,找到设置填充量指令。这个和设置文本的逻辑差不多,第二个空格填入的是填充量百分比,也就是当前经验值/最大经验值的。我们先将其他空格选好。
                        
        接着我们用一个本地变量先存储计算值。并将百分比填入最后一个空格中
                        
        这时,我们再进入游戏击杀山贼,就可以修改对应的HUD啦。
                        
        不过,在RPG游戏中,获得经验值的手段可不止击败怪物这一个手段。那我们是不是还要去这些地方,都把获取经验值的指令再写一遍呢?其实大可不必。还记得我们在玩家角色中使用的自定义指令吗?我们在事件侦听器中没法调用到玩家角色下的自定义指令,但是却可以调用到全局存储和实体存储下的自定义指令,我们将玩家获得经验值的指令写在实体存储中。首先先在自定义指令中放置函数,并且添加一个参数,作为玩家获得的经验值,这样我们调用这个函数时,只需要填入玩家本次获得的经验值,就能继续执行下边的指令了。
                        
        接着我们对应事件侦听器下边的逻辑,不过这次设置变量时,我们使用此中的变量,则不需要填入玩家。
                        
        最后就是要吧其他几句逻辑填入玩家了,当然,玩家也可以通过传入参数的方式过来。但是还有更简单的方法,我们点开游戏逻辑、此,这里有一个存储拥有者。顾名思义,这个就是拥有这个存储的人。所以我们直接将这个填入指令中。
                        
        最后回到事件侦听器中,发现这边的自定义指令和变量一样,也需要填入一个实体。所以我们将触发实体填入其中,就完成了玩家击败怪物获得经验值的逻辑啦。
                        
3、玩家等级系统
制作好了玩家获得经验值的逻辑,接下来,就该制作等级系统啦。
                        
        在RPG游戏中,通常每个等级对应的最大经验值都是不一样的,其中制作为表格就如这样。而等级和需要的经验值就是一一对应的关系。
                        
        所以我们要制作等级系统,那就必须要先将等级和经验值对应的表格,在游戏中存储起来。而当玩家升级的时候,修改玩家等级的同时,还要将玩家当前经验值扣除升级需要的经验值,最后需要修改玩家对应等级的需求经验值。
                        
        所以首先我们先来制作这个等级对应经验值的数据库。
3.1简易数据库
        我们继续看这张表格,不难发现,表格中等级可以作为一串数据列,需要的经验值也可以作为一串数据列,而且两串的数据列的序号是一致的。
                        
        大家一定还记得中级第一期中,我们提到的数组吧。数组就是一个可以存储很多数据的容器。之前我们是通过标签的形式,获取数组的内容,今天我就教大家如何创建和使用数组。首先,因为这两个数据,在游戏中,每个玩家升级的时候都会用到,但是都只需要用的一样的数据且不会改变。所以我们只需要在全局存储下边保存数据就可以了。我们先放置一个全局储存在地图中。同时修改名字为[全局存储]初始化经验值系统。
                        
接着我们打开全局存储的脚本编辑界面,点击变量此、点击创建新变量,同时勾选数组,并输入我们想要的名字,再点击确认。就创建了好了数组变量。
                        
        我们点击数组,这里的指令都是可以对数组进行操作的。而我们本次需要使用的是PUSH指令。而这里有两条push指令,我们看末尾的对象空格,不难发现一个可以填入变量,一个可以填入数组。而这两条指令的功能就是将数组或变量放入数组的末尾中。而我们这里需要使用的,肯定是针对变量的一条。为了能让等级和经验值在数组中位置一致,所以我们在存入数据时,需要同时使用push指令,将二者的数据分别存入数组中。我先放置一个自定义指令,并且添加等级、经验值两个参数。接着接入两条push指令,并将等级、经验值两个参数分别压入玩家等级和玩家经验值的两个数组中。这样我们调用这条指令的时候,两个数据将分别被存入两个数组中相同的位置中。
                        
        接着我们再使用一个自定义指令来制作表格中的数据库。制作完成后,我们还需要一个事件用来执行数据库的初始化。而这个数据,应该在游戏的最开始就执行。所以我们找到事件游戏开始时,并在事件下方调用刚刚创建好的数据。
                        
3.2玩家升级
        制作好了数据库,现在可以来制作玩家升级事件啦。首先,我们还是依据什么时候做什么事情的逻辑来分析一下这个事件。玩家会在什么时候升级呢?就是玩家获得经验值的时候,所以我们在玩家获得经验值的时候,需要判断计算后的经验值是否满足升级条件。同时执行升级的逻辑。执行完毕后,还需要考虑玩家本次获得经验值过多的情况,所以还需要再次判断玩家是否可以升级。如果不能升级,则结束逻辑的运行。
                        
        我们先来制作玩家升级这部分的逻辑,我们继续打开玩家经验值的实体存储,放置一个自定义指令,首先是修改玩家等级和修正玩家经验值,我们将目前经验值设置为目前经验值-最大经验值,而等级则为当前等级+1。
                        
        接着我们还要给我玩家一些升级的反馈。我们可以从听觉和视觉两方面给予玩家反馈,我们在搜索处先搜索粒子,将播放粒子特效指令放入下边,其中第一个空格可以选择粒子的样式,其中就有升级的特效。第二个位置自然就是玩家的位置,我们使用获取位置指令,获取存储拥有者。旋转就是粒子的旋转绝对,这里可以不用修改。缩放为粒子的大小,而这里使用默认值即可。
                        
        接着我们搜索音效,第一个空格是可以选择各种声音,后面几个也都很好理解。
                        
        接着我们还要修改左上方的等级UI。使用设置文本指令和获取部件指令进行组合就可以了。
                        
        最后,我们还需要修改一个变量,就是玩家当前等级最大经验值。由于玩家等级的变化,而升级锁需求的经验值也发生了变化,比如刚刚数据库中,我们为1级的时候,需要经验值为300,而升级时,等级变为了2级,所以我们需要的经验值就变为了400。这时候,我们就要把当前等级最大经验值这个变量从300修改为400。那我们要如何查找到对应的经验值呢?
                        
        当我们升级时,等级从1变化为了2。所以我们可以先确定等级为2。那么我们只需要先通过2级查到2级在等级数组中的索引为1,接着再通过索引1就可以找到对应的经验值。
                        
        现在我们首先要查找升级后的等级在数组中的位置。我们先放置一个本地变量进行保存,然后打开数组栏,找到index of指令,这条指令可以查询对象在数组中的索引。我们填入全局存储中的数组和修改后的玩家等级。
                        
        接着我们使用获取数组数值的指令,获取到对应的玩家经验值数组中的数值。同时修改玩家当前等级最大经验值。
                        
        但是,按照数据库中,玩家等级只有7级,当玩家的等级达到了8级时,那就找不到对应的经验值了。所以我们还需要做一个判断,当index of查询不到对应的值时,获得的数值为-1。我们就可以判断索引的值是否为-1,当为-1时将目前经验值和最大经验值都修改为0。不为0时,则设置当前等级最大经验值。
                        
        完成了升级逻辑以后,我们开始制作判断玩家是否升级的逻辑。首先当玩家可以升级时,执行完升级语句后,还需要再判断玩家是否可以升级。所以我们这里需要使用循环指令。我们先放置一个新的函数,然后打开循环,使用只要是指令,这一条指令为条件循环。只要满足空格中的条件,就会执行包含的逻辑。所以我们这里判断一下玩家目前经验值是否大于当前等级最大经验值即可。然后调用玩家升级指令。
                        
        最后我们还要修改一下玩家获得经验值函数。我们在这里插入判断玩家是否升级指令。
                        
        接着我们还需要判断玩家是否已经满级了,和升级逻辑一样,我们依旧通过索引来制作。我们查询玩家的索引,如果索引不等于-1时,才会执行增加经验值的逻辑。
                        
        这样我们就完成了游戏中的等级系统和经验值系统。
4、作业
        使用数据库设置怪物的数值,并且在生成怪物时,给怪物添加经验值存储。玩家击败怪物A时获得100点经验,击败怪物B时获得200点经验值,击败怪物C时获得300点经验值。
                        



版主
  • 主题

    70

  • 帖子

    151

  • 精华

    7

+加好友 查看TA的游戏
  • L0
  • 2

发表于:2020-4-24 16:59:36 板凳

中级教程第三期

角色扮演中级第三期:玩家任务系统

艾兰岛的岛民们大家好,欢迎来到从零开始系列。上期视频中,我们做出了玩家的经验值和等级系统。那么,除了打怪之外,角色扮演类游戏中,另一个重要的经验值来源----任务系统也是必不可少的。我们本期的中级教学,就来制作一个简单的任务系统吧。

  我们和商人进行对话,商人表示想让我们帮忙传一个口信给小镇里的弟弟,让他来帮忙。
                        

我们到了小镇中,和相应的npc对话,点击完成任务,这个简单的对话任务就做完了,还获得了不少的经验值。

                        
                        

我们再和这个npc对话,他说他刚刚上山采药的时候被狼群袭击了。希望我们帮他杀掉五只狼。

                        

接受任务后,我们上山杀掉了狼。

                        
还在附近发现了一些药草。这里就先拿上,没准儿一会用得到。
                        

现在可以回去找npc交付任务了。

                        

交付了打怪任务之后,我们获得了经验并且升了级。那么就再和NPC对话一次,看看还有没有其他任务。这回npc又委托我们帮他采集三株药草。

                        

刚刚采集的药草正好就能够派上用场了,可以直接交给npc。

                        

点击完成任务,扣除了我们的任务物品,角色又获得了经验值。这样,我们的第三个任务,收集物品的任务也完成了。

                        

之后再找npc对话的话,就只有一些简单的寒暄了。看来所有任务都已经做完了。

                        

而如果我们在刚开始的时候不接取对话任务,直接找小镇中的NPC进行对话的话,是无法接取到打怪任务的。

                        

并且接了打怪任务后,再和npc对话,他也只会催促我们赶快动身。不会让我们接到采集草药的任务。

                        

也就是说,这是一个一环扣一环的任务链。

下面就让我们一起看看这样的任务系统是怎么实现出来的吧。

  • 场景设置


场景方面我们需要的是一个小镇,大家可以在创意工坊中搜索“小镇”找到我们本期教学中用到的这个小镇,当然小伙伴们也可以自行搭建一个小镇。

                        
2、功能梳理

场景设置好后,我们来梳理一下今天要实现的功能都有哪些。

刚刚的演示流程中,我们一共做了三种不同类型的任务,分别是对话任务,打怪任务和采集任务,并且这三个任务之间有一定的次序,完成了前置任务之后,才能接受新的任务。

                        

并且这三个任务之间有一定的次序,完成了前置任务之后,才能接受新的任务。

                        
  • 逻辑实现

2.1 步骤分析

我们在和NPC互动的时候,可能是四种情况,第一种,玩家过来找NPC想要接取任务。第二种,玩家已经接过任务了,不过任务还没有完成。第三种,就是玩家完成了任务,过来找NPC交付任务并领取任务奖励。而最后一种,则是玩家不能从NPC这里接到任务的情况。

                        

所以我们下面首先要做的就是,在玩家交互NPC时,通过指令来区分出这四种不同的状况。

第一种情况,玩家来接取任务,我们期望只有满足接取任务的条件的玩家才能成功的接到任务。

那么接取任务需要满足哪些条件呢?

为了保证任务之间的次序,想要接取一个新任务,就需要先判断我们是否已经完成了它的前置任务,只有完成了前置任务,或是我们想要接的这个任务它没有前置任务时,才能够接取新任务。这里需要强调一下,判断前置任务是为了实现出一环扣一环的任务链效果,不需要的话可以不对该项进行判断。判断完前置任务的完成情况之后,还需要判断这个任务我们是否已经接过了,已经接过的任务肯定是不可以重复进行接取的。最后,还要再判断一下我们是不是已经做过一遍这个任务了。已经做完的任务也是不能接取的。

                        

同时满足完成前置任务、没有接取过当前任务也没有完成过当前任务三个条件的玩家,才能成功接取任务。

后面的第二种情况和第三种情况,都有一个前提条件,那就是玩家已经接取过任务了。那么我们就可以先判断任务的接取情况,在确定玩家已经接取任务后,再对已经完成任务和未完成任务两种情况进行分别判断。

                        

最后一种,便是其他三种条件都不符合,那么说明玩家已经做过了任务,或是没有完成前置任务,无法接取任务。

3、逻辑实现

理清了判断条件,我们就可以开始编辑脚本指令了。就从最简单的对话任务开始吧。

由于游戏中我们接取所有任务之前,都需要判断玩家是否满足接取任务的条件,所以我们可以写一条自定义指令来避免重复写指令的情况发生。

既然要判断玩家是否满足接受任务的条件,那也就是说,我们要写的这条自定义指令的作用就是获取一个真假值。

我们往期用到的都是无返回值的自定义函数,而今天要用到的则是有返回值的自定义函数。这两者的区别在于无返回值的函数可以直接执行,而有返回值的函数,它的作用只是帮助我们获取到某个值,可以作为参数填入其他指令中。

                        

编辑器**有两个带有返回值的自定义函数模板,其中上面的一条可以帮助我们获取变量,下面的则可以帮助我们获取数组,大家根据需求选择即可。我们的例子中需要获取的是一个真假值,所以就选择使用上面这条可以获取变量的模板。

                        

由于要判断玩家是否可以接某个任务,所以这里就把目标任务做为参数,同时还需要传入目标任务的前置任务,以判断任务是否可以被接取。

                        

接着还要判断玩家对该任务的接取和完成的情况进行判断,多人游戏的情况下,不同玩家对于同一任务的接取状态一般是不同的,那么我们就需要用到前面讲过的实体存储来保存不同玩家的任务接取情况。

考虑到玩家接受复数个任务的可能性,这里我们就选择使用可以保存多个数据的数组来保存玩家已经接受了的任务。

                        
                        

已完成的任务同样也用一个数组来保存

                        

定义好指令和变量后,下面我们开始编辑指令内容,首先是对前置任务的判断,在脚本列表的数组选项中,可以找到INCLUDES指令,这条指令的作用是判断一个数组中是否包含一个指定的值,根据判断结果获得一个真假值,如果数组中包含我们所填入的对象,就会获得一个真值,反之则获得的值为假。

                        

我们可以通过这条指令来判断玩家是否已经完成了目标任务的前置任务

                        

而还有另一种情况是目标任务没有前置任务,两种情况满足其中任意一种就可以,这里我们需要用到脚本列表中逻辑一栏下的逻辑判断指令,指令中可选选项为“逻辑或”和“逻辑与”,我们这里用到的是逻辑或。选择逻辑或的情况下,我们填入该指令中的条件,只要其中任意一个条件为真,那么指令就会获得一个真值,所有条件都为假时得到的值才为假。

                        

这样我们对前置任务完成情况的判断就完成了。

                        

接下来,我们需要对玩家是否已经接取或是已经做过任务进行判断。这两种情况都为假时,才说明玩家没接过并且也没完成过任务

                        

指令列表的逻辑选项中。可以找到非指令,他的作用是获得一个与指令中所填真假值相反的值。

                        
                        

这样就成功实现了对三个接任务条件的判断。

                        

最后,用一个本地变量作为判断的结果,当玩家同时满足三个条件时,我们就将变量的值设置为真。在末尾处将判断结果作为自定义指令的值填入返回值处。那么用于判断玩家是否可以接任务的自定义指令就完成了。

                        

接下来再按照同样的思路写出用于判断玩家是否已经接取了目标任务的自定义指令。

                        

编辑完自定义指令,下面我们就可以开始对NPC进行编程了。

先用选项对话设置好接任务时与NPC在不同情况下的对话内容。接着进入发布对话任务的NPC中,在玩家与NPC交互时,用刚刚写的自定义指令来判断玩家是否可以接一个对话任务,指令的第二个槽位中可以使用任何变量来表示任务,但一定要注意避免重复。这里为了方便大家理解,选择使用文本来表示任务。如果判断玩家可以接受的话,就打开对话任务的选项对话。

                        
                        

在这种情况下,我们需要在玩家选择了选项对话中代表接受任务的选项时,将这个任务保存到玩家的已接任务数组里。

我们可以先去实体存储中,创建一个用于保存所玩家对话任务的变量。

                        

在确定玩家可以接取任务后,就把这个任务保存下来。

                        

最后,要在玩家点击选项对话中的接受选项时,将这个变量存进玩家的已接任务数组中。

选项对话里面回答后指令中回答ID这个参数,对应的便是对象属性中不同回答选项的ID。
                        

这样我们就可以在玩家选择接受任务时,通过回答ID来判断玩家选择的选项,并在玩家选择接受时,将任务存进玩家的已接任务数组了。

                        

完成了接任务的全部流程后,我们接下来再回到NPC处,编辑其他情况下交互NPC会发生的事情。

如果玩家已经接取了任务,那么可接这条指令下的打开对话就不会执行了,所以我们这里新增一个判断,用自定义指令判断玩家是否已经接取了任务。

                        

原本有两种可能性,分别是接了任务但未完成时会发生的事,和完成了任务会发生的事。但由于这是个对话任务,完成任务的条件是与小镇中的NPC对话,所以我们和这个NPC对话时不可能触发完成任务的情况,我们就在这里直接为玩家显示接了任务而未完成情况下NPC的选项对话内容即可。

                        
                        

最后,如果上述条件均不满足,说明玩家不能接任务,就和刚刚一样显示一下选项对话的内容即可

                        
                        

写完第一个NPC内的指令,我们再来看看情况更多更复杂的,小镇里的NPC的脚本指令该怎么编辑。

首先,我们先判断玩家有没有接取对话任务,如果接取了,就可以为玩家显示选项对话的内容。

                        
                        

当玩家点击选项中的完成任务时,我们总共需要做三件事,第一件,将这个任务存进玩家已完成任务的数组中,第二件,将这个任务从玩家的已接任务数组中移除掉。最后,则是将任务奖励发放给这个完成任务的玩家。

其中的第一件事,需要获取到玩家正在对话的任务,由于这里发生了新的对话,所以我们就去判断玩家是否已经接取任务的自定义指令中更新一下正在对话的任务的值。

                        

接着,用前面讲过的push指令将任务存进已完成数组即可。

                        

接下来是第二件事,我们需要把这个完成了的任务,从已接任务的数组里面移除掉,这个移除的操作分为两个步骤,第一步我们要先找到这个任务在已接任务数组中的位置。我们可以使用index of指令来完成这个步骤。

                        

第二步,便是通过刚刚找到的索引来删除掉数组中保存的任务,这一步骤中要用到的是SPLICE指令。这条指令同样在可以在数组一栏中找到。

                        

指令的作用就是删除数组中保存的东西,第一个空中填入目标数组,也就是玩家的已接任务数组,第二个空中填入删除目标的索引,也就是我们刚刚用index of指令获取到的索引,最后的计数指的是删除东西的个数,我们这里只需要将刚刚完成了的那个任务删除掉,所以填1就可以了。

                        

还有最后一件事,就是给玩家完成任务的奖励,这里就用上期视频中的修改经验值指令,奖励玩家一些经验值。                        

这些就是在玩家交付任务时需要做的事情了,下面我们再回到小镇NPC中,完成其他情况的脚本指令。

对话任务相关的脚本已经全部完成了,下面我们可以继续判断玩家是否能够接取打怪的任务。这里我们就在前置任务处填入对话任务,只有完成了对话任务的玩家才能接取打怪任务。

                        
                        

与对话任务一样,需要在玩家接受任务时将任务存入已接的数组中。

                        

而这次不一样的是,这回我们需要在玩家已经接了打怪任务后,对任务的完成情况进行判断。也就是说,需要判断玩家打败怪物的数量。

                        

那么我们就可以去玩家的任务存储中,创建一个用于保存打怪数量的变量。

                        

接着用事件侦听器,侦听玩家击败狼的事件。

                        

在玩家击败狼时,判断一下该玩家有没有接打怪任务,如果接了,就让该玩家的打怪数量+1。

                        

然后回到游戏存储中,由于考虑到游戏内可能有多个打怪任务时的情况,我们这里就编写一个用于判断玩家打怪的数量,并根据判断结果打开对应情况的选项对话的自定义指令。

                        

接着回到NPC处,调用刚刚的自定义指令即可。

                        
                        

完成任务时同样要将任务从已接数组中移除,并存入已完成数组,最后在加上任务奖励。

                        

现在只剩下最后的采集任务了,判断采集任务的完成情况时,需要对玩家背包中的物品进行检测。

                        

那么我们就再去实体存储中写一个用于判断玩家任务物品是否足够的自定义指令,参数这里要用到任务物品的数量和任务物品的实体类型

因为现在我们需要判断玩家背包内任务道具的数量,所以这里就创建一个本地变量用来保存道具的总数量。

                        

在实体一栏的角色选项中,可以找到获取背包指令。该指令的作用是以数组的形式获取到角色背包内的所有实体。

                        

获取到玩家背包内所有的物品后,我们需要对每个道具进行一次判断,并找出其中的药草。数组循环指令可以帮助我们获取到背包内个每个物品。

                        

在实体一栏中的高级选项下,可以找到类型判断指令。该指令的作用是判断第一个空内所填的实体,是否属于第二个空内填入的实体类型。如果属于,则获取到的值为真,反之则会获取到一个假值。

                        

那么我们在指令第一个空里面填入背包内的物品,第二个空内填入任务物品的实体类型即可。

随后再用如果指令进行判断,若类型判断的值为真,说明该道具是任务物品,那么我们就需要记录它的数量。

                        

在实体一栏的道具选项中,可以找到获取堆叠计数指令。该指令的作用就是获取指定道具的堆叠数量。

                        

这样就能得到玩家背包内各个栏位里面药草数量的总和了。

                        

得到背包内药草总数量后,我们就可以看看这个数量是否满足任务的需求,并打开相应情况的选项对话。

                        

完成自定义指令后,我们回到NPC处,调用刚刚的自定义指令即可。

指令中的任务物品实体类型处,在游戏一栏的枚举选项下可以找到实体类型

                        

点击可以对实体类型进行选择。演示中我们是用亚麻植株作为药草的,这里我们直接使用搜索框找到亚麻植株,并填入类型判断指令中。

                        
                        

在我们交互采集任务的时候,除了之前的三件事之外,还需要多做一件事,那就是从玩家的背包中扣除任务物品。

                        

下面我们就再去实体存储写一个用于从玩家背包中扣除物品的自定义指令

这里就用一个本地变量来表示一下玩家待扣除任务物品的数量,并用数组循环找到玩家背包内的药草。

                        

在实体一栏的道具选项中,可以找到设置堆叠计数指令。这条指令作用是将物品的数量设置为我们填入的数值。我们可以用这条指令来扣除玩家背包中的药草。

                        

接着我们判断一下待扣除道具的数量是否大于0。如果大于零,便说明我们需要扣除道具,那么我们就用一个本地变量来记录一下本次扣除掉道具的数量。

                        

接着用设置堆叠指令扣除玩家道具后,修改一下待扣除物品的数量,这样的话如果一个栏位里面的亚麻植株都扣光了,就会从背包中下一个亚麻植株的栏位中继续扣除道具。

                        
写好自定义指令后,回到采集任务的选项对话中执行自定义指令即可。
                        

最后,我们再回到小镇NPC中,添加好最后一种情况,玩家已经不能从NPC这里接任务的时候,显示一下闲谈的对话,我们本期玩家任务系统的所有内容就全部编辑完成了。

                        
4、作业

制作任务数据库,要求可以通过数据库设置三种任务的前置任务以及选项对话,其中打怪任务与采集任务都需要用另外的数据库来保存任务信息,包括任务目标数量和任务目标的实体类型。

                        
                        




版主
  • 主题

    70

  • 帖子

    151

  • 精华

    7

+加好友 查看TA的游戏
  • L0
  • 2

发表于:2020-4-24 17:02:27 地板

角色扮演中级第四期

角色扮演中级第四期:玩家技能和法力值
        艾兰岛的岛民们大家好,欢迎来到从零开始系统。在中级第三期的教学中,我们已经学会了制作对话、打怪、收集三种任务。现在我们就来看看我们第四期中将会学习到的游戏内容吧。
        进入游戏后,我先看到在左上角有一个血条和蓝条,同时我们看不到了游戏中自带的心型血条。
                        
        接着让我们走进建筑中看一看。
                        
        咦这里好像有一个很长的楼梯,我们爬到二楼去看看二楼有什么。
                        
        我们发现二楼有一个悬浮的武功秘籍,还在上下飘动。
                        
        我们交互武功秘籍,身上弹出了粒子特效,还有叮的一声音效。同时右上方弹出了一条消息,恭喜学会了新技能。而在右下角多了两个按键提示,分别是冲刺和剑气斩。
                        
        我们先按下T键,立刻就有几道剑气从玩家正前方发射出去,同时左侧的蓝条也减少了,并且剑气斩也进入了冷却状态。
                        
        而我们再次按下了T键时,并不会释放技能。而当左侧的倒计条归0后,我们按下T键才能再次使用剑气斩。
                        
        接着我们再试一试Y键。哎我们怎么飞了出去,还摔了我半管血条。
                        
        现在我们来看一下要如何制作出本期的游戏内容吧。
        首先,我们先来看一下本期可以学习到的内容吧。首先是我们的法力值系统,还要制作对应的蓝条和红条。接着是制作两个技能:剑气斩和冲刺。最后是制作技能冷却系统。
                        
1、 制作法力值系统
首先我们先在创意工坊中搜索法力值,找到玩家法力值自定义HUD组件放入地图中。
                        
        我们打开新放入的组件,由于独立的心形血条和条状的蓝条不太适合,所以我们这里也制作了血条。并且这两者都已经设置好的了填充格式。我们在制作时,只需要修改这两个UI部件就可以了。
                        
        然后我们来考虑一下法力值系统中需要实现的地方,首先是给玩家添加数值,接着需要根据法力值动态修改UI,最后还需要每秒恢复玩家的法力值。
                        
1.1给玩家添加数值
        了解了这些,现在制作起来就很简单了。首先我们要给玩家添加两个数值,和经验值一样,是每个玩家都需要拥有的。所以我们先放置实体存储,修改名字为[实体存储]玩家法力值。然后在其中创建三个变量,当前法力值、全部法力值、每秒法力值恢复量。
                        
        接着我们再制作修改法力值的同时,还要修改玩家显示的UI,这个也和经验值系统一样,放置一个函数,同时创建一个参数为变化值。设置当前法力值为当前法力值+变化值,同时计算法力值的百分比,并且使用设置填充量指令修改蓝条的填充量。
                        
        不过这里有一个问题,修改法力值不像经验值,通常使用技能的时候,变化值为负数。但是游戏中自然不能让法力值变为负数,并且在恢复法力值的时候,也不能让法力值超过玩家的最**力值。所以我们可以使用一个限制。我们点击数字,找到clamp指令,这条指令可以限制变量或者计算结果的范围。当第一个空格中的值小于最大值时,则只会获得最小值,反之则获得最大值。所以我们只需要限制计算结果在0到最**力值中间即可。
                        
        制作好了修改法力值的函数。我们还需要制作一个判断玩家法力值是否足够的指令,这样玩家每次释放技能的时候,就可以直接调用判断函数,并判断这次技能是否释放成功。因为判断法力值足够这个事件会有两种结果,一种足够一种不够。所以我们需要使用有返回值的函数,并且根据两种结果分别返回真、假。我们先放置有返回值的函数,接着使用一个本地变量check用来储存判断结果。然后判断当前法力值-变化值是否小于0,如果小于0,则设置check为假,否则为真。
                        
        当然,我们还可以在这里给玩家添加一个提示,告诉玩家法力值不足,我们搜索警告。能获得两条结果,第一条不需要填入玩家,则是所有玩家都能看到警告,但是我们只需要对应玩家能看到即可。所以我们使用第二条警告指令。
                        
        做好了这些,我们还没有给玩家添加存储以及设置对应的数值。为了分类管理,我们不要将初始化的函数全写在玩家角色中,我们放置一个全局储存,并修改名字为[全局存储]初始化玩家法力值。接着制作初始化指令,先给玩家添加储存,然后设置玩家最**力值。接着我们使用各个制作好的修改法力值函数,将当前法力值修改为玩家的最**力值。最后要设置的数值时玩家每秒恢复法力值数。
                        
        最后,我们还要去玩家角色中,调用一下初始化指令。
                        
1.2玩家每秒恢复法力值
        做好了这些,我们的法力值系统就差最后一步了,就是制作玩家呼吸回蓝**。玩家恢复法力值是随时间变化而变化了。那当然要用到时间触发器这个逻辑对象啦。我们放置在地图中,并且修改为每秒执行一次。
                        
        接着,我们在时间触发器中调用刚刚制作好的。修改法力值指令,并且在变化值处填入每秒法力值回复量。但是这里需要填入恢复的玩家,可是时间触发器中无法获取到玩家,这可怎么办呢?
                        
        不慌,我来告诉大家。我们都知道在全局存储中申请的变量是可以全局通用,那么我们如果在全局存储中创建一个变量。并且在玩家出生时记录下来。那是不是就可以使用了呢?不过,变量只能针对一个玩家,如果多人游戏,那就需要用数组来记录。我们在[全局存储]初始化玩家法力值下创建一个新数组。并且在初始化时,将玩家push进数组中。
                        
        然后回到时间触发器中,我们点开循环,找到数组循环指令,这个指令能对数组中所有元素都执行一遍放在其中的逻辑,而道具则指的是每次循环中的元素。我们就将修改法力值指令接入循环中,并且将道具拖入指令中。就完成了恢复法力值的系统。
                        
1.4玩家血条
        我们此时进入游戏,发现左上角还是有心形血条。而且我们设置的红条也没有随玩家生命值变化而变化。
                        
        我们返回编辑,首先先要屏蔽游戏自带的血条。我们打开初始化全局存储,搜索禁用,找到禁用HUD指令,并修改第一个对象为心形血量,第二条为真时,则禁用,为假时则生效,最后填入被禁用的玩家。
                        
        接着来制作血条随玩家血量变化而变化,我们再放置一个时间触发器,将时间设置为最小值0.03S执行一次。
                        
        接着打开脚本编辑界面,同样使用数组循环,对血条进行修改,这样血条UI就会随着玩家生命值变化而变化了。
                        
2、 制作玩家技能
接下来我们就要制作玩家的技能了,其中我们要制作两个技能,以及按键触发的功能。
                        
2.1制作按键监听
在演示中,右下角有显示按键的信息,而同时我们按下对应按键就能释放技能。所以我们先来制作一下游戏中技能通用的这一块
                        
        首先,我们在编辑器的上方点开按键监听。
                        
右上角完成按钮的旁边有两个按钮,这两个就是我们需要在本界面中设置的东西了。其中问号图标的是触发键按钮,触发键指的就是那个被我们监听的按键,点击后会显示一个触发键的列表,现在我们还没添加,所以是空的。
                        
旁边手指图标的是动作按钮,指的是我们的按键动作,是单击,双击还是连击等等。点击后同样会显示一个按键动作的列表,现在也是空的。
                        
        首先,我们需要添加技能的触发键,比如刚刚游戏中按下Y键冲刺,按下T键释放剑气斩。我们先点击问号图标,来到触发键的设置界面,我们点击加号添加一个触发键。
                        
        默认的触发键为名字为射击,且监听的按键为“b”键。左侧的面板是触发键可以设置的属性。
                        
我们先修改名字,比如我们先设置剑气斩的,就修改为剑气斩。
                        
接着我们来看默认按键,我们点击设置后,跳出了这个界面,此时我们按下T键,就可以将这个触发键修改为“T”键。而往下的移动端属性则为移动端的属性设置,这里就先不说了。
                        
        接着,我们再按照这个步骤设置冲刺的触发键,并设置触发键为“Y”键。
                        
        接着我们切换到动作界面,点击加号再次添加动画。左侧可以看到设置的属性,其中第一条生效,勾选时,才能触发此动作。
                        
        第二条名称只是为了识别,可以随便取,我们就修改为触发剑气斩,而ID则是判断的根据,我们先将ID修改为剑气斩。我们在本界面设置好的按键动作,都是需要通过事件***来进行监听的。而事件***就是通过动作的ID来对不同的自定义动作进行区分的。
                        
        我们再来看下一个选项。触发键类型,也就是我们的按键动作。这里是一个下拉选项框,可以看到触发的方式也是多种多样,而且也都比较好理解,这里就不一一为大家介绍了。而我们需要制作的是按下“T”键释放剑气斩,所以我们肯定选择单击时。
                        
        接下来是设置该动作的触发键,我们单击设置,这里可以将动作绑定对应的触发键。默认的只有游戏中自带的这六个按键,而我们的设置的触发键则是在自定义中。我们点击自定义,然后选择我们设置好的剑气斩。
                        
                        
        最后这里显示提示则是右下角的信息,我们将其修改为剑气斩。
                        
最后依据这个制作过程,再制作冲刺的对应动作。
                        
        最后我们放置一个事件侦听器,修改侦听类型为玩家动作,事件为执行自定义按键动作时
                        
        接着我们打开事件侦听器的编程界面,同时拖入事件,我们能看到这个动作ID,而这个就是动作界面中,我们设置好的ID,比如此时我们按下T键,而参数中的动作ID就是“剑气斩”。后续制作好技能只需要通过这个参数进行判断就可以了。
                        
2.2冲刺技能
        制作好了触发系统,接着我们现在制作一个简单的技能“冲刺”。当然,技能和经验值、法力值都是一样的,也是相对于每个玩家的。如果制作的深入一些,还有技能等级,伤害数据,每个人也是不一样的。所以我们制作技能也是需要使用实体存储。我们先放置一个实体存储,并修改名字为[实体存储]冲刺。
                        
        我先来介绍一下冲刺技能的原理。当玩家按下“Y”键后,角色会获得一个很大的向前的速度,导致玩家向前方冲刺出去。而过了一段时间后,玩家的速度会恢复为正常速度。所以,设置速度就是这个技能的核心。然后打开脚本编辑界面,先放入一个函数,然后在实体、角色中找到设置速度指令。我们可以发现第一个空格需要填入玩家,那么在实体存储中自然就是存储拥有者了。而第二个空格需要填入一个向量。那这又是怎么回事呢?
                        
        众所周知,向量是有方向性的,所以这里的速度使用的是向量。而三轴的值则分别指代玩家在X、Y、Z三轴上的速度。我们先放置一个NPC在游戏中。并且在左上角点击移动。我们发现NPC身上出现了一个坐标轴,其中红色为X轴,蓝色为Z轴,绿色为Y轴。这个就是艾兰岛中的坐标系。
                        
        不过在艾兰岛中可是存在本地坐标系的,我们点击上方的省略号,在空间选项中选择本地。
                        
        接着我们发现坐标系发生了变化,除了Y轴以外,X轴和Z轴都已经不在原来的位置上了。
                        
当我们旋转NPC时,本地坐标系也会发生改变。
                        
        当我们切回全局坐标系的时候,坐标系和最早我们看到一样,并没有发生改变。
                        
        其实原因是这样的,首先我们先来弄清楚什么是世界坐标系。一张游戏地图内可能包含成千上百个单独的游戏对象。为了能找到他们中每一个的位置,我们必须把他们放到一个公共场景里,让其中所有的对象都统一遵守同一个坐标系统。这个坐标系统就是世界坐标,它能够标注每个物体在世界中唯一的位置方向信息。我们新建地图时,默认出生点的位置就是世界坐标轴原点(0,0,0)的位置。
                        
世界坐标系的坐标轴,是不会因为物体的旋转而进行改变的。因为坐标轴只是坐标系的一个参照方向。同时,左边属性中的位置的坐标,就是这个实体在世界坐标系中的位置。
                        
        而本地坐标系就不一样了,这个坐标系是以实体本身建立的一个坐标系。就拿NPC来说,固定以NPC的面向方向为Z轴。上方为Y轴,右手方向为X轴建立的坐标。
                        
        回到实体存储中,我们需要玩家向前加速移动,那我只需要在玩家面向方向加入一个速度即可,所以我们只需要设置玩家的速度为(0.0.40)。
                        
        不过,这样好像不太对,玩家如果此时已经在移动了呢?我们还是应该用玩家目前的速度加上我们想要增加的速度才对。我们在设置速度指令边上可以找到获取速度指令。然后使用本地变量先保存,接着打开向量,找到向量计算指令,设置玩家的速度为玩家当前速度+(0.0.40)。
                        
        过了一段时间,我们还要玩家的速度变回原来的值。所以我们可以使用延迟指令,先在左上方搜索延迟,找到该指令,在时间处,我们可以设置延迟的具体时长,这里我们设置时长为0.5秒就可以了。
                        
        当然了,每个技能当然还有对应的一些数值,比如消耗法力值,冷却时间。当然,如果要制作技能升级,那么移动的速度也是需要改变的,所以我们把速度也制作为变量进行保存。
                        
        当然了,我们不要忘记在释放技能的时候,还要消耗法力值的,我们点击自定义指令,找到前边制作好的修改法力值指令。并接入函数中。
                        
        接着我们不要忘记制作实体存储的初始化呀。依旧放置一个全局储存。
                        
然后给玩家添加存储,并设置好相应的数值。
                        
        游戏中,我们是交互一本书籍学会了这个技能。那么,我们可以将初始化放入交互书籍时。我们先在地图中放入一本书籍,修改它的名字,以及可交互选项,将其设置为使用自定义交互。
                        
接着打开脚本编辑界面,找到互动时事件,在其中调用初始化指令。
                        
不过刚刚游戏中我们还给玩家添加了音效和粒子特效,并且还有一个警告文本,我们把这些也加上。
                        
        最后我们修改或者放置一个新的事件侦听器,将其侦听玩家的按键动作
                        
        接着在事件***中,判断动作ID是否为冲刺,接着还要判断玩家的法力值是否足够,如果足够才调用玩家使用技能的指令。
                        
        不过还有一个问题,我们在交互书籍以前是没有这个存储的,那此时按下按键“Y”,那不就出问题了。没错所以我们先打开按键监听的界面,将两个动作的生效都先关闭。
                        
        接着回到初始化中。搜索按键,找到设置自定义按键动作指令,这条指令可以开关设置好的自定义按键动作,第一个空格填入玩家,第二个空格选择按键,最后则是是否开启。
                        
        设置完成后,我们进入游戏看一下。出生后,左下角并没有按键提示,按下“Y”键也没有任何反应。
                        
        我们交互武功秘籍,身上跳出了粒子特效,右上角弹出警告,右下角也显示了冲刺的按键提示。
                        
按下Y键后,玩家就向前移动,同时也消耗了法力值。
                        
2.4剑气斩技能
        这样我们制作好了冲刺技能,接下来就要制作剑气斩技能,和刚刚一样,我们肯定是需要事件侦听器,实体存储,以及初始化的。我们选中这三个,将其复制一份。
                        
        然后分别修改名字为[事件侦听器]剑气斩、[全局存储]初始化剑气斩、[实体存储]剑气斩存储。
                        
                        
                        
然后打开[实体存储]剑气斩存储。修改变量名和自定义指令名字,并且将自定义指令中不需要的部分删除。
                        
然后打开[全局存储]初始化剑气斩,修改初始化的数值,并且修改设置自定义按键动作的动作ID。
                        
最后打开[事件侦听器]剑气斩,修改判断中的“冲刺”为剑气斩。
                        
        这些都是两个技能一样的部分。就不用了我一个个说明了,接下来,我们先来分析一下剑气斩的原理。游戏中,当我们按下“T”键时,会产生一个粒子特效,从玩家正前方,也就是Z轴方向飞出,而且,对应范围内的怪物也都应该要受到伤害。
                        
        所以我们先来制作粒子特效的部分,播放粒子特效只能在特定的位置播放一个特效,并不能实现移动的效果。而游戏逻辑中的粒子特效可以。那么我们是不是可以在玩家按下按键时,生成一个粒子特效并且移动它呢?
                        
        当然是可以的。首先我们先设置粒子特效使用的粒子为慢速效果,接着下边的属性是缩放,这个就是大小了。然后是透明度越小则粒子越透明。再下来是模拟速度,就是粒子效果的运行速度啦。接着是颜色和图像,这里可以对粒子进行一些细节上的修改。我们视频中的粒子使用的是自定义。
                        
        接着在次级粒子特效中点击编辑,然后使用左箭头。
                        
        然后修改颜色为黄色,当然这些组合大家都可以自己去试一试。
                        
        设置好粒子以后,不要忘记勾选有动画的,这个选项是针对一些动画指令,我们接下来会使用到,勾上以后,动画指令才能对齐生效。
                        
        大家还记得我们在刷新怪物系统中,我们使用了实体模板。那么游戏逻辑呢?当然也有游戏逻辑模板。我们放入地图后,先修改名字,然后使用吸管选择刚刚设置好粒子特效。
                        
        接着我们打开实体储存开始制作我们剑气斩的粒子特效吧。首先是生成指令,这次我们要选择的是生存游戏逻辑指令。而粒子特效是在玩家身上发出的,所以位置处填入存储拥有者的位置。
                        
        接着我们搜索移动至,这两天指令都可以将实体或者游戏逻辑移动到指定位置,而区别在于一个是时间,则是对象移动到指定位置需要的时间,另一个则是速度,则是移动对象时,对象的移动速度。而最后都一样的是平滑化,当为0时,物体做匀速运动,最大值为1,数值越大时,加速运动越明显。而这里使用那一条都是可以的,我们就选时间好了。
                        
                        
        其他几个空都没有什么问题,但是位置需要怎么确定呢?我们在刚刚说到了玩家本地坐标系。而剑气斩的粒子特效是在玩家身上,并往玩家正前方发出,也就是玩家本地坐标系中的Z轴方向发出的。那就很简单了,我们搜索偏移。这个指令就是针对玩家的本地坐标系的。我们只需要在偏移量中的Z轴填入15,得到的值就是玩家正前方,15个单位以外的坐标。
                        
        接着,当然粒子特效到达终点的时候,我们还需要删除它。我们在指令中设置了让粒子特效移动一秒,所以我们延迟一秒以后,删除这个粒子特效就可以了。这样剑气斩的动画部分就做完了,是不是十分简单呢?
                        
        接下来,我们就要制作这个技能的伤害部分了。我们再来思考一下原理,当粒子特效飞行时,对经过区域的玩家造成伤害。那么其实就是对一个会移动的区域中的实体造成伤害了。而游戏中,对于区域进行侦听的游戏逻辑就是触发区域了。我们只需要让触发区域跟随粒子特效移动,并且对进入区域的实体造成伤害就可以了呢?所以我再放置一个游戏逻辑模板和一个触发区域,并且修改触发区域的大小和粒子特效差不多,接着设置触发物为有标签的实体,而标签我们可以另外放置一个将对人都贴上这个标签。也可以选择经验值系统中的敌人标签。我们不要王佳勾选上有动画的选项,最后我们将触发区域存入游戏逻辑模板中。
                        
                        
        接着我们在生成粒子的同时生成这个触发区域,并且跟随粒子移动。当然,这里我们可以使用跟随指令,这个指令可以让一个对象,跟随着另一个对象移动,其中第一个和第二个分别是跟随对象和被跟随对象。第三个则是跟随对象和目标的相对偏移位置,也是本地坐标系的,而第四个则是是否开启这个偏移量。接着最大速度和加速度自然就是跟随对象的运动状态,我们这里想让他能完全跟随,那么这两个值自然是越大越好。
                        
        制作好了触发区域的移动,但是此时区域中没有写任何的逻辑,自然无法对实体造成伤害。不过打开游戏逻辑模板再写逻辑有些太麻烦了,以后找起来也不太好找。
我教大家一个新办法,事件侦听器不止可以侦听实体事件,还可以侦听游戏逻辑对象的事件。我们放置一个事件侦听器,修改侦听类型为游戏逻辑事件,触发对象为带标签的游戏逻辑,而事件选择进入区域时。
                        
        接着我们放置游戏逻辑标签,这个标签的作用和实体标签类似,不过针对的是游戏逻辑。
                        
        接着在生成触发区域时,添加该标签。
                        
        接着我们来到事件侦听器中,首先命中时,我们需要给予玩家一个反馈,所以先播放一个粒子特效,接着对实体造成伤害。我们店家实体、一般设定可以找到该指令。不过这个实体需要填入发起人和数量,其中发起人应该是玩家才对,而伤害数值也存在实体存储中,那要如果在这里实现呢?
                        
        其实也不难,对于实体有实体存储,游戏逻辑也有游戏逻辑存储,我们先放置一个游戏逻辑存储在地图中,接着修改名字为[游戏逻辑存储]剑气斩区域。
                        
接着打开存储,并在其中添加两个变量用于存储伤害数值和来源玩家。
                        
        接着回到创建触发区域的逻辑中,增加一个对触发区域的初始化,并将玩家和伤害数值传入其中。
                        
        这样,我们再到事件侦听器中就可以获取到玩家和伤害数值了。
                        
        制作完成后,不要忘记去书籍中,给玩家添加一下初始化哦!
                        
3、 技能冷却系统
制作完成了技能,现在就差技能冷却系统了。
                        
                还是按照惯例,我们先来分析一下技能冷却系统的原理,当释放技能时,将该技能加入技能冷却队列,接着展示对应的HUD。而在时间触发器中,需要判断该技能是否冷却完成,如果冷却完成,则移除技能冷却队列,并且修改相应的HUD。
                        
        那么我们先从加入技能冷却队列开始,那么加入技能冷却队列中,需要放入一些什么数据呢?首先是技能名字,然后还有技能冷却时间。最后还有一个时间戳,那什么是时间戳呢?时间戳就是一个固定的时刻,比如6:00这一个时刻,就可以当成是一个时间戳。而游戏中自然也有获取时间戳的方式,这个我们使用的时候再提起。按照表格中,时间触发器只需要判断当前的时间戳-技能冷却的时间戳大于技能冷却时间,就可以将技能移除队列。
                        
3.1技能冷却队列
        接着我们先放入需要使用到的逻辑,首先是时间触发器,需要用来判断冷却队列。为了判断准确,我们设置时间为最短间隔0.03S。
                        
        然后是全局存储和实体存储,分别用来初始化和存储数据。
                        
        接着先来到全局存储下边写初始化的函数,给玩家添加上储存。
                        
制作完成后,不要忘记去玩家角色中,给玩家添加上对应的存储呀!
                        
        然后我们先来制作获取时间戳的指令,我们运行,就可以找到总运行时间指令,使用该指令就可以获取到时间触发器的总运行时长,我在技能冷却时,获取一次总运行时间,然后再后期再用新的总运行时长判断就可以了。
                        
        最后打开实体储存,并在其中创建三个数组,分别为技能冷却名字,触发技能时间戳,技能冷却时间。
                        
        现在我们需要制作玩家使用技能时,将技能存入队列的函数。我们先放入一个函数模板,接着分别将技能名字、时间戳、冷却时长push进入三个数组中。
                        
        然后再分别打开两个释放技能的函数,将技能开始冷却函数接入释放技能函数中,并填入对应的参数。
                        
                        
        当我们在使用技能之前,我们还需要判断一下这个技能是否在冷却队列中,如果在的话,则无法使用技能。所以我们回到实体存储中,建立判断冷却函数,同时我们使用include的指令来判断冷却队列时候包含对应的技能。当包含时,则技能不再冷却,不包含时,则技能正在冷却。
                        
接着我们打开两个技能的事件侦听器,分别加入判断。
                        
                        
        按照步骤中,已经制作好了加入技能冷却队列,现在我们先忽略HUD,所以我们接下来要制作时间触发器中判断队列中技能是否冷却完成。
                        
        这个判断需要将数组中每个元素都进行判断,但是这里有三个数组,很显然不能使用数组循环,我们可以使用FOR循环来制作。
                        
        这个指令上边有一个参数和三个空格,其中第一个空格代表的是起始数组,也就是对应参数的数值。而第二个空格则是结束的数值,最后的步长为每循环一次后,参数增加的数值,当参数的数值大于等于结束数值时,则结束循环。而我们这里,只需要对数组中的数值进行判断,所以我们从数组的第一个索引0开始,到数组的长度结束即可执行数组中元素的对应次数。
                        
        接着我们先根据循环参数,获取到对应的时间戳和冷却时间,并通过判断语句,判断其是否还应该在冷却中。
                        
如果持续时间已经超过了技能冷却时间,则将对应的技能移除冷却队列。
                        
        不过这里有一些小问题,假设我们的第一个技能冷却完成了,而第二个技能还没有冷却完成,此时我们将第一个技能删除移除,那么第二个技能就来到第一个技能的位置。而循环参数依旧在增加,这样肯定是会出问题的。
                        
        所以我们此时可以重新运行一遍这个逻辑,并且在此处脱离本次的循环。
                        
        接着我们打开时间触发器,调用该指令,当然这里我们要对所有玩家都执行该指令,所以我们还是需要使用数组循环,而玩家数组可以新建一个,也可以使用法力值系统中使用的数组。
                        
        这样,技能冷却系统就完成了。
3.2动态修改冷却UI
        当然这只是逻辑部分,功能上的确已经实现了,但是我们还需要UI让玩家能明白自己的技能冷却还需要多少时间。我们先到创意工坊中,搜索冷却,可以找到一个已经上传好的HUD组件。
                        
放置在地图以后,打开HUD面板,我们什么都无法看见,
                        
        将右侧的选项勾上后,HUD才能显示,不过冷却面板只有在技能进入冷却时,才会显示,所以我们默认情况是需要关闭的,我们依旧将选项去掉。
                        
        将UI展开后,我们发现。每一条UI我们都需要修改的部件有开启节点,修改冷却条的填充量,修改技能文本。
                        
        而这些,我们也能列一个表,其中冷却队列中第一条和第一行冷却节点下的HUD对应,而第二条和第二行节点下的HUD对应。
                        
        既然如此,我们还需要三个数组保存这些数据,我们打开实体存储,再创建三个数组。
                        
        我们依旧之前学习的创建数据库的方式, 先创建初始化UI的函数。
                        
然后找到获取部件指令,将获取部件指令放入对象中,并将部件ID填入初始化UI的参数中,并修改对应的部件ID。而使用设置数组的参数替换push指令中的获取部件的部件ID。
                        
        打开全局储存你,调用初始化UI指令。这样就完成了UI数组的初始化。
                        
        接着,我们在技能冷却结束时和技能开始冷却时,都需要设置UI的开启和关闭,尤其是结束时,当第一个技能冷却时,我们要将第二行UI关闭,并将修改第一行的UI为新技能的冷却时间。
                        
        所以我们直接制作一个重新设置UI的函数,就可以解决这两个问题。首先我们使用数组循环将所有的UI节点都关闭
                        
        然后我们需要读取所有技能的冷却信息,所以我们需要选择for循环,将所有的有信息读取出来并存入本地变量中。
                        
        不过这里需要注意一个地方,我们的UI只有5个,当冷却技能超过5时就会出现问题,所以我们还需要设定一个最小值。当技能冷却名字数组大于5时,则只能获得5。
                        
最后我们设置获取的节点开启,并设置技能文本的技能名字,修改填充条的百分比。
                        
        然后将这个指令接入技能开始冷却和修改技能冷却中。
                        
        最后我们还剩下最后一步,就是随着时间流逝,技能的填充条开始消退。我们找到修改技能冷却指令中,在判断语句添加一个否则,当判断的技能还在冷却时,则计算填充条的百分比,并且设置对应的填充条。
                        
        对了,还需要判断一下此时判断的技能是否还有填充条可以使用,如果有才能设置填充条。
                        
        这样我们就完成了这个技能冷却系统。
4、 作业
制作一个新的技能:玩家攻击怪物时,能让怪物中毒,中毒状态持续5秒,每秒掉2点生命值,同时当怪物中毒期间玩家持续攻击怪物时,可以刷新怪物中毒的时间戳,并延长至被攻击的5秒后移除中毒状态。
                        



  • 主题

    1

  • 帖子

    4

  • 精华

    0

+加好友 查看TA的游戏
  • L0
  • 2

发表于:2020-4-29 01:17:03 5
这个中级教程80%的图片是模糊的,用什么积木看不清
  • 主题

    0

  • 帖子

    1

  • 精华

    0

+加好友 查看TA的游戏
  • L0
  • 2

发表于:2020-9-19 00:43:10 6
楼主大神,你发的图片好模糊看不清
  • 主题

    0

  • 帖子

    1

  • 精华

    0

+加好友 查看TA的游戏
  • L0
  • 2

发表于:2020-12-9 19:36:35 7
图片好不清晰啊。看不清啊。好难受啊

回复帖子

您需要登录后才可以回帖 登录 | 立即注册 登录

回帖 刷 新 回到顶部