本文最后更新于42 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
初步构思:角色在防御状态时血条右边应出现一个小盾牌,如果是点击防御减免50%伤害,在此防御回合之内一个小盾牌即可。如果是防御增加n防御值(额外血条)还应该显示数字。
这个盾牌图标应当有小动画,如淡入淡出甚至被打抖动以及“碎盾”图标等,在此处用tween,用代码控制动画。
| 特性 | Tween | AnimationPlayer |
| 代码控制 | 强 | 弱(需配合Animation资源) |
| 简单动画 | 方便 | 需要创建资源 |
| 复杂动画 | 代码复杂 | 可视化编辑方便 |
| 动态生成 | 容易 | 困难 |
| 学习曲线 | 低 | 中等 |
Godot的Tween系统非常适合程序化生成的简单动画、UI过渡效果、游戏对象的平滑移动等场景。对于复杂的、需要反复调整的动画,建议使用AnimationPlayer;对于需要代码动态控制的简单动画,Tween是更轻量、灵活的选择。
核心优势:无需创建动画资源文件,直接在代码中定义,特别适合需要根据游戏逻辑动态调整参数的动画场景。
小盾牌特效(defense indicator):
在battle_scene里如果进入到防御状态则显示,若无则隐藏
## 显示指示器
func show_indicator() -> void:
visible = true
# 添加简单的小动画效果
scale = Vector2.ZERO # 先设置为 0(不可见)
var tween = create_tween()
tween.tween_property(self, "scale", Vector2.ONE, 0.3).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
# 然后在 0.3 秒内从 0 缩放到 1(正常大小),带弹性效果
## 隐藏指示器
func hide_indicator() -> void:
if not visible:
return
var tween = create_tween()
tween.tween_property(self, "scale", Vector2.ZERO, 0.2).set_ease(Tween.EASE_IN)
# 然后在 0.2 秒内从 1 缩放到 0(隐藏),带弹性效果
tween.tween_callback(set_visible.bind(false))
# 通过 tween_callback 确保在动画结束后才隐藏,避免动画还没播完就消失
Tween动画常用代码段:
create_tween()方法是更现代的方式,无需预先添加节点
tween_property() – 核心动画方法
tween.tween_property(
object, # 要动画的对象
property, # 属性名(字符串)
final_val, # 目标值
duration, # 持续时间(秒)
# 可选参数:
# trans_type: 过渡类型(如Tween.TRANS_LINEAR)
# ease_type: 缓动类型(如Tween.EASE_IN)
# delay: 延迟开始时间
)
2. 常用过渡类型(trans_type)
Tween.TRANS_LINEAR:线性(匀速)
Tween.TRANS_SINE:正弦曲线
Tween.TRANS_QUAD:二次方
Tween.TRANS_CUBIC:三次方
Tween.TRANS_ELASTIC:弹性效果
Tween.TRANS_BOUNCE:弹跳效果
3. 常用缓动类型(ease_type)
Tween.EASE_IN:开始慢,结束快
Tween.EASE_OUT:开始快,结束慢
Tween.EASE_IN_OUT:开始和结束都慢
Tween.EASE_OUT_IN:开始和结束都快
tween.tween_property(...) # 动画1
tween.tween_property(...) # 动画2(在动画1结束后开始)
tween.parallel().tween_property(...) # 与上一个动画同时开始
# 动画完成时触发
tween.finished.connect(_on_animation_finished)
# 或使用链式方法
tween.tween_callback(func(): print("动画完成!"))
伤害数字飘字(damage number):
在battle_scene或者character里处理,攻击方执行攻击之后在被攻击方的左上或者右上显示伤害飘字
func _process(delta: float) -> void:
if time_elapsed < float_duration:
# 向上漂浮并渐变淡出
position.y -= float_speed * delta
label.modulate.a = lerp(1.0, 0.0, time_elapsed / float_duration) # 从 1 到 0 渐变
time_elapsed += delta
else:
# 动画完成后自动销毁
queue_free()
func show_number(text: String, color: Color = Color.WHITE) -> void:
label.text = text
label.modulate = color
time_elapsed = 0.0
