Godot游戏练习01-第15节-敌人生成动画,翻转,碰撞

今天来优化敌人, 逐步补充细节, 之前实现的敌人只会简单追踪Player, 现在给敌人添加生成动画和一些优化内容, 让敌人也更生动一些

看看效果

  1. 出生时的缩放动画
  2. 追击玩家时自动切换方向
  3. 敌人之间有碰撞, 不会完全重叠

看这个左右瞅的小眼神, 竟然还有点可爱, 哈哈哈

实现过程

先修改一个小问题: 当Host主机等到倒计时为0的时候Client加入, 会产生一个错误

plaintext 复制代码
E 0:00:20:053   enemy_spawn_component.gd:86 @ _synchronize(): Time should be greater than zero.

在设置wait_time的时候值必须大于0, 修改timer计时同步的源码, 稍加过滤即可

gdscript 复制代码
@rpc("authority", "call_remote", "reliable")
func _synchronize(data: Dictionary) -> void:
	round_count = data.round_count
	var wait_time: float = data.round_timer_time_left
	if wait_time > 0:
		round_timer.wait_time = wait_time
	if data.round_timer_running:
		round_timer.start()

敌人之间的碰撞

这个最简单了

打开敌人场景enemy.tscn, 调整根节点的碰撞层级, 将层级2设置为敌人碰撞层, 在CollisionLayer中, 将Layer的2层选中, 在Mask中也选中2层

代表以下含义

  • 敌人在敌人碰撞层, 2层
  • 敌人检测来自2层的碰撞, 同时检测来自1层的碰撞(空气墙壁层)

生成动画

生成动画使用Tween实现, 这是一个制作简单动画的强大神器, 今天也算是学到一点新内容

如果希望掌握Tween的使用, 应该搜索相关资料全面学习, 特别是ease/trans组合的不同效果

gdscript 复制代码
func _play_spawn_animation() -> void:
	is_spawning = true
	var tween := create_tween()
	tween.tween_property(visual, "scale", Vector2.ONE, 0.4)\
		.from(Vector2.ZERO)\
		.set_ease(Tween.EASE_OUT)\
		.set_trans(Tween.TRANS_BACK)
	tween.finished.connect(func():
		is_spawning = false
	)

create_tween()是Node节点提供的内置方法, 以下是官方文档

Creates a new Tween and binds it to this node.

This is the equivalent of doing:

get_tree().create_tween().bind_node(self)

The Tween will start automatically on the next process frame or physics frame (depending on Tween.TweenProcessMode). See Tween.bind_node() for more info on Tweens bound to nodes.

Note: The method can still be used when the node is not inside SceneTree. It can fail in an unlikely case of using a custom MainLoop.

该函数相当于 get_tree().create_tween().bind_node(self)

表示创建一个tween对象, 并且绑定当前节点, 它的动画会在下一帧自动开始

绑定的效果是, 在当前节点释放时, tween对象也会自动释放, 与节点同生命周期

我们在_ready()生命周期中调用_play_spawn_animation(), 就实现了敌人出生时播放一个从小变大的动画

这里添加了一个is_spawning标志位, 表示敌人是否正在生成, 如果正在生成, 我们不希望敌人在生成过程中就开始移动

因此, process中也增加了额外判断, 仅当敌人不在生成过程中时, 才允许移动

gdscript 复制代码
func _process(_delta: float) -> void:
	if is_multiplayer_authority() and not is_spawning:
		if has_track_target:
			velocity = global_position.direction_to(track_target) * 40
			move_and_slide()
	if not is_spawning:
		_update_direction()

方向自动翻转

上面的_update_direction()调用就是自动翻转, 具体源码如下, 与之前Player的翻转一样, 依据目标方位在自己的左右侧来调整scale达到翻转效果

gdscript 复制代码
func _update_direction() -> void:
	visual.scale = Vector2.ONE\
		if track_target.x > global_position.x\
		else Vector2(-1, 1)

为了让翻转在所有peer上同步生效, 我们在process中并没有限制authority, 并且在Enemy的MultiplayerSynchronizer中新增了track_target的同步, 方便_update_direction()的效果在所有peer上一致

现在再回过头看看最开始的版本, 增加了细节之后确实看起来细致很多了

这里也引出一个问题: 我们判断敌人是否在生成中, 增加了标志位, 若以后还要判断敌人是否在攻击中, 是否有什么状态, 若不断增加标志位, 这里的逻辑将会变得稀烂

下一次我们就来学习状态管理利器: 状态机的使用

相关推荐
资源分享助手14 小时前
我!勇者?The Warrior免安装中文版下载与玩法体验
游戏
云起SAAS16 小时前
抖音小游戏源码 - 消消乐 | 含激励广告+成就系统 | 开箱即用商业级消除游戏模板
android·游戏·广告联盟·看激励广告联盟流量主·抖音小游戏源码 - 消消乐
那个村的李富贵17 小时前
Unity自适应文本提示框:从原理到实战
unity·游戏引擎
津津有味道17 小时前
一键写入启动游戏NDEF复合记录NFC标签vb6源码
游戏·标签·nfc·ndef·复合记录
WarPigs17 小时前
Unity人物翻越功能
unity·游戏引擎
游乐码17 小时前
Unity基础(四)向量相关
游戏·unity·游戏引擎
VT LI19 小时前
Cocos2d-x 引擎架构全面深度解析:从底层渲染到上层交互的系统性技术全景
游戏引擎·cocos·引擎架构
阿阳微客19 小时前
网易Buff游戏搬砖,长期可做!
笔记·学习·游戏
Kurisu57520 小时前
探灵直播2026最新官方正版免费下载 一键转存 永久更新 (看到速转存 资源随时走丢)
游戏·游戏引擎·游戏程序·动画·关卡设计
神码编程20 小时前
【Unity】MiniGame编辑器小游戏(十五)中国象棋局域网对战【Chinese Chess】(上)
unity·编辑器·游戏引擎·小游戏