#pragma once #include #include #include #include #include #include #include namespace extra2d { // 前向声明 class Scene; class TransformComponent; /** * @brief 场景节点类 * * 节点是场景图的基本单元,可以包含多个组件和子节点 */ class Node : public RefCounted { public: /** * @brief 构造函数 */ Node(); /** * @brief 析构函数 */ ~Node() override; // 禁止拷贝 Node(const Node&) = delete; Node& operator=(const Node&) = delete; // ======================================== // 层级关系 // ======================================== /** * @brief 添加子节点 * @param child 子节点 */ void addChild(Ptr child); /** * @brief 移除子节点 * @param child 子节点 */ void removeChild(Node* child); /** * @brief 从父节点移除 */ void removeFromParent(); /** * @brief 获取父节点 * @return 父节点指针 */ Node* getParent() const { return parent_; } /** * @brief 获取所有子节点 * @return 子节点列表 */ const std::vector>& getChildren() const { return children_; } /** * @brief 移除所有子节点 */ void removeAllChildren(); // ======================================== // 组件管理 // ======================================== /** * @brief 添加组件 * @tparam T 组件类型 * @param component 组件 * @return 组件指针 */ template T* addComponent(Ptr component) { static_assert(std::is_base_of::value, "T must be derived from Component"); T* ptr = component.get(); components_.push_back(component); ptr->onAttach(this); // 如果是 TransformComponent,缓存它 if (auto* transform = dynamic_cast(ptr)) { transform_ = transform; } return ptr; } /** * @brief 获取组件 * @tparam T 组件类型 * @return 组件指针,未找到返回 nullptr */ template T* getComponent() const { for (const auto& comp : components_) { if (auto* ptr = dynamic_cast(comp.get())) { return ptr; } } return nullptr; } /** * @brief 移除组件 * @tparam T 组件类型 */ template void removeComponent() { for (auto it = components_.begin(); it != components_.end(); ++it) { if (dynamic_cast(it->get())) { (*it)->onDetach(); components_.erase(it); return; } } } // ======================================== // 变换便捷接口 // ======================================== /** * @brief 设置位置 * @param pos 位置 */ void setPosition(const Vec2& pos); /** * @brief 设置位置 * @param x X坐标 * @param y Y坐标 */ void setPosition(float x, float y); /** * @brief 获取位置 * @return 位置 */ Vec2 getPosition() const; /** * @brief 设置旋转角度 * @param rot 角度(度) */ void setRotation(float rot); /** * @brief 获取旋转角度 * @return 角度(度) */ float getRotation() const; /** * @brief 设置缩放 * @param scale 缩放 */ void setScale(const Vec2& scale); /** * @brief 设置统一缩放 * @param scale 缩放值 */ void setScale(float scale); /** * @brief 设置缩放 * @param x X轴缩放 * @param y Y轴缩放 */ void setScale(float x, float y); /** * @brief 获取缩放 * @return 缩放 */ Vec2 getScale() const; /** * @brief 设置尺寸 * @param size 尺寸 */ void setSize(const Vec2& size); /** * @brief 设置尺寸 * @param width 宽度 * @param height 高度 */ void setSize(float width, float height); /** * @brief 获取尺寸 * @return 尺寸 */ Vec2 getSize() const; /** * @brief 设置锚点 * @param anchor 锚点 [0,1] */ void setAnchor(const Vec2& anchor); /** * @brief 设置锚点 * @param x X锚点 * @param y Y锚点 */ void setAnchor(float x, float y); /** * @brief 获取锚点 * @return 锚点 */ Vec2 getAnchor() const; /** * @brief 获取世界变换 * @return 世界变换 */ Transform getWorldTransform() const; /** * @brief 获取世界矩阵 * @return 世界矩阵 */ Mat4 getWorldMatrix() const; // ======================================== // 属性 // ======================================== /** * @brief 设置名称 * @param name 名称 */ void setName(const std::string& name) { name_ = name; } /** * @brief 获取名称 * @return 名称 */ const std::string& getName() const { return name_; } /** * @brief 设置标签 * @param tag 标签 */ void setTag(int32 tag) { tag_ = tag; } /** * @brief 获取标签 * @return 标签 */ int32 getTag() const { return tag_; } /** * @brief 设置是否可见 * @param visible 是否可见 */ void setVisible(bool visible) { visible_ = visible; } /** * @brief 是否可见 * @return 是否可见 */ bool isVisible() const { return visible_; } /** * @brief 获取 TransformComponent * @return TransformComponent 指针 */ TransformComponent* getTransform() const { return transform_; } // ======================================== // 生命周期 // ======================================== /** * @brief 节点进入场景时调用 */ void onEnter(); /** * @brief 节点离开场景时调用 */ void onExit(); /** * @brief 每帧更新 * @param dt 帧间隔时间 */ void update(float dt); /** * @brief 渲染(收集渲染命令) */ virtual void render(); private: std::string name_; int32 tag_ = 0; bool visible_ = true; Node* parent_ = nullptr; std::vector> children_; std::vector> components_; TransformComponent* transform_ = nullptr; }; } // namespace extra2d