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        self.name = name
 55        """ 节点名称 """
 56        self.owner = None
 57        """
 58        节点的所有者
 59
 60        注意:owner的指定与节点的创建顺序有关,例如:
 61
 62            A = Node("A")
 63            B = Node("B")
 64            C = Node("C")
 65            D = Node("D")
 66
 67            A.add_child(B)
 68            A.add_child(C)
 69            B.add_child(D)
 70
 71        此时,A的子节点为B、C,B的子节点为D,B、C、D的owner均为A。
 72
 73        而如果继续添加节点:
 74
 75            E = Node("E")
 76            E.add_child(A)
 77
 78        此时,E的子节点为A,A的owner为E,但是B、C、D的owner仍然为A。
 79        """
 80        self._children = []
 81        self._parent = None
 82
 83        # 全局属性
 84        from robotengine.engine import Engine
 85        from robotengine.input import Input
 86
 87        self.engine: Engine = None
 88        """ 节点的 Engine 实例 """
 89        self.input: Input = None
 90        """ 节点的 Input 实例 """
 91
 92        self.process_mode: ProcessMode = ProcessMode.PAUSABLE
 93        """ 节点的process模式 """
 94
 95        # 信号
 96        self.ready: Signal = Signal()
 97        """ 信号,节点 _ready 执行结束后触发 """
 98
 99    def add_child(self, child_node):
100        """ 添加子节点 """
101        if child_node._parent is not None:
102            error(f"{self.name}{child_node.name} 已经有父节点!")
103            return
104        for child in self._children:
105            if child.name == child_node.name:
106                error(f"节点 {self.name} 已经有同名子节点{child_node.name} !")
107                return
108
109        child_node._parent = self  # 设置子节点的 _parent 属性
110        if self.owner is not None:
111            child_node.owner = self.owner
112        else:
113            child_node.owner = self
114
115        self._children.append(child_node)
116
117    def remove_child(self, child_node):
118        """ 移除子节点 """
119        if child_node in self._children:
120            self._children.remove(child_node)
121            child_node._parent = None  # 解除 _parent 绑定
122        else:
123            warning(f"{self.name}{child_node.name} 并未被找到,未执行移除操作")
124
125    def _update(self, delta) -> None:
126        """ 引擎内部的节点更新函数,会以很低的频率调用 """
127        pass
128
129    def _timer(self, delta) -> None:
130        """ 引擎内部的定时器更新函数,负责 Timer 相关的更新 """
131        pass
132
133    def _init(self) -> None:
134        """ 初始化节点,会在 _ready() 之前被调用,尽量不要覆写此函数 """
135        pass
136    
137    def _ready(self) -> None:
138        """ 节点 _ready 函数,会在 _init() 之后被调用,可以在此函数中执行一些初始化操作 """
139        pass
140
141    def _ready_execute(self) -> None:
142        self._ready()
143        self.ready.emit()
144
145    def _process(self, delta) -> None:
146        """ 节点 process 函数,会根据 Engine 中设置的 frequency 进行连续调用 """
147        pass
148
149    def _input(self, event: InputEvent) -> None:
150        """ 节点 input 函数,会在接收到输入事件时被调用 """
151        pass
152
153    def get_child(self, name) -> "Node":
154        """ 通过节点名称获取子节点 """
155        for child in self._children:
156            if child.name == name:
157                return child
158        return None
159    
160    def get_children(self) -> List["Node"]:
161        """ 获取所有子节点 """
162        return self._children
163    
164    def get_parent(self) -> "Node":
165        """ 获取父节点 """
166        return self._parent
167    
168    def rbprint(self, str, end="\n"):
169        print(f"[{self.engine.get_frame()}] {str}", end=end)
170
171    def __repr__(self):
172        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        self.name = name
 56        """ 节点名称 """
 57        self.owner = None
 58        """
 59        节点的所有者
 60
 61        注意:owner的指定与节点的创建顺序有关,例如:
 62
 63            A = Node("A")
 64            B = Node("B")
 65            C = Node("C")
 66            D = Node("D")
 67
 68            A.add_child(B)
 69            A.add_child(C)
 70            B.add_child(D)
 71
 72        此时,A的子节点为B、C,B的子节点为D,B、C、D的owner均为A。
 73
 74        而如果继续添加节点:
 75
 76            E = Node("E")
 77            E.add_child(A)
 78
 79        此时,E的子节点为A,A的owner为E,但是B、C、D的owner仍然为A。
 80        """
 81        self._children = []
 82        self._parent = None
 83
 84        # 全局属性
 85        from robotengine.engine import Engine
 86        from robotengine.input import Input
 87
 88        self.engine: Engine = None
 89        """ 节点的 Engine 实例 """
 90        self.input: Input = None
 91        """ 节点的 Input 实例 """
 92
 93        self.process_mode: ProcessMode = ProcessMode.PAUSABLE
 94        """ 节点的process模式 """
 95
 96        # 信号
 97        self.ready: Signal = Signal()
 98        """ 信号,节点 _ready 执行结束后触发 """
 99
100    def add_child(self, child_node):
101        """ 添加子节点 """
102        if child_node._parent is not None:
103            error(f"{self.name}{child_node.name} 已经有父节点!")
104            return
105        for child in self._children:
106            if child.name == child_node.name:
107                error(f"节点 {self.name} 已经有同名子节点{child_node.name} !")
108                return
109
110        child_node._parent = self  # 设置子节点的 _parent 属性
111        if self.owner is not None:
112            child_node.owner = self.owner
113        else:
114            child_node.owner = self
115
116        self._children.append(child_node)
117
118    def remove_child(self, child_node):
119        """ 移除子节点 """
120        if child_node in self._children:
121            self._children.remove(child_node)
122            child_node._parent = None  # 解除 _parent 绑定
123        else:
124            warning(f"{self.name}{child_node.name} 并未被找到,未执行移除操作")
125
126    def _update(self, delta) -> None:
127        """ 引擎内部的节点更新函数,会以很低的频率调用 """
128        pass
129
130    def _timer(self, delta) -> None:
131        """ 引擎内部的定时器更新函数,负责 Timer 相关的更新 """
132        pass
133
134    def _init(self) -> None:
135        """ 初始化节点,会在 _ready() 之前被调用,尽量不要覆写此函数 """
136        pass
137    
138    def _ready(self) -> None:
139        """ 节点 _ready 函数,会在 _init() 之后被调用,可以在此函数中执行一些初始化操作 """
140        pass
141
142    def _ready_execute(self) -> None:
143        self._ready()
144        self.ready.emit()
145
146    def _process(self, delta) -> None:
147        """ 节点 process 函数,会根据 Engine 中设置的 frequency 进行连续调用 """
148        pass
149
150    def _input(self, event: InputEvent) -> None:
151        """ 节点 input 函数,会在接收到输入事件时被调用 """
152        pass
153
154    def get_child(self, name) -> "Node":
155        """ 通过节点名称获取子节点 """
156        for child in self._children:
157            if child.name == name:
158                return child
159        return None
160    
161    def get_children(self) -> List["Node"]:
162        """ 获取所有子节点 """
163        return self._children
164    
165    def get_parent(self) -> "Node":
166        """ 获取父节点 """
167        return self._parent
168    
169    def rbprint(self, str, end="\n"):
170        print(f"[{self.engine.get_frame()}] {str}", end=end)
171
172    def __repr__(self):
173        return f"{self.name}"

Node 基类

Node(name='Node')
53    def __init__(self, name="Node"):
54        """ 初始化节点, 需要指定节点名称 """
55        self.name = name
56        """ 节点名称 """
57        self.owner = None
58        """
59        节点的所有者
60
61        注意:owner的指定与节点的创建顺序有关,例如:
62
63            A = Node("A")
64            B = Node("B")
65            C = Node("C")
66            D = Node("D")
67
68            A.add_child(B)
69            A.add_child(C)
70            B.add_child(D)
71
72        此时,A的子节点为B、C,B的子节点为D,B、C、D的owner均为A。
73
74        而如果继续添加节点:
75
76            E = Node("E")
77            E.add_child(A)
78
79        此时,E的子节点为A,A的owner为E,但是B、C、D的owner仍然为A。
80        """
81        self._children = []
82        self._parent = None
83
84        # 全局属性
85        from robotengine.engine import Engine
86        from robotengine.input import Input
87
88        self.engine: Engine = None
89        """ 节点的 Engine 实例 """
90        self.input: Input = None
91        """ 节点的 Input 实例 """
92
93        self.process_mode: ProcessMode = ProcessMode.PAUSABLE
94        """ 节点的process模式 """
95
96        # 信号
97        self.ready: Signal = Signal()
98        """ 信号,节点 _ready 执行结束后触发 """

初始化节点, 需要指定节点名称

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):
100    def add_child(self, child_node):
101        """ 添加子节点 """
102        if child_node._parent is not None:
103            error(f"{self.name}{child_node.name} 已经有父节点!")
104            return
105        for child in self._children:
106            if child.name == child_node.name:
107                error(f"节点 {self.name} 已经有同名子节点{child_node.name} !")
108                return
109
110        child_node._parent = self  # 设置子节点的 _parent 属性
111        if self.owner is not None:
112            child_node.owner = self.owner
113        else:
114            child_node.owner = self
115
116        self._children.append(child_node)

添加子节点

def remove_child(self, child_node):
118    def remove_child(self, child_node):
119        """ 移除子节点 """
120        if child_node in self._children:
121            self._children.remove(child_node)
122            child_node._parent = None  # 解除 _parent 绑定
123        else:
124            warning(f"{self.name}{child_node.name} 并未被找到,未执行移除操作")

移除子节点

def get_child(self, name) -> Node:
154    def get_child(self, name) -> "Node":
155        """ 通过节点名称获取子节点 """
156        for child in self._children:
157            if child.name == name:
158                return child
159        return None

通过节点名称获取子节点

def get_children(self) -> list[Node]:
161    def get_children(self) -> List["Node"]:
162        """ 获取所有子节点 """
163        return self._children

获取所有子节点

def get_parent(self) -> Node:
165    def get_parent(self) -> "Node":
166        """ 获取父节点 """
167        return self._parent

获取父节点

def rbprint(self, str, end='\n'):
169    def rbprint(self, str, end="\n"):
170        print(f"[{self.engine.get_frame()}] {str}", end=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

输入事件基类