#pragma once #include #include "EngineFrame/Attribute/Y_Transform.h" #include "EngineFrame/Attribute/Flag.h" #include "math/Math.h" #include "Tool/RefObject.h" #include "Tool/RefPtr.h" #include "Tool/IntrusiveList.hpp" class Node : public RefObject, protected IntrusiveListValue> { public: typedef std::function UpdateCallback; typedef IntrusiveList> NodeList; using IntrusiveListValue>::GetNext; using IntrusiveListValue>::GetPrev; private: /**变换属性 */ Y_Transform transform_; /**变换矩阵 */ mutable Matrix3x2 transform_matrix_; mutable Matrix3x2 transform_matrix_inverse_; mutable Matrix3x2 transform_matrix_to_parent_; /**更新时的回调函数 */ std::map cb_update_; /**锚点 */ glm::vec2 anchor_; /**Z轴显示层级 */ int z_order_; /**大小 */ VecSize size_; /**透明度 */ float opacity_; /**是否可见 */ bool visible_; /**是否暂停更新 */ bool update_pausing_; /**是否显示边界 */ bool show_border_; /**名称 */ std::string name_; /**父对象 */ Node *parent_; /**子对象链表 */ NodeList children_; /**标志 */ mutable Flag dirty_flag_; public: virtual void Init(); virtual void HandleEvents(SDL_Event *e); virtual void Update(float deltaTime); virtual void PreRender(); virtual void Render(); virtual void Clear(); void UpdateSelf(float dt); public: /// \~chinese /// @brief 获取显示状态 bool IsVisible() const; /// \~chinese /// @brief 获取 Z 轴顺序 int GetZOrder() const; /// \~chinese /// @brief 获取坐标 glm::vec2 GetPosition() const; /// \~chinese /// @brief 获取 x 坐标 float GetPositionX() const; /// \~chinese /// @brief 获取 y 坐标 float GetPositionY() const; /// \~chinese /// @brief 获取大小 virtual VecSize GetSize() const; /// \~chinese /// @brief 获取宽度 float GetWidth() const; /// \~chinese /// @brief 获取高度 float GetHeight() const; /// \~chinese /// @brief 获取缩放后的宽度 float GetScaledWidth() const; /// \~chinese /// @brief 获取缩放后的高度 float GetScaledHeight() const; /// \~chinese /// @brief 获取缩放后的大小 VecSize GetScaledSize() const; /// \~chinese /// @brief 获取锚点 glm::vec2 GetAnchor() const; /// \~chinese /// @brief 获取 x 方向锚点 float GetAnchorX() const; /// \~chinese /// @brief 获取 y 方向锚点 float GetAnchorY() const; /// \~chinese /// @brief 获取透明度 float GetOpacity() const; /// \~chinese /// @brief 获取旋转角度 float GetRotation() const; /// \~chinese /// @brief 获取缩放比例 glm::vec2 GetScale() const; /// \~chinese /// @brief 获取横向缩放比例 float GetScaleX() const; /// \~chinese /// @brief 获取纵向缩放比例 float GetScaleY() const; /// \~chinese /// @brief 获取错切角度 glm::vec2 GetSkew() const; /// \~chinese /// @brief 获取横向错切角度 float GetSkewX() const; /// \~chinese /// @brief 获取纵向错切角度 float GetSkewY() const; /// \~chinese /// @brief 获取变换 Y_Transform GetTransform() const; /// \~chinese /// @brief 获取父角色 Node *GetParent() const; /// \~chinese /// @brief 设置角色是否可见 void SetVisible(bool val); /// \~chinese /// @brief 设置名称 void SetName(std::string name); /// \~chinese /// @brief 设置坐标 void SetPosition(const glm::vec2 &pos); /// \~chinese /// @brief 设置坐标 void SetPosition(float x, float y); /// \~chinese /// @brief 设置横坐标 void SetPositionX(float x); /// \~chinese /// @brief 设置纵坐标 void SetPositionY(float y); /// \~chinese /// @brief 移动至坐标 void MoveTo(const glm::vec2 &p); /// \~chinese /// @brief 移动至坐标 void MoveTo(float x, float y); /// \~chinese /// @brief 移动相对坐标 void MoveBy(const glm::vec2 &trans); /// \~chinese /// @brief 移动相对坐标 void MoveBy(float trans_x, float trans_y); /// \~chinese /// @brief 设置缩放比例,默认为 (1.0, 1.0) void SetScale(const glm::vec2 &scale); /// \~chinese /// @brief 设置缩放比例,默认为 (1.0, 1.0) void SetScale(float scalex, float scaley); /// \~chinese /// @brief 设置错切角度,默认为 (0, 0) void SetSkew(const glm::vec2 &skew); /// \~chinese /// @brief 设置错切角度,默认为 (0, 0) void SetSkew(float skewx, float skewy); /// \~chinese /// @brief 设置旋转角度,默认为 0 void SetRotation(float rotation); /// \~chinese /// @brief 设置锚点位置,默认为 (0, 0), 范围 [0, 1] void SetAnchor(const glm::vec2 &anchor); /// \~chinese /// @brief 设置锚点位置,默认为 (0, 0), 范围 [0, 1] void SetAnchor(float anchorx, float anchory); /// \~chinese /// @brief 修改大小 void SetSize(const VecSize &size); /// \~chinese /// @brief 修改大小 void SetSize(float width, float height); /// \~chinese /// @brief 修改宽度 void SetWidth(float width); /// \~chinese /// @brief 修改高度 void SetHeight(float height); /// \~chinese /// @brief 设置透明度,默认为 1.0, 范围 [0, 1] void SetOpacity(float opacity); /// \~chinese /// @brief 设置二维仿射变换 void SetTransform(const Y_Transform &transform); /// \~chinese /// @brief 设置 Z 轴顺序,默认为 0 void SetZOrder(int zorder); /// \~chinese /// @brief 添加子角色 void AddChild(RefPtr child); /// \~chinese /// @brief 获取全部子角色 NodeList &GetAllChildren(); /// \~chinese /// @brief 获取全部子角色 const NodeList &GetAllChildren() const; /// \~chinese /// @brief 移除子角色 void RemoveChild(RefPtr child); /// \~chinese /// @brief 移除所有节点 void RemoveAllChildren(); /// \~chinese /// @brief 从父角色移除 void RemoveFromParent(); /// \~chinese /// @brief 暂停角色更新 void PauseUpdating(); /// \~chinese /// @brief 继续角色更新 void ResumeUpdating(); /// \~chinese /// @brief 角色更新是否暂停 bool IsUpdatePausing() const; /// \~chinese /// @brief 设置更新时的回调函数 void SetCallbackOnUpdate(std::string Key, const UpdateCallback &cb); /// \~chinese /// @brief 移除更新时的回调函数 void RemoveCallbackOnUpdate(std::string Key); /// \~chinese /// @brief 判断点是否在角色内 virtual bool ContainsPoint(const glm::vec2 &point) const; /// \~chinese /// @brief 将世界坐标系点转换为局部坐标系点 glm::vec2 ConvertToLocal(const glm::vec2 &point) const; /// \~chinese /// @brief 将局部坐标系点转换为世界坐标系点 glm::vec2 ConvertToWorld(const glm::vec2 &point) const; /// \~chinese /// @brief 渲染角色边界 void ShowBorder(bool show); public: Node(/* args */); ~Node(); /// \~chinese /// @brief 更新自己的二维变换,并通知所有子角色 void UpdateTransform() const; /// \~chinese /// @brief 向上追溯更新 /// @details 对于节点树 A->B(dirty)->C->D,当对 D 执行 UpdateTransformUpwards 时会对 B、C、D 从上到下依次更新 void UpdateTransformUpwards() const; /// \~chinese /// @brief 获取二维变换矩阵 const Matrix3x2 &GetTransformMatrix() const; /// \~chinese /// @brief 获取二维变换的逆矩阵 const Matrix3x2 &GetTransformInverseMatrix() const; /// \~chinese /// @brief 获取变换到父角色的二维变换矩阵 const Matrix3x2 &GetTransformMatrixToParent() const; /// \~chinese /// @brief 将所有子角色按Z轴顺序排序 void Reorder(); enum DirtyFlag : uint8_t { Clean = 0, DirtyTransform = 1, DirtyTransformInverse = 1 << 1, DirtyOpacity = 1 << 2, DirtyVisibility = 1 << 3 }; };