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为默认模式

PAUSABLE = <ProcessMode.PAUSABLE: 0>

当 Engine.paused 为 True 时,节点的 process 函数将不会被调用

WHEN_PAUSED = <ProcessMode.WHEN_PAUSED: 1>

只有当 Engine.paused 为 True 时,节点的 process 函数才会被调用

ALWAYS = <ProcessMode.ALWAYS: 2>

节点的 process 函数将始终被调用

DISABLED = <ProcessMode.DISABLED: 3>

节点的 process 函数将永远不会被调用

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: 节点名称
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。

engine: 'Engine'

节点的 Engine 实例

input: 'Input'

节点的 Input 实例

process_mode: ProcessMode

节点的process模式

信号,节点 _ready 执行结束后触发

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: 子节点
def get_child(self, name) -> 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 get_children(self) -> list[Node]:
195    def get_children(self) -> List["Node"]:
196        """ 
197        获取所有子节点 
198        """
199        return self._children

获取所有子节点

def get_parent(self) -> Node:
201    def get_parent(self) -> "Node":
202        """ 
203        获取父节点 
204        """
205        return self._parent

获取父节点

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)

打印节点树

def rbprint(self, str, end='\n'):
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)

打印带有帧号的字符串

:param str: 要打印的字符串
:param end: 结束符
class Node.InputEvent:
130class InputEvent:
131    """ 输入事件基类 """
132    def __init__(self):
133        pass
134
135    def get_action_strength(self, action: str) -> float:
136        """ 返回某个动作的强度 """
137        pass
138
139    def is_action_pressed(self, action: str) -> bool:
140        """ 检查某个动作是否被按下 """
141        pass
142
143    def is_action_released(self, action: str) -> bool:
144        """ 检查某个动作是否被释放 """
145        pass

输入事件基类