[ 分享 ]11.HITBOXES AND KNOCKBACK(受击盒和击退)
本系列是油管上的HeartBeast的[Beginner] Make an RPG课程的中文笔记,主要形式是截图的方式进行步骤上的说明。面向对象:GameMaker新手,以学习一门脚本编程语言,制作一个RPG游戏为目标的爱好者。
在上一节当中已经做到了攻击状态和移动状态的切换,但实际上攻击的效果, 并没有得到实现,在这一节当中,将实现以下效果:
- 将攻击到的敌人击退
- 并扣除敌人的HP1点
创建精灵spr_damage,设置大小为24*24
然后使用笔刷工具,绘制一个黑色圆形,来示意攻击的范围,实际上可以将其称为“技能特效”。
设置原点中心在middle center的位置。(12*12)
创建obj_damage,并选中spr_damage作为它的精灵
实现击退的效果,是利用创建一个Obj对象,obj会对碰撞的其他对象施加一个力的作用,使其“被击退”,所以在此先创建一个对象
回到obj_life_parent的事件中,初始化生命体的HP属性
在“生命体”对象的create事件中,创建hp变量并赋值为3
注意玩家对象obj_player和obj_enemy_slime对象同样继承了该属性(在create事件中使用了event_inherited()),如果想要更改玩家的对象的血量为20,只需要在obj_player的create事件中,对变量hp重新赋值即可,但必须在event_inherited()语句后面,否则继承的父物体的赋值将会覆盖你前面的赋值,所以一般继承函数会放置在整段代码的最上方。
生命值归0,销毁生命体实例
常见的,HP归0,生物死亡需要进行销毁,节省内存。在destroy事件中实现。
对碰撞的物体“实施伤害”
创建obj_damage与生命体的碰撞事件
在攻击时,创建“实施伤害”的obj_damage
现在obj_player的create事件中,初始化attacked变量来标记攻击状态。
为什么要创建这个attacked变量呢,是因为碰撞事件是每帧都会进行检测的,如果不使用这个状态变量来控制,就会每帧都扣除碰撞到的对象1点HP,这显然不是我们的想要的效果,我们想要的效果,是“1次攻击只造成1次伤害”。
然后在scr_attack_state脚本中,来创建obj_damage。
同样的在从攻击动作切换回movestate时,需要重新将attacked变为false来准备下一次的创建damage对象。
修复玩家实例不存在的BUG
一般的,在引用任何对象的属性前,都必须判断对象实例是否存在,因为一旦GMS2进行索引的对象实例不存在,将会导致游戏崩溃,不存在就不索引,并且报出Debug信息。
在引用obj_view里引用obj_player的变量属性前,先对obj_player的实例判断是否存在
同样的,修正在obj_enemy_slime里的代码
由于这时obj_damage是对lifeform的碰撞,所以也会对玩家对象obj_player造成伤害
初始化obj_damage变量属性
这里将obj_damage造成的伤害和击退距离以变量的形式储存起来,方便以后的修改。
在step事件中引用伤害变量
添加obj_damage销毁代码
创建计时器变量
在计时器事件中进行实例销毁
修复damage实例对玩家player实例的伤害
在scr_attack_state创建damage对象的代码中,排除攻击者自身。(即obj_damage不是对所有对象实例造成伤害,这里要筛选掉自己。)
在创建damage对象后,马上对damage对象进行赋值。
创建击退效果
在damage的碰撞事件中,对碰到的物体实施击退,应用的是物理引擎的“冲击力”效果,physics_apply_impulse.
通过设置史莱姆的物理属性,来优化调整击退效果(击退距离)
将史莱姆的Linear Damping线性阻尼由0.1改为5,该阻尼值越高,移动时,需要的力就越大
修正obj_damage的创建位置
现在的代码是把obj_damage对象创建在自己的位置上,而正确的需求是将其创建在打击特效上,但是需要根据人物的打击的方向,将其放置在不同的位置上,所以针对四个不同的方向,使用switch语句来修正创建对象的x,y坐标
修正方向错误的问题
在施加击退冲击力时,方向应该是调用攻击脚本的实例位置和碰撞位置两点的矢量方向,而不是damage和碰撞到实例连线矢量方向
最后将obj_damage设置为隐藏
将visible设置勾选掉,当然如果有动画资源,而可以在创建obj_damage后设置它的精灵动画,作为打击特效或者受击特效处理