【Godot4自学手册】第十六节敌人的攻击和主人公的受伤
各位同学大家好,前面我们学习了敌人的攻击动画,但是没有真正意义上实现攻击功能。今天我们将要学习敌人的攻击和主任的受伤功能的实现,其实原理很简单我们以前都学过,主要是给敌人添加一个Area2D子节点,这个结点用于与主任公发生碰撞达到进攻记录的目的;给主人公添加一个Area2D子节点用于接收敌人的进攻。开始吧。
各位同学大家好,前面我们学习了敌人的攻击动画,但是没有真正意义上实现攻击功能。今天我们将要学习敌人的攻击和主任的受伤功能的实现,其实原理很简单我们以前都学过,主要是给敌人添加一个Area2D子节点,这个结点用于与主任公发生碰撞达到进攻记录的目的;给主人公添加一个Area2D子节点用于接收敌人的进攻。开始吧。
一、敌人的进攻
1.结点布置。
在Enemy场景中添加Area2D结点,命名为HitBox,在该节点下添加CollisionShape2D结点,该节点用于敌人攻击与主任公发生碰撞的位置,在检测其中将Shape选择矩形碰撞,属性Disabled启用,这样的目的是禁用改碰撞默认启用,后面只有在敌人进攻的时候启用。
2.适当调整碰撞位置。
单击AnimationP结点,在动画面板中,选择Attack动画,切换到第七帧,根据动画调整HitBox到合适位置,整个过程如下:
3.停用启用碰撞
切换到动画面板,然后选择Attack动画,将播放位置拖到第一帧,然后在Hitbox子节点CollisionShape2D的检查器中,属性Disabled启用后单击后面的关键帧,这样会在动画第一帧中添加一个启用Disable的关键帧。如下:
同理,在Attack动画的第七帧添加一个不启用Disable的关键帧,在最后一帧添加启用Disable的关键帧,最终动画设置如下:
这样,只用敌人进攻时,碰撞才起作用。
4.修改代码
在Enemy代码中,完善代码一是翻转攻击碰撞HitBox,攻击框随着敌人的翻转而翻转;二是添加敌人攻击力。
攻击框翻转代码如下:
@onready var hit_box = $HitBox #获取攻击框
#chase_state函数中,hit_box.scale.x =-1翻转碰撞框
func chase_state():
anima.play("Run")
var direction = Globals.last_Player-global_position
if direction.x<0:
animaS.flip_h=true
hit_box.scale.x =-1
else:
animaS.flip_h = false
hit_box.scale.x=1
global_position = global_position.move_toward(Globals.last_Player,SPEED)
敌人攻击力代码简单的写一行,以后会逐步完善,代码如下:
var hitCount=2
目前,整个敌人的代码如下:
extends CharacterBody2D
enum {
IDLE,
CHASE,
ATTACK,
HURT,
DEATH
}
const SPEED = 1.0
var hitCount=2
@onready var anima = $AnimaP
@onready var animaS =$AnimaS
@onready var hit_box = $HitBox
var state = IDLE
func _physics_process(delta):
match state:
IDLE:
idle_state()
CHASE:
chase_state()
ATTACK:
attack_state()
HURT:
hurt_state()
DEATH:
death_state()
move_and_slide()
func idle_state():
anima.play("Idle")
func chase_state():
anima.play("Run")
var direction = Globals.last_Player-global_position
if direction.x<0:
animaS.flip_h=true
hit_box.scale.x =-1
else:
animaS.flip_h = false
hit_box.scale.x=1
global_position = global_position.move_toward(Globals.last_Player,SPEED)
func attack_state():
anima.play("Attack")
await anima.animation_finished
state = IDLE
await get_tree().create_timer(1).timeout
state = ATTACK
func hurt_state():
pass
func death_state():
pass
func _on_trace_area_body_entered(body):
if body.name=="Player" :
state = CHASE
func _on_trace_area_body_exited(body):
if body.name=="Player" :
state = IDLE
func _on_hit_area_body_entered(body):
if body.name=="Player" :
state = ATTACK
func _on_hit_area_body_exited(body):
if body.name=="Player" :
state = CHASE
二、碰撞层的设置
单击菜单栏中的项目,然后选择项目设置,在项目设置对话框中选择层名称->2D物理层,在第5层中输入HitEnemy,这个层用于与敌人发生碰撞。
进入Enemy场景选择HitBox结点,在检查器中Collision属性中将Layer设置为HitEnemy,Mask不进行设置,这样HitBox会位于HitEnemy层,为下一步碰撞做好准备。如下:
三、设置主人公受伤
1.搭建子节点。
进入Player场景,在跟场景添加Area2D结点,命名为HurtBox。为HurtBox添加子节点CollisionShape2D,形状选择胶囊碰撞,在检查器中Collision属性中将Layer不进行设置,Mask设置为HitEnemy,这样表示该节点与HitEnemy发生碰撞,设置如下:
2.设置受伤动画
进入主人公场景,选择AnimatedSprite2D结点,在动画帧控制面板中,新建两个动画一个是Hurt_Left,一个是Hurt_Right,操作如下:
然后单击从精灵表中添加帧,然后选择Playerer素材,在弹出的选择帧对话框中,水平设置4,垂直设为2,前两张图片添加到Hurt_Left动画,后两张图片添加到Hurt_Right动画,如下:
切换到AnimationPlayer结点,在检查器中单击导入按钮,将AnimatedSprite2D导入到该节点下,操作如下:
在动画面板中将Hurt_Left动画时长设置0.2,并调整动画帧到0.2秒内,如下:
同理,Hurt_Right进行同样设置。
切换到AnimationTree结点,在动画树面板中选择创建新节点按钮,命名为Hurt,然后单击后面的小笔图标。如下所示:
在Hurt面板内选择创建点按钮,然后在最左侧单击按钮选择添加动画->Hurt_Left,在最右侧添加Hurt_Right;最后选择混合模式选择离散模式,而不是连续模式。操作如下:
3.添加信号编写代码
在Player场景中,给Player结点添加Area2D结点,命名为HurtBox。给HurtBox结点添加CollisionShape2D子节点,检查器中shape中选择椭圆形碰撞结点,根据主人公调整大小。如下:
选择HurtBox结点,切换到信号,双击area_entered信号在弹出信号连接对话框中选择Player,单击链接按钮,操作如下:
切换Enemy代码,编写代码如下:
func _on_hurt_box_area_entered(area):
state=HURT #切换到HURT状态
enemyPositon = area.owner.global_position #敌人位置
func hurt_state():
var dir = enemyPositon.direction_to(global_position).normalized()
#判断攻击方向
anima_tree.set("parameters/Hurt/blend_position",dir.x)
anima_tree["parameters/playback"].travel("Hurt")
#播放受伤动画
if dir.x>0:
velocity.x +=10
else :
velocity.x -=10
#击退效果
await anima_tree.animation_finished
state=WALK
velocity = Vector2.ZERO
#动画播放完成后,人物状态切换到WALK状态,速度降为0
最终效果如下:
这节就到这,还有许多问题需要完善,我们下节完善吧。同学们,下次再见!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)