引入阵营
下面,我们先为人物引入阵营:
- 新建列表:人物阵营,用于存放每个人物的阵营。
- 将放置人物的自制积木添加一个“阵营”参数,并在放置人物时将阵营加入列表:
- 这样,放置人物时,就可以填写人物的阵营:
将玩家的处理一般化
在前面的教程中,关于玩家的相关处理(比如击中检测、血量扣除、血条跟随)都做了特判处理。这是因为玩家的血量、坐标等信息没有存到列表中,导致玩家和一般敌人处理方式不一样。 为了统一玩家和敌人的处理方式,方便之后编写统一的代码,需要将玩家的相关数据转移到列表中储存。可以用人物列表的第一项专门存放玩家信息:
- 首先,在“人物”角色中,在清空人物列表后,将玩家的信息加到列表第一项:(阵营可填“我”,表示我方)
- 为 AI 人物新建私有变量“目标敌人编号”,表示当前 AI 人物正在攻击的敌人编号。由于现在所有的 AI 只攻击玩家,“目标敌人编号”暂时固定为 1(玩家信息在第一项,因此玩家编号就是 1):
- 来到“人物武器”角色,同样新建私有变量“目标敌人编号”,存放武器锁定的敌人:
- 来到子弹角色,将检测击中敌人的代码修改如下:子弹在检测是否击中敌人时,需要判断对方和自己的阵营不一样,才能击中对方(不然就会出现击中友军,甚至自己的子弹击中自己的情况)
- 来到血条角色,所有关于玩家的特判代码也可以直接移除:
- 回到玩家角色,将血量相关变量全部用列表替换,并设置玩家的阵营为“我”
- 来到玩家武器,将读取玩家血量代码进行替换:
为了避免混乱,可以把初始化数据单独做成一个自制积木:
放置人物的代码中,如果是玩家,就不克隆自己,仅添加列表数据
然后,将人物代码修改如下:如果攻击的目标死亡,就将目标设为空;如果没有攻击目标,就不执行动作:
接着,将之前敌人锁定玩家的代码,全部替换为“目标敌人”:
将武器中,计算到玩家的距离,改成计算到编号 n 的人物的距离:
将近战武器代码中,原来锁定玩家的代码做如下修改:
将远程武器代码中,面向玩家的代码改成面向目标的代码:
由于现在人物增加了阵营的属性,子弹的阵营改为根据人物阵营决定:
(由于玩家的信息也转移到了列表中,之前关于玩家的特判代码可以移除)
子弹扣除血量的代码,可以直接移除玩家特判的部分:
医疗包中,修改玩家血量的代码,替换为修改列表:
(注:设置列表的代码要放在“等待 0 秒”后,避免初始化时列表被清空,设置的内容丢失)
玩家死亡后,将自己的编号(也就是 1)从存活列表中移除:
玩家在循环中,重复上传自己的位置、方向信息到列表:
将玩家生成血条的代码,如下改为“1”(玩家跟随的人物编号,玩家在列表第一项,所以填 1)
将武器发射的子弹的阵营,替换为玩家的阵营:
这样,我们就完成了对玩家的一般化! 再次运行游戏,虽然看起来似乎没什么变化,但是玩家的处理和敌人的处理得到了统一,以后编写的代码就更加简化;同时,敌人锁定的目标使用了变量记录,可以通过修改变量,来改变敌人锁定的目标。 一个可以发现的小细节就是:火箭筒的爆炸伤害能够伤害玩家了。这正是因为玩家和敌人被统一处理了(之前爆炸伤害没有特判玩家,玩家不会受到爆炸伤害)
补充:更“一般化”的做法
一个让玩家更一般化的做法,是把玩家直接作为“人物”的一部分,即和其他敌人一起被克隆,而不是单独的角色。这样,玩家和敌人就可以共享很多代码。 《逃离物理卷》就是这么处理的,事实上,《逃离物理卷》的所有人物、武器、子弹等等都被整合到了一个叫“物体”的角色中,这样他们就可以最大限度共享代码、变量、造型等各种内容。
把玩家和敌人甚至一切实体都合并成一个角色有好有坏:
- 坏处是,代码被集中在同一个角色,会让这个角色比较臃肿(比如“物理卷”单个角色 9k+ 代码,容易导致编辑器卡顿……),而且各种物体的代码全集中在一个角色中,可能会让代码变得有点混乱;
- 好处是,人物、子弹、武器被合并到一个角色后,可以共享很多代码(例如“移到大地图正确位置”、“图层排序”、“计算两点距离”这些通用代码,如果分开角色,就需要在每个角色中都出现一遍,而且万一代码需要更新,这些角色的代码就需要都改一遍,不利于维护)
不过考虑到 Gandi 编辑器支持全局积木,分角色时,同样的代码就不需要每个角色都复制一次,而是统一放到一个全局模块中进行修改。
tip:教程中主要介绍的是原版的写法,所以没有介绍全局积木,如果想了解全局积木的用法可以看这篇文章:
<iframe
width="100%"
height="800px"
scrolling="no"
src="https://www.ccw.site/embed?id=STG202/Arkos/Lec8/02&type=comment"
title="{射击中级-8-02-将玩家一般化}"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
scrolling="0"
></iframe>