【Godot】时间线(技能)节点

news/2025/1/13 8:03:16/

4.1

游戏中一般都会有各种各样的技能,或者其他需要按一定的时间顺序去执行的功能。

这里我写出了一个时间线节点,就像是在播放动画一样,按一定的阶段去执行某些功能

#============================================================
#    Timeline
#============================================================
# - author: zhangxuetu
# - datetime: 2023-09-24 23:10:53
# - version: 4.1
#============================================================
class_name _TimeLine
extends Node## 执行完这个阶段时发出这个信号
signal executed_stage(stage, data)
## 手动停止执行
signal stopped
## 暂停执行
signal paused
## 继续执行
signal resumed
## 执行完成
signal finished## process 执行方式
enum ProcessExecuteMode {PROCESS, ## _process 执行PHYSICS, ## _physics_process 执行
}enum {UNEXECUTED, ## 未执行EXECUTING, ## 执行中PAUSED, ## 暂停中
}## 时间阶段名称。这关系到 [method execute] 方法中的数据获取的时间数据
@export var stages : Array = []
## process 执行方式。如果设置为 [member PROCESS][member PHYSICS] 以外的值,
## 则当前节点的线程将不会执行
@export var process_execute_mode : ProcessExecuteMode = ProcessExecuteMode.PROCESSvar _last_data : Dictionary
var _point : int = -1:set(v):if _point != v:_point = vif _point >= 0 and _point < stages.size():self.executed_stage.emit(stages[_point], _last_data)
var _time : float
var _execute_state : int = UNEXECUTED:set(v):if _execute_state == v:return_execute_state = vmatch _execute_state:UNEXECUTED:set_process(false)set_physics_process(false)EXECUTING:if process_execute_mode == ProcessExecuteMode.PROCESS:set_process(true)elif process_execute_mode == ProcessExecuteMode.PHYSICS:set_physics_process(true)PAUSED:set_process(false)set_physics_process(false)func _ready():set_process(false)set_physics_process(false)func _process(delta):_exec(delta)func _physics_process(delta):_exec(delta)func _exec(delta):_time -= deltawhile _time <= 0:_point += 1if _point < stages.size():_time += _last_data[stages[_point]]else:_point = -1_execute_state = UNEXECUTEDself.finished.emit()breakfunc get_time_left():return _timefunc get_last_data() -> Dictionary:return _last_datafunc get_last_stage():return stages[_point]## 执行功能。这个数据里需要有 [member stages] 中的 key 的数据,且需要是 [int][float]
## 类型作为判断执行的时间。否则默认时间为 0
func execute(data: Dictionary):_last_data = data_time = 0_point = 0if not stages.is_empty():_execute_state = EXECUTINGfor stage in stages:_last_data[stage] = float(data.get(stage, 0))# 执行时会先执行一下_time = _last_data[stages[0]]_exec(0)else:printerr("没有设置 stages,必须要设置每个执行的阶段的 key 值!")## 获取执行状态
func get_execute_state():return _execute_state## 是否正在执行
func is_executing():return _execute_state == EXECUTING## 停止执行
func stop():if _execute_state == EXECUTING:_execute_state = UNEXECUTEDself.stopped.emit()## 暂停执行
func pause():if _execute_state == EXECUTING:_execute_state = PAUSED## 恢复执行
func resume():if _execute_state == PAUSED:_execute_state = EXECUTINGself.resumed.emit()## 跳跃到这个阶段
func goto(stage, emit_stage_changed_signal: bool = true):if _execute_state == EXECUTING:if stages.has(stage):_point = stage_time = 0if emit_stage_changed_signal:self.executed_stage.emit()else:printerr("stages 中没有 ", stage, ". 所有 stage: ", stages)

这里我进行添加整个时间中有哪些阶段,我想一个技能需要有下面几个阶段:

start(开始执行功能,一般用于判断这个条件下是否可以进行执行这个功能,以便进行功能的打断等操作);before 执行功能时的施放动作前摇;execute 具体执行出的功能;after 执行功能后的动画结束;refresh 技能刷新阶段。

这是我的理解,可以自行随意设计。

下面的代码我创建了只有一个 Node2D 作为根节点的场景,进行测试

#============================================================
#    Time Line Test
#============================================================
# - author: zhangxuetu
# - datetime: 2023-09-24 21:51:11
# - version: 4.1
#============================================================
extends Node2Dvar timeline = _TimeLine.new()func _ready():timeline.stages = [&"start", &"before", &"execute", &"after", &"refresh"]add_child(timeline)timeline.executed_stage.connect(_executed_stage)timeline.execute({"name": "技能名称",&"start": 0,&"before": 0.4,&"execute": 0.2,&"after": 0.2,&"refresh": 3,})func _executed_stage(stage, data):match stage:&"start":print("   开始执行: ", data["name"])&"before":print("   播放动作")# 临时修改执行时间,延长或缩短时间data[&"execute"] = 2&"execute":print("   实际执行功能,这里写这个阶段要做的事情")&"after":print("   已经执行完功能,进行后续结束动作")&"refresh":print("   ", data["name"], " 结束动作完成,开始进行倒计时刷新")

这里我在执行这个技能的时候,传入上面各个阶段所需要的时间的数据,然后在 executed_stage 信号中进行判断各个阶段所需要处理的功能。

这样一个技能节点即可完成,使用时调用 execute 方法即可


http://www.ppmy.cn/news/1142142.html

相关文章

docker 的数据管理

docker 容器中数据主要有两种方式 数据卷&#xff08; Data Volumes &#xff09; 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录往载到数据卷上&#xff0c;对数据卷的修改操作立刻可见&#xff0c;并且更新数据不会影响镜像&#xff0c;从而实现…

Mac mov转mp4,详细转换步骤

Mac mov转mp4怎么转&#xff1f;视频文件格式为.mov是由Apple公司所开发的特殊格式。因其只能在苹果设备上播放&#xff0c;与他人分享时就会变得困难。为此&#xff0c;我们通常会选择使用MP4这种最受欢迎的视频格式。在日常使用中&#xff0c;MP4成为了大家首选的视频格式。而…

Tomcat 介绍与 jspgou 部署

一、虚拟机简介 1、Java 虚拟机 (1) 虚拟机&#xff1a; 虚拟机&#xff08;Virtual Machine&#xff09;是一种软件或硬件实体&#xff0c;它模拟了一个独立的计算环境&#xff0c;可以在其上运行应用程序。 虚拟机可分为系统虚拟机和程序虚拟机&#xff1a; ● 系统虚拟…

python:xlwings 操作 Excel 加入图片

pip install xlwings ; xlwings-0.28.5-cp37-cp37m-win_amd64.whl (1.6 MB) 摘要&#xff1a;Make Excel fly: Interact with Excel from Python and vice versa. Requires: pywin32 编写 xlwings_test.py 如下 # -*- coding: utf-8 -*- """ xlwings 结合 …

HashMap 1.7 和 HashMap 1.8 的区别?

不同点HashMap 1.7HashMap 1.8数据结构数组链表数组链表/红黑树插入数据的方式头插法尾插法hash 值计算方式9次扰动处理(4次位运算5次异或)2次扰动处理(1次位运算1次异或)扩容策略插入前扩容(只要不小于阈值就直接扩容2倍)插入后扩容 (当数组容量未达到64时&#xff0c;以2倍进…

【算法分析与设计】回溯法(下)

目录 一、符号三角形问题二、N皇后问题三、0-1背包问题四、最大团问题4.1 进一步改进 五、图的m着色问题5.1 算法设计六、旅行售货员问题七、连续邮资问题八、回溯法效率分析九、重排原理十、回溯法的效率分析十一、Monte Carlo方法附一、四后问题的搜索树附二、随机选择路径附…

Linux程序崩溃时的信号量(signal)说明

一、概念说明 在程序崩溃的时候&#xff0c;我们将会获取到两个信息: • signal: 信号量&#xff0c;下文将会详细的说明不同的信号量及其含义 • code: 错误码, 除了几个所有信号量(signal) 公共的错误码(code)&#xff0c;一般不同信号量(signal)有特定的错误码(code)&#x…

【JavaEE】JavaScript webAPI的基本知识

JavaScript Web API 文章目录 JavaScript Web APIwebAPI背景DOMDOM树 获取元素querySelectorquerySelectorAll 事件初识键盘事件onkeydownonkeypressonkeyup 操作元素获取/修改元素内容1.innerText2.innerHTML 获取/修改元素属性获取/修改表单元素属性获取/修改样式属性行内样式…