robotengine.node
节点是 RobotEngine 的构建模块。它们可以被指定为另一个节点的子节点,从而形成树状排列。一个给定的节点可以包含任意数量的节点作为子节点,要求所有的兄弟节点(即该节点的直接子节点)的名字唯一。
当由节点组成的节点树被挂载到 Engine 中时,将会从子节点开始,依次执行每个节点的初始化程序 _init() 和 _ready(),注意 _init() 将会在 _ready() 之前被调用。
在节点的 _ready() 函数被调用后,将会触发节点中的 ready 信号。
节点可供覆写的弱定义函数有:
def _init() -> None:
# 初始化函数,在节点的 _ready() 函数被调用前被调用,尽量不要覆写此函数。
pass
def _ready() -> None:
# 节点 _ready 函数,会在 _init() 之后被调用,可以在此函数中执行一些初始化操作。
pass
def _process(delta) -> None:
# 节点 process 函数,会根据 Engine 中设置的 frequency 进行连续调用。
pass
def _input(event: InputEvent) -> None:
# 节点 input 函数,会在接收到输入事件时被调用。
pass
节点的 process 函数会根据 Engine 中设置的 frequency 进行连续调用,当节点的 process_mode 为 ProcessMode.PAUSABLE 时,当 Engine.paused 为 True 时,节点的 process 函数将不会被调用。
1""" 2 3节点是 RobotEngine 的构建模块。它们可以被指定为另一个节点的子节点,从而形成树状排列。一个给定的节点可以包含任意数量的节点作为子节点,要求所有的兄弟节点(即该节点的直接子节点)的名字唯一。 4 5当由节点组成的节点树被挂载到 Engine 中时,将会从子节点开始,依次执行每个节点的初始化程序 _init() 和 _ready(),注意 _init() 将会在 _ready() 之前被调用。 6 7在节点的 _ready() 函数被调用后,将会触发节点中的 ready 信号。 8 9节点可供覆写的弱定义函数有: 10 11 def _init() -> None: 12 # 初始化函数,在节点的 _ready() 函数被调用前被调用,尽量不要覆写此函数。 13 pass 14 15 def _ready() -> None: 16 # 节点 _ready 函数,会在 _init() 之后被调用,可以在此函数中执行一些初始化操作。 17 pass 18 19 def _process(delta) -> None: 20 # 节点 process 函数,会根据 Engine 中设置的 frequency 进行连续调用。 21 pass 22 23 def _input(event: InputEvent) -> None: 24 # 节点 input 函数,会在接收到输入事件时被调用。 25 pass 26 27节点的 process 函数会根据 Engine 中设置的 frequency 进行连续调用,当节点的 process_mode 为 ProcessMode.PAUSABLE 时,当 Engine.paused 为 True 时,节点的 process 函数将不会被调用。 28 29""" 30 31from enum import Enum 32from typing import List 33from robotengine.tools import warning, error 34from robotengine.signal import Signal 35 36 37class ProcessMode(Enum): 38 """ 节点的process模式,PAUSABLE为默认模式 """ 39 PAUSABLE = 0 40 """ 当 Engine.paused 为 True 时,节点的 process 函数将不会被调用 """ 41 WHEN_PAUSED = 1 42 """ 只有当 Engine.paused 为 True 时,节点的 process 函数才会被调用 """ 43 ALWAYS = 2 44 """ 节点的 process 函数将始终被调用 """ 45 DISABLED = 3 46 """ 节点的 process 函数将永远不会被调用 """ 47 48class Node: 49 """ Node 基类 """ 50 from robotengine.input import InputEvent 51 52 def __init__(self, name="Node"): 53 """ 54 初始化节点 55 56 :param name: 节点名称 57 """ 58 self.name = name 59 """ 节点名称 """ 60 self.owner = None 61 """ 62 节点的所有者 63 64 注意:owner的指定与节点的创建顺序有关,例如: 65 66 A = Node("A") 67 B = Node("B") 68 C = Node("C") 69 D = Node("D") 70 71 A.add_child(B) 72 A.add_child(C) 73 B.add_child(D) 74 75 此时,A的子节点为B、C,B的子节点为D,B、C、D的owner均为A。 76 77 而如果继续添加节点: 78 79 E = Node("E") 80 E.add_child(A) 81 82 此时,E的子节点为A,A的owner为E,但是B、C、D的owner仍然为A。 83 """ 84 self._children = [] 85 self._parent = None 86 87 # 全局属性 88 from robotengine.engine import Engine 89 from robotengine.input import Input 90 91 self.engine: Engine = None 92 """ 节点的 Engine 实例 """ 93 self.input: Input = None 94 """ 节点的 Input 实例 """ 95 96 self.process_mode: ProcessMode = ProcessMode.PAUSABLE 97 """ 节点的process模式 """ 98 99 # 信号 100 self.ready: Signal = Signal() 101 """ 信号,节点 _ready 执行结束后触发 """ 102 103 def add_child(self, child_node): 104 """ 105 添加子节点 106 107 :param child_node: 子节点 108 """ 109 if child_node._parent is not None: 110 error(f"{self.name}:{child_node.name} 已经有父节点!") 111 return 112 for child in self._children: 113 if child.name == child_node.name: 114 error(f"节点 {self.name} 已经有同名子节点{child_node.name} !") 115 return 116 117 child_node._parent = self # 设置子节点的 _parent 属性 118 if self.owner is not None: 119 child_node.owner = self.owner 120 else: 121 child_node.owner = self 122 123 self._children.append(child_node) 124 125 def remove_child(self, child_node): 126 """ 127 移除子节点 128 129 :param child_node: 子节点 130 """ 131 if child_node in self._children: 132 self._children.remove(child_node) 133 child_node._parent = None # 解除 _parent 绑定 134 else: 135 warning(f"{self.name}:{child_node.name} 并未被找到,未执行移除操作") 136 137 def _update(self, delta) -> None: 138 """ 139 引擎内部的节点更新函数,会以很低的频率调用 140 """ 141 pass 142 143 def _timer(self, delta) -> None: 144 """ 145 引擎内部的定时器更新函数,负责 Timer 相关的更新 146 """ 147 pass 148 149 def _init(self) -> None: 150 """ 151 初始化节点,会在 _ready() 之前被调用,尽量不要覆写此函数 152 """ 153 pass 154 155 def _ready(self) -> None: 156 """ 157 节点 _ready 函数,会在 _init() 之后被调用,可以在此函数中执行一些初始化操作 158 """ 159 pass 160 161 def _do_ready(self) -> None: 162 self._ready() 163 self.ready.emit() 164 165 def _process(self, delta) -> None: 166 """ 167 节点 process 函数,会根据 Engine 中设置的 frequency 进行连续调用 168 """ 169 pass 170 171 def _input(self, event: InputEvent) -> None: 172 """ 173 节点 input 函数,会在接收到输入事件时被调用 174 175 :param event: 输入事件 176 """ 177 pass 178 179 def _on_engine_exit(self) -> None: 180 """ 引擎退出时调用的函数 """ 181 pass 182 183 def get_child(self, name) -> "Node": 184 """ 185 通过节点名称获取子节点 186 187 :param name: 节点名称 188 """ 189 for child in self._children: 190 if child.name == name: 191 return child 192 return None 193 194 def get_children(self) -> List["Node"]: 195 """ 196 获取所有子节点 197 """ 198 return self._children 199 200 def get_parent(self) -> "Node": 201 """ 202 获取父节点 203 """ 204 return self._parent 205 206 def print_tree(self): 207 """ 208 打印节点树 209 """ 210 def print_recursive(node: "Node", prefix="", is_last=False, is_root=False): 211 if is_root: 212 print(f"{node}") # 根节点 213 else: 214 if is_last: 215 print(f"{prefix}└── {node}") # 最后一个子节点 216 else: 217 print(f"{prefix}├── {node}") # 其他子节点 218 219 for i, child in enumerate(node.get_children()): 220 is_last_child = (i == len(node.get_children()) - 1) 221 print_recursive(child, prefix + " ", is_last=is_last_child, is_root=False) 222 223 print_recursive(self, is_last=False, is_root=True) 224 225 def rbprint(self, str, end="\n"): 226 """ 227 打印带有帧号的字符串 228 229 :param str: 要打印的字符串 230 :param end: 结束符 231 """ 232 print(f"[{self.engine.get_frame()}] {str}", end=end) 233 234 def __repr__(self): 235 return f"{self.name}"
class
ProcessMode(enum.Enum):
38class ProcessMode(Enum): 39 """ 节点的process模式,PAUSABLE为默认模式 """ 40 PAUSABLE = 0 41 """ 当 Engine.paused 为 True 时,节点的 process 函数将不会被调用 """ 42 WHEN_PAUSED = 1 43 """ 只有当 Engine.paused 为 True 时,节点的 process 函数才会被调用 """ 44 ALWAYS = 2 45 """ 节点的 process 函数将始终被调用 """ 46 DISABLED = 3 47 """ 节点的 process 函数将永远不会被调用 """
节点的process模式,PAUSABLE为默认模式
Inherited Members
- enum.Enum
- name
- value
class
Node:
49class Node: 50 """ Node 基类 """ 51 from robotengine.input import InputEvent 52 53 def __init__(self, name="Node"): 54 """ 55 初始化节点 56 57 :param name: 节点名称 58 """ 59 self.name = name 60 """ 节点名称 """ 61 self.owner = None 62 """ 63 节点的所有者 64 65 注意:owner的指定与节点的创建顺序有关,例如: 66 67 A = Node("A") 68 B = Node("B") 69 C = Node("C") 70 D = Node("D") 71 72 A.add_child(B) 73 A.add_child(C) 74 B.add_child(D) 75 76 此时,A的子节点为B、C,B的子节点为D,B、C、D的owner均为A。 77 78 而如果继续添加节点: 79 80 E = Node("E") 81 E.add_child(A) 82 83 此时,E的子节点为A,A的owner为E,但是B、C、D的owner仍然为A。 84 """ 85 self._children = [] 86 self._parent = None 87 88 # 全局属性 89 from robotengine.engine import Engine 90 from robotengine.input import Input 91 92 self.engine: Engine = None 93 """ 节点的 Engine 实例 """ 94 self.input: Input = None 95 """ 节点的 Input 实例 """ 96 97 self.process_mode: ProcessMode = ProcessMode.PAUSABLE 98 """ 节点的process模式 """ 99 100 # 信号 101 self.ready: Signal = Signal() 102 """ 信号,节点 _ready 执行结束后触发 """ 103 104 def add_child(self, child_node): 105 """ 106 添加子节点 107 108 :param child_node: 子节点 109 """ 110 if child_node._parent is not None: 111 error(f"{self.name}:{child_node.name} 已经有父节点!") 112 return 113 for child in self._children: 114 if child.name == child_node.name: 115 error(f"节点 {self.name} 已经有同名子节点{child_node.name} !") 116 return 117 118 child_node._parent = self # 设置子节点的 _parent 属性 119 if self.owner is not None: 120 child_node.owner = self.owner 121 else: 122 child_node.owner = self 123 124 self._children.append(child_node) 125 126 def remove_child(self, child_node): 127 """ 128 移除子节点 129 130 :param child_node: 子节点 131 """ 132 if child_node in self._children: 133 self._children.remove(child_node) 134 child_node._parent = None # 解除 _parent 绑定 135 else: 136 warning(f"{self.name}:{child_node.name} 并未被找到,未执行移除操作") 137 138 def _update(self, delta) -> None: 139 """ 140 引擎内部的节点更新函数,会以很低的频率调用 141 """ 142 pass 143 144 def _timer(self, delta) -> None: 145 """ 146 引擎内部的定时器更新函数,负责 Timer 相关的更新 147 """ 148 pass 149 150 def _init(self) -> None: 151 """ 152 初始化节点,会在 _ready() 之前被调用,尽量不要覆写此函数 153 """ 154 pass 155 156 def _ready(self) -> None: 157 """ 158 节点 _ready 函数,会在 _init() 之后被调用,可以在此函数中执行一些初始化操作 159 """ 160 pass 161 162 def _do_ready(self) -> None: 163 self._ready() 164 self.ready.emit() 165 166 def _process(self, delta) -> None: 167 """ 168 节点 process 函数,会根据 Engine 中设置的 frequency 进行连续调用 169 """ 170 pass 171 172 def _input(self, event: InputEvent) -> None: 173 """ 174 节点 input 函数,会在接收到输入事件时被调用 175 176 :param event: 输入事件 177 """ 178 pass 179 180 def _on_engine_exit(self) -> None: 181 """ 引擎退出时调用的函数 """ 182 pass 183 184 def get_child(self, name) -> "Node": 185 """ 186 通过节点名称获取子节点 187 188 :param name: 节点名称 189 """ 190 for child in self._children: 191 if child.name == name: 192 return child 193 return None 194 195 def get_children(self) -> List["Node"]: 196 """ 197 获取所有子节点 198 """ 199 return self._children 200 201 def get_parent(self) -> "Node": 202 """ 203 获取父节点 204 """ 205 return self._parent 206 207 def print_tree(self): 208 """ 209 打印节点树 210 """ 211 def print_recursive(node: "Node", prefix="", is_last=False, is_root=False): 212 if is_root: 213 print(f"{node}") # 根节点 214 else: 215 if is_last: 216 print(f"{prefix}└── {node}") # 最后一个子节点 217 else: 218 print(f"{prefix}├── {node}") # 其他子节点 219 220 for i, child in enumerate(node.get_children()): 221 is_last_child = (i == len(node.get_children()) - 1) 222 print_recursive(child, prefix + " ", is_last=is_last_child, is_root=False) 223 224 print_recursive(self, is_last=False, is_root=True) 225 226 def rbprint(self, str, end="\n"): 227 """ 228 打印带有帧号的字符串 229 230 :param str: 要打印的字符串 231 :param end: 结束符 232 """ 233 print(f"[{self.engine.get_frame()}] {str}", end=end) 234 235 def __repr__(self): 236 return f"{self.name}"
Node 基类
Node(name='Node')
53 def __init__(self, name="Node"): 54 """ 55 初始化节点 56 57 :param name: 节点名称 58 """ 59 self.name = name 60 """ 节点名称 """ 61 self.owner = None 62 """ 63 节点的所有者 64 65 注意:owner的指定与节点的创建顺序有关,例如: 66 67 A = Node("A") 68 B = Node("B") 69 C = Node("C") 70 D = Node("D") 71 72 A.add_child(B) 73 A.add_child(C) 74 B.add_child(D) 75 76 此时,A的子节点为B、C,B的子节点为D,B、C、D的owner均为A。 77 78 而如果继续添加节点: 79 80 E = Node("E") 81 E.add_child(A) 82 83 此时,E的子节点为A,A的owner为E,但是B、C、D的owner仍然为A。 84 """ 85 self._children = [] 86 self._parent = None 87 88 # 全局属性 89 from robotengine.engine import Engine 90 from robotengine.input import Input 91 92 self.engine: Engine = None 93 """ 节点的 Engine 实例 """ 94 self.input: Input = None 95 """ 节点的 Input 实例 """ 96 97 self.process_mode: ProcessMode = ProcessMode.PAUSABLE 98 """ 节点的process模式 """ 99 100 # 信号 101 self.ready: Signal = Signal() 102 """ 信号,节点 _ready 执行结束后触发 """
初始化节点
:param name: 节点名称
owner
节点的所有者
注意:owner的指定与节点的创建顺序有关,例如:
A = Node("A")
B = Node("B")
C = Node("C")
D = Node("D")
A.add_child(B)
A.add_child(C)
B.add_child(D)
此时,A的子节点为B、C,B的子节点为D,B、C、D的owner均为A。
而如果继续添加节点:
E = Node("E")
E.add_child(A)
此时,E的子节点为A,A的owner为E,但是B、C、D的owner仍然为A。
def
add_child(self, child_node):
104 def add_child(self, child_node): 105 """ 106 添加子节点 107 108 :param child_node: 子节点 109 """ 110 if child_node._parent is not None: 111 error(f"{self.name}:{child_node.name} 已经有父节点!") 112 return 113 for child in self._children: 114 if child.name == child_node.name: 115 error(f"节点 {self.name} 已经有同名子节点{child_node.name} !") 116 return 117 118 child_node._parent = self # 设置子节点的 _parent 属性 119 if self.owner is not None: 120 child_node.owner = self.owner 121 else: 122 child_node.owner = self 123 124 self._children.append(child_node)
添加子节点
:param child_node: 子节点
def
remove_child(self, child_node):
126 def remove_child(self, child_node): 127 """ 128 移除子节点 129 130 :param child_node: 子节点 131 """ 132 if child_node in self._children: 133 self._children.remove(child_node) 134 child_node._parent = None # 解除 _parent 绑定 135 else: 136 warning(f"{self.name}:{child_node.name} 并未被找到,未执行移除操作")
移除子节点
:param child_node: 子节点
184 def get_child(self, name) -> "Node": 185 """ 186 通过节点名称获取子节点 187 188 :param name: 节点名称 189 """ 190 for child in self._children: 191 if child.name == name: 192 return child 193 return None
通过节点名称获取子节点
:param name: 节点名称
def
print_tree(self):
207 def print_tree(self): 208 """ 209 打印节点树 210 """ 211 def print_recursive(node: "Node", prefix="", is_last=False, is_root=False): 212 if is_root: 213 print(f"{node}") # 根节点 214 else: 215 if is_last: 216 print(f"{prefix}└── {node}") # 最后一个子节点 217 else: 218 print(f"{prefix}├── {node}") # 其他子节点 219 220 for i, child in enumerate(node.get_children()): 221 is_last_child = (i == len(node.get_children()) - 1) 222 print_recursive(child, prefix + " ", is_last=is_last_child, is_root=False) 223 224 print_recursive(self, is_last=False, is_root=True)
打印节点树
class
Node.InputEvent:
139class InputEvent: 140 """ 输入事件基类 """ 141 def __init__(self): 142 pass 143 144 def get_action_strength(self, action: str) -> float: 145 """ 返回某个动作的强度 """ 146 pass 147 148 def is_action_pressed(self, action: str) -> bool: 149 """ 检查某个动作是否被按下 """ 150 pass 151 152 def is_action_released(self, action: str) -> bool: 153 """ 检查某个动作是否被释放 """ 154 pass
输入事件基类