[godot] 采用状态机时,如何处理攻击时移动?如“冲撞”

这里以'史莱姆撞击'为例子,将'空中跃进'定义为伤害帧。(见下图)

先梳理流程:a.史莱姆原地蓄力(起跳准备)--->b.跳起并移动一段距离(空中跃进)--->c.落地调整

当状态机进入'攻击状态'时,在enter()中设置起跳速度,并播放'a动画'。a动画播放期间,do()函数什么也不做。

a动画结束后,do()函数中开始执行move_and_slide()。

b动画不要用play()播放,而是手动控制动画帧:

在上升过程中,设置动画为"空中跃进-第1帧"

在下降过程中,设置动画为"空中跃进-第2帧"

当史莱姆落回地板时(is_on_floor),播放c动画,不再执行move_and_slide()。

c动画结束后,退出攻击状态,转到移动/待机状态

python 复制代码
#== gdScript
#== 攻击状态
var is_jump = 0 # 是否处于空中跳跃阶段
var to_end = 0 # 是否处于落地调整阶段
func enter():
	print("进入攻击状态")
	# 设置起跳速度
	chara.velocity.x = $"../Run".direct.x*40
	chara.velocity.y=-300
	$"../../AnimatedSprite2D".play("攻击准备")
func do():
	# 空中移动过程
	if is_jump==1:
		chara.velocity.y+=chara.gravity*0.01
		chara.move_and_slide()
        ## 可以在这里判断是否触碰到玩家并造成伤害

 
	# 空中移动动画
	if chara.velocity.y>=0&&to_end==0:
		$"../../AnimatedSprite2D".frame=1 # 下降期间动画
	# 落地
	if chara.is_on_floor()&&to_end==0&&is_jump==1:
		is_jump=0 # 不再移动位置
		to_end=1 # 该if块只执行一次
		$"../../AnimatedSprite2D".play("攻击结束")	
	
func exit():
	to_end=0 # 记得重置变量

func _on_animated_sprite_2d_animation_finished():
	# 若开启了"动画循环",则不会触发finished信号
	if $"../../AnimatedSprite2D".animation=="攻击准备": 
		is_jump=1 # 开始移动
		$"../../AnimatedSprite2D".animation="攻击过程"
		$"../../AnimatedSprite2D".frame=0 # 上升期间动画
	if $"../../AnimatedSprite2D".animation=="攻击结束":
		get_parent().change_state($"../Run") # 转移到移动状态

关键是对攻击进一步细分

相关推荐
mxwin1 天前
Unity Shader 半透明物体为什么不能写入深度缓冲?
unity·游戏引擎·shader
晚枫歌F1 天前
三层时间轮的实现
网络·unity·游戏引擎
努力长头发的程序猿1 天前
Unity使用ScriptableObject序列化资源
unity·游戏引擎
mxwin1 天前
Unity Shader 手写基于 PBR 的 URP Lit Shader 核心光照计算
unity·游戏引擎·shader
魔士于安1 天前
Unity windows 同步 异步 打开文件文件夹工具
游戏·unity·游戏引擎·贴图·模型
笑虾1 天前
cocos2d-x lua 加载 Cocos Studio 导出的 csb
游戏引擎·lua·cocos2d
魔士于安1 天前
unity lowpoly 风格 城市 建筑 道路 交通标志
游戏·unity·游戏引擎·贴图·模型
mxwin1 天前
Unity GPU Shader 性能优化指南
unity·游戏引擎·shader
董董女友2 天前
unity mcp 配置指南
unity·游戏引擎
垂葛酒肝汤2 天前
Unity的可视化网格和文字标签
unity·游戏引擎