在笔者的一番观察之后,发现Enemy和Player间的主要区别还是体现在了脚本上,其余的部分的创建步骤基本是一致的,所以在这里就以脚本为主。
惯例,代码的主要结构:
可以看到这里除了MovingObject里提供的部分功能之外,还额外的处理了一些事情。我们还是按顺序的解释一下。
在Start()方法中:
我们除了获取了Player自己的动画器以外,同时还对UI中的文字进行了控制。
OnDisable()和OnTriggerEnter2D()都是MonoBehaviour提供的事件,
当我们在游戏关卡切换的时候,我们会将Player给Disable掉,这个时候就会触发OnDisable事件,在这里我们就是把最后的hp传递给GameManager,然后当下一关的Player创建的时候,便会从GameManager中获取上一关之后的hp继续游戏。
当Player在移动过程中,碰到了其它的碰撞体之后,便会根据这个碰撞体的tag来进行不同的处理(tag可以在unity的Inspector视图里面进行设置)。
对于Player的移动行为,我们是在Update()里面对用户的输入进行判断:
可以看到在这里,我们为了不让玩家能够斜着移动(因为这样和游戏的设计初衷就不一样了),所以当我们检测到有水平移动时,就会把垂直方向的移动归零。
Input.GetAxisRaw()是Unity提供的方法,用来获取轴向的输入,这样不管是键盘的方向键还是手机的加速器都可以作为一种输入方式被检测到。Input类里面还集成了很多其它的方法,用于获取各种输入的信息,详情请查询官方的文档。
在覆写的AttemptMove方法中:
我们每尝试移动一次都会消耗一点体力(hp、食物),同时修改了UI并且随机播放一种移动的声音。在移动结束之后会检查是否已经符合了结束游戏的条件(体力变成0),最后标记玩家回合结束、让电脑去控制敌方回合。
在OnCantMove中,我们将只处理和场地内墙的碰撞:
处理的方式就是让玩家做出挖掘的动作,一定次数的挖掘将使得场地内墙被摧毁。
Restart()方法中:
通过让引擎重新加载游戏场景的方式,重置游戏数据(不过笔者在这里没有调用过这个方法,主要原因是懒了,其实可以在GameManager的Update()中检测某个键的输入,如果检测到了就直接调用这个方法即可)
最后在CheckIfGameOver中,我们当检测到食物总数小于零之后将执行一些处理标志着游戏的结束:
至此MovingObject以及Enemy和Player我们就都讲完了。可以看到由于我们规定了MovingObject这个基类,所以使得在制作后面两种单位的时候减少了很多需要重复做的工作。
最后把做好的Enemy和Player从hierarchy视图拖入project视图中,会自动创建出prefab,这样尤其对于敌方单位来说,将更加便于批量创建。
下一篇文章将会讲解一下声音管理器(SoundManager)