diff --git a/.vscode/settings.json b/.vscode/settings.json index baf253f..fc04630 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -96,5 +96,6 @@ "semaphore": "cpp", "cinttypes": "cpp", "netfwd": "cpp" - } + }, + "Codegeex.RepoIndex": true } \ No newline at end of file diff --git a/folder-alias.json b/folder-alias.json index c661ff6..4f7d50f 100644 --- a/folder-alias.json +++ b/folder-alias.json @@ -214,5 +214,8 @@ }, "source/EngineFrame/Component/NumberText.h": { "description": "数字文本" + }, + "source/EngineFrame/Attribute": { + "description": "属性" } } \ No newline at end of file diff --git a/source/EngineCore/Game.cpp b/source/EngineCore/Game.cpp index 84136f7..c022a30 100644 --- a/source/EngineCore/Game.cpp +++ b/source/EngineCore/Game.cpp @@ -1,7 +1,7 @@ #include "Game.h" #include "squirrel/SquirrelEx.h" #include "EngineFrame/Component/Sprite.h" -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" #include "EngineFrame/Component/Text.h" Game::Game() @@ -25,10 +25,11 @@ void Game::Init(std::function CallBack) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // 双缓冲 + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // 24位深度缓冲(避免z-fighting) // 启用多重采样(关键步骤) SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // 启用多重采样缓冲 - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8); // 4x 采样(可改为 8 等) + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { diff --git a/source/EngineFrame/Attribute/Bits.h b/source/EngineFrame/Attribute/Bits.h new file mode 100644 index 0000000..0c70188 --- /dev/null +++ b/source/EngineFrame/Attribute/Bits.h @@ -0,0 +1,26 @@ +#pragma once +#include + +namespace bits +{ + template + inline void Set(_Ty &old, _Ty flag) + { + static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type"); + old |= flag; + } + + template + inline void Unset(_Ty &old, _Ty flag) + { + static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type"); + old &= ~flag; + } + + template + inline bool Has(_Ty old, _Ty flag) + { + static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type"); + return !!(old & flag); + } +} \ No newline at end of file diff --git a/source/EngineFrame/Attribute/Flag.h b/source/EngineFrame/Attribute/Flag.h new file mode 100644 index 0000000..e430f9c --- /dev/null +++ b/source/EngineFrame/Attribute/Flag.h @@ -0,0 +1,57 @@ +#pragma once +#include // uint8_t +#include "Bits.h" +template +class Flag +{ +public: + static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type"); + + typedef _Ty value_type; + + _Ty value; + + inline Flag() + : value() + { + } + + inline Flag(_Ty value) + : value(value) + { + } + + inline void Set(_Ty value) + { + bits::Set(this->value, value); + } + + inline void Unset(_Ty value) + { + bits::Unset(this->value, value); + } + + inline bool Has(_Ty value) const + { + return bits::Has(this->value, value); + } +}; + +template +struct IsFlag : public std::false_type +{ +}; + +template +struct IsFlag> : public std::true_type +{ +}; + +typedef Flag FlagUint8; +typedef Flag FlagUint16; +typedef Flag FlagUint32; +typedef Flag FlagUint64; +typedef Flag FlagInt8; +typedef Flag FlagInt16; +typedef Flag FlagInt32; +typedef Flag FlagInt64; diff --git a/source/EngineFrame/Attribute/Y_Transform.cpp b/source/EngineFrame/Attribute/Y_Transform.cpp new file mode 100644 index 0000000..f2ce8e6 --- /dev/null +++ b/source/EngineFrame/Attribute/Y_Transform.cpp @@ -0,0 +1,61 @@ +#include "Y_Transform.h" +#include +Y_Transform::Y_Transform() : position(0.f, 0.f), scale(1.0f, 1.0f), skew(0.f, 0.f), rotation(0.f) +{ +} + + +Matrix3x2 Y_Transform::ToMatrix() const +{ + // 将角度转换为弧度 + float rotRad = glm::radians(rotation); + float skewXRad = glm::radians(skew.x); + float skewYRad = glm::radians(skew.y); + + // 计算旋转的正弦和余弦 + float cosRot = std::cos(rotRad); + float sinRot = std::sin(rotRad); + + // 计算错切的正切值 + float tanSkewX = std::tan(skewXRad); + float tanSkewY = std::tan(skewYRad); + + // 构造基础变换矩阵(缩放 × 错切 × 旋转的组合) + // 注意:矩阵乘法顺序为 旋转 × 错切 × 缩放(从右向左应用) + float m00 = scale.x * (cosRot - sinRot * tanSkewY); + float m01 = scale.y * (-sinRot + cosRot * tanSkewX); + float m10 = scale.x * (sinRot + cosRot * tanSkewY); + float m11 = scale.y * (cosRot + sinRot * tanSkewX); + + // 平移分量 + float tx = position.x; + float ty = position.y; + + // 构造并返回 3x2 矩阵(假设 Matrix3x2 可通过此方式初始化) + return Matrix3x2(m00, m01, m10, m11, tx, ty); +} + +glm::mat4 Y_Transform::GetTransformMatrix() const +{ + // 缩放矩阵(Scale) + glm::mat4 scaleMat = glm::mat4(1.0f); // 单位矩阵 + scaleMat[0][0] = scale.x; // x轴缩放 + scaleMat[1][1] = scale.y; // y轴缩放 + + // 错切矩阵(Skew):先将角度转为弧度 + float skewX = glm::radians(skew.x); // 沿y轴错切角度(x方向倾斜) + float skewY = glm::radians(skew.y); // 沿x轴错切角度(y方向倾斜) + glm::mat4 skewMat = glm::mat4(1.0f); + skewMat[0][1] = tan(skewX); // x方向错切因子(影响y轴) + skewMat[1][0] = tan(skewY); // y方向错切因子(影响x轴) + + // 旋转矩阵(Rotation):绕z轴旋转,角度转弧度 + float rotRad = glm::radians(rotation); + glm::mat4 rotMat = glm::rotate(glm::mat4(1.0f), rotRad, glm::vec3(0, 0, 1)); + + // 平移矩阵(Translation) + glm::mat4 transMat = glm::translate(glm::mat4(1.0f), glm::vec3(position, 0.0f)); + + // 组合变换矩阵:平移 × 旋转 × 错切 × 缩放(注意乘法顺序,从右向左应用) + return transMat * rotMat * skewMat * scaleMat; +} diff --git a/source/EngineFrame/Attribute/Y_Transform.h b/source/EngineFrame/Attribute/Y_Transform.h new file mode 100644 index 0000000..213c4b1 --- /dev/null +++ b/source/EngineFrame/Attribute/Y_Transform.h @@ -0,0 +1,26 @@ +#pragma once +#include "math/Math.h" +#include +#include +#include +class Y_Transform +{ +public: + float rotation; ///< 旋转 + glm::vec2 position; ///< 坐标 + glm::vec2 scale; ///< 缩放 + glm::vec2 skew; ///< 错切角度 + +public: + Y_Transform(/* args */); + + bool IsFast() const + { + return skew.x == 0.f && skew.y == 0.f && + scale.x == 1.f && scale.y == 1.f && + rotation == 0.f; + } + + Matrix3x2 ToMatrix() const; + glm::mat4 GetTransformMatrix() const; +}; diff --git a/source/EngineFrame/Actor/Actor.cpp b/source/EngineFrame/Base/Actor.cpp similarity index 85% rename from source/EngineFrame/Actor/Actor.cpp rename to source/EngineFrame/Base/Actor.cpp index 3994ab6..fe9db83 100644 --- a/source/EngineFrame/Actor/Actor.cpp +++ b/source/EngineFrame/Base/Actor.cpp @@ -18,8 +18,17 @@ void Actor::Init() addTag(Tag::UPDATE); } +void Actor::Update(float deltaTime) +{ + if (!Visible) + return; + BaseNode::Update(deltaTime); +} + void Actor::Render() { + if (!Visible) + return; // 如果有裁切视口 if (this->_CropViewportFlag) { @@ -34,16 +43,6 @@ void Actor::Render() } } -void Actor::AddComponent(RefPtr Component) -{ - BaseNode::AddChild(Component); -} - -void Actor::RemoveComponent(RefPtr Component) -{ - BaseNode::RemoveChild(Component); -} - void Actor::SetCropViewport(SDL_Rect CropViewport) { if (CropViewport.x == 0 && CropViewport.y == 0 && CropViewport.w == 0 && CropViewport.h == 0) diff --git a/source/EngineFrame/Actor/Actor.h b/source/EngineFrame/Base/Actor.h similarity index 81% rename from source/EngineFrame/Actor/Actor.h rename to source/EngineFrame/Base/Actor.h index b9a80c6..cce1872 100644 --- a/source/EngineFrame/Actor/Actor.h +++ b/source/EngineFrame/Base/Actor.h @@ -1,6 +1,5 @@ #pragma once #include "EngineFrame/Base/BaseNode.h" -#include "EngineFrame/Component/Component.h" #include "Tool/IntrusiveList.hpp" class Scene; /** @@ -21,9 +20,8 @@ public: public: void Init() override; + void Update(float deltaTime) override; void Render() override; - void AddComponent(RefPtr Component); - void RemoveComponent(RefPtr Component); // 设置裁切视口(放在Actor里 他与他的子对象都会被裁切) void SetCropViewport(SDL_Rect CropViewport); diff --git a/source/EngineFrame/Base/BaseNode.cpp b/source/EngineFrame/Base/BaseNode.cpp index 639cc92..6e0288f 100644 --- a/source/EngineFrame/Base/BaseNode.cpp +++ b/source/EngineFrame/Base/BaseNode.cpp @@ -27,11 +27,6 @@ void BaseNode::HandleEvents(SDL_Event *e) void BaseNode::Update(float deltaTime) { - // 如果有回调函数,则调用回调函数 - if (cb_update_) - { - cb_update_(deltaTime); - } // 如果有子节点并含有刷新标签,则更新子节点 RefPtr child = m_BaseNodes.GetFirst(); while (child) @@ -40,6 +35,14 @@ void BaseNode::Update(float deltaTime) child->Update(deltaTime); child = child->GetNext(); } + // 如果有回调函数,则调用回调函数 + if (cb_update_.size() > 0) + { + for (auto &cb : cb_update_) + { + cb.second(deltaTime); + } + } } void BaseNode::PreRender() @@ -53,7 +56,6 @@ void BaseNode::PreRender() child = child->GetNext(); } } - void BaseNode::Render() { // 如果有子节点并含有渲染标签,则渲染子节点 @@ -70,9 +72,14 @@ void BaseNode::Clear() { } -void BaseNode::SetCallbackOnUpdate(const UpdateCallback &cb) +void BaseNode::SetCallbackOnUpdate(std::string Key, const UpdateCallback &cb) { - cb_update_ = cb; + cb_update_[Key] = cb; +} + +void BaseNode::RemoveCallbackOnUpdate(std::string Key) +{ + cb_update_.erase(Key); } void BaseNode::SetChildIterationTransform() diff --git a/source/EngineFrame/Base/BaseNode.h b/source/EngineFrame/Base/BaseNode.h index ad29148..b627177 100644 --- a/source/EngineFrame/Base/BaseNode.h +++ b/source/EngineFrame/Base/BaseNode.h @@ -20,7 +20,7 @@ public: public: // 更新时的回调函数 - UpdateCallback cb_update_; + std::map cb_update_; // 节点名称 std::string m_Name; // 子节点列表 @@ -60,8 +60,9 @@ public: /// \~chinese /// @brief 设置更新时的回调函数 - void SetCallbackOnUpdate(const UpdateCallback &cb); - + void SetCallbackOnUpdate(std::string Key,const UpdateCallback &cb); + void RemoveCallbackOnUpdate(std::string Key); + void SetChildIterationTransform(); // 计算渲染信息 diff --git a/source/EngineFrame/Base/Node.cpp b/source/EngineFrame/Base/Node.cpp new file mode 100644 index 0000000..49c4f51 --- /dev/null +++ b/source/EngineFrame/Base/Node.cpp @@ -0,0 +1,549 @@ +#include "Node.h" +#include "EngineCore/Game.h" +void Node::Init() +{ +} +void Node::HandleEvents(SDL_Event *e) +{ +} +inline void Node::Update(float deltaTime) +{ + if (children_.IsEmpty()) + { + return; + } + + RefPtr child = children_.GetFirst(); + while (child) + { + if (child->GetZOrder() >= 0) + break; + + child->Update(deltaTime); + child = child->GetNext(); + } + + UpdateSelf(deltaTime); + + + while (child) + { + child->Update(deltaTime); + child = child->GetNext(); + } +} +inline void Node::PreRender() +{ +} +inline void Node::Render() +{ +} +void Node::Clear() +{ +} + +void Node::UpdateSelf(float deltaTime) +{ + // 如果有回调函数,则调用回调函数 + if (cb_update_.size() > 0) + { + for (auto &cb : cb_update_) + { + cb.second(deltaTime); + } + } +} + +void Node::RemoveFromParent() +{ + if (parent_) + { + parent_->RemoveChild(this); + } +} +inline void Node::PauseUpdating() +{ + update_pausing_ = true; +} +inline void Node::ResumeUpdating() +{ + update_pausing_ = false; +} +inline bool Node::IsUpdatePausing() const +{ + return update_pausing_; +} + +void Node::SetCallbackOnUpdate(std::string Key, const UpdateCallback &cb) +{ + cb_update_[Key] = cb; +} + +void Node::RemoveCallbackOnUpdate(std::string Key) +{ + cb_update_.erase(Key); +} + +bool Node::ContainsPoint(const glm::vec2 &point) const +{ + // if (size_.x == 0.f || size_.y == 0.f) + return false; + // glm::vec2 local = ConvertToLocal(point); + // return local.x >= 0 && local.y >= 0 && local.x <= size_.x && local.y <= size_.y; +} + +glm::vec2 Node::ConvertToLocal(const glm::vec2 &point) const +{ + glm::vec2 local = GetTransformInverseMatrix().Transform(point); + return local; +} + +glm::vec2 Node::ConvertToWorld(const glm::vec2 &point) const +{ + glm::vec2 world = GetTransformMatrix().Transform(point); + return world; +} + +void Node::ShowBorder(bool show) +{ + show_border_ = show; +} + +Node::Node() : visible_(true), update_pausing_(false), show_border_(false), parent_(nullptr), anchor_(0.0f, 0.0f), z_order_(0), opacity_(1.f), name_("Node") +{ + Game::GetInstance().m_nodeCount++; +} + +Node::~Node() +{ + Game::GetInstance().m_nodeCount--; + RemoveAllChildren(); +} + +void Node::UpdateTransform() const +{ + if (!dirty_flag_.Has(DirtyFlag::DirtyTransform)) + return; + dirty_flag_.Unset(DirtyFlag::DirtyTransform); + dirty_flag_.Set(DirtyFlag::DirtyTransformInverse); + dirty_flag_.Set(DirtyFlag::DirtyVisibility); + + if (transform_.IsFast()) + { + transform_matrix_to_parent_ = Matrix3x2::Translation(transform_.position); + } + else + { + transform_matrix_to_parent_ = transform_.ToMatrix(); + } + + glm::vec2 anchor_offset(-size_.width * anchor_.x, -size_.height * anchor_.y); + transform_matrix_to_parent_.Translate(anchor_offset); + + transform_matrix_ = transform_matrix_to_parent_; + if (parent_) + { + transform_matrix_ *= parent_->transform_matrix_; + } + + for (const auto &child : children_) + child->dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +void Node::UpdateTransformUpwards() const +{ + if (parent_) + { + parent_->UpdateTransformUpwards(); + + if (parent_->dirty_flag_.Has(DirtyFlag::DirtyTransform)) + { + dirty_flag_.Set(DirtyFlag::DirtyTransform); + } + } + + UpdateTransform(); +} + +const Matrix3x2 &Node::GetTransformMatrix() const +{ + UpdateTransformUpwards(); + return transform_matrix_; +} + +const Matrix3x2 &Node::GetTransformInverseMatrix() const +{ + UpdateTransformUpwards(); + if (dirty_flag_.Has(DirtyFlag::DirtyTransformInverse)) + { + dirty_flag_.Unset(DirtyFlag::DirtyTransformInverse); + transform_matrix_inverse_ = transform_matrix_.Invert(); + } + return transform_matrix_inverse_; +} + +const Matrix3x2 &Node::GetTransformMatrixToParent() const +{ + UpdateTransformUpwards(); + return transform_matrix_to_parent_; +} + +void Node::Reorder() +{ + if (parent_) + { + RefPtr me = this; + + parent_->children_.Remove(me); + + RefPtr sibling = parent_->children_.GetLast(); + + if (sibling && sibling->GetZOrder() > z_order_) + { + sibling = sibling->GetPrev(); + while (sibling) + { + if (sibling->GetZOrder() <= z_order_) + break; + sibling = sibling->GetPrev(); + } + } + + if (sibling) + { + parent_->children_.InsertAfter(me, sibling); + } + else + { + parent_->children_.PushFront(me); + } + } +} + +inline void Node::RemoveAllChildren() +{ + RefPtr next; + for (RefPtr child = children_.GetFirst(); child; child = next) + { + next = child->GetNext(); + RemoveChild(child); + } +} + +inline bool Node::IsVisible() const +{ + return visible_; +} + +inline int Node::GetZOrder() const +{ + return z_order_; +} + +inline glm::vec2 Node::GetPosition() const +{ + return transform_.position; +} + +inline float Node::GetPositionX() const +{ + return GetPosition().x; +} + +inline float Node::GetPositionY() const +{ + return GetPosition().y; +} + +inline VecSize Node::GetSize() const +{ + return size_; +} + +inline float Node::GetWidth() const +{ + return GetSize().width; +} + +inline float Node::GetHeight() const +{ + return GetSize().height; +} + +inline float Node::GetScaledWidth() const +{ + return GetWidth() * GetScaleX(); +} + +inline float Node::GetScaledHeight() const +{ + return GetHeight() * GetScaleY(); +} + +inline VecSize Node::GetScaledSize() const +{ + return VecSize{GetScaledWidth(), GetScaledHeight()}; +} + +inline glm::vec2 Node::GetAnchor() const +{ + return anchor_; +} + +inline float Node::GetAnchorX() const +{ + return GetAnchor().x; +} + +inline float Node::GetAnchorY() const +{ + return GetAnchor().y; +} + +inline float Node::GetOpacity() const +{ + return opacity_; +} + +inline float Node::GetRotation() const +{ + return transform_.rotation; +} + +inline glm::vec2 Node::GetScale() const +{ + return transform_.scale; +} + +inline float Node::GetScaleX() const +{ + return GetScale().x; +} + +inline float Node::GetScaleY() const +{ + return GetScale().y; +} + +inline glm::vec2 Node::GetSkew() const +{ + return transform_.skew; +} + +inline float Node::GetSkewX() const +{ + return GetSkew().x; +} + +inline float Node::GetSkewY() const +{ + return GetSkew().y; +} + +inline Y_Transform Node::GetTransform() const +{ + return transform_; +} + +inline Node *Node::GetParent() const +{ + return parent_; +} + +inline void Node::SetVisible(bool val) +{ + visible_ = val; +} + +inline void Node::SetName(std::string name) +{ + name_ = name; +} + +inline void Node::SetPosition(const glm::vec2 &pos) +{ + if (transform_.position == pos) + return; + + transform_.position = pos; + dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +inline void Node::SetPosition(float x, float y) +{ + this->SetPosition(glm::vec2(x, y)); +} + +inline void Node::SetPositionX(float x) +{ + this->SetPosition(glm::vec2(x, GetPosition().y)); +} + +inline void Node::SetPositionY(float y) +{ + this->SetPosition(glm::vec2(GetPosition().x, y)); +} + +inline void Node::MoveTo(const glm::vec2 &p) +{ + this->SetPosition(p); +} + +inline void Node::MoveTo(float x, float y) +{ + this->SetPosition(glm::vec2(x, y)); +} + +inline void Node::MoveBy(const glm::vec2 &trans) +{ + this->SetPosition(transform_.position.x + trans.x, transform_.position.y + trans.y); +} + +inline void Node::MoveBy(float trans_x, float trans_y) +{ + this->MoveBy(glm::vec2(trans_x, trans_y)); +} + +inline void Node::SetScale(const glm::vec2 &scale) +{ + if (transform_.scale == scale) + return; + + transform_.scale = scale; + dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +inline void Node::SetScale(float scalex, float scaley) +{ + this->SetScale(glm::vec2(scalex, scaley)); +} + +inline void Node::SetSkew(const glm::vec2 &skew) +{ + if (transform_.skew == skew) + return; + + transform_.skew = skew; + dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +inline void Node::SetSkew(float skewx, float skewy) +{ + this->SetSkew(glm::vec2(skewx, skewy)); +} + +inline void Node::SetRotation(float rotation) +{ + if (transform_.rotation == rotation) + return; + + transform_.rotation = rotation; + dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +inline void Node::SetAnchor(const glm::vec2 &anchor) +{ + if (anchor_ == anchor) + return; + + anchor_ = anchor; + dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +inline void Node::SetAnchor(float anchorx, float anchory) +{ + this->SetAnchor(glm::vec2(anchorx, anchory)); +} + +inline void Node::SetSize(const VecSize &size) +{ + if (size_ == size) + return; + + size_ = size; + dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +inline void Node::SetSize(float width, float height) +{ + this->SetSize(VecSize{width, height}); +} + +inline void Node::SetWidth(float width) +{ + this->SetSize(width, GetHeight()); +} + +inline void Node::SetHeight(float height) +{ + this->SetSize(GetWidth(), height); +} + +inline void Node::SetOpacity(float opacity) +{ + if (opacity_ == opacity) + return; + + opacity_ = std::min(std::max(opacity, 0.f), 1.f); + dirty_flag_.Set(DirtyFlag::DirtyOpacity); +} + +inline void Node::SetTransform(const Y_Transform &transform) +{ + transform_ = transform; + dirty_flag_.Set(DirtyFlag::DirtyTransform); +} + +inline void Node::SetZOrder(int zorder) +{ + if (z_order_ != zorder) + { + z_order_ = zorder; + Reorder(); + } +} + +void Node::AddChild(RefPtr child) +{ + if (child) + { + assert(!child->parent_ && "Actor::AddChild failed, the actor to be added already has a parent"); + + children_.PushBack(child); + child->parent_ = this; + + child->dirty_flag_.Set(DirtyFlag::DirtyTransform); + child->dirty_flag_.Set(DirtyFlag::DirtyOpacity); + child->Reorder(); + } + else + { + SDL_LogError(0, "Actor::AddChild failed, NULL pointer exception"); + } +} + +Node::NodeList &Node::GetAllChildren() +{ + return children_; +} + +const Node::NodeList &Node::GetAllChildren() const +{ + return children_; +} + +inline void Node::RemoveChild(RefPtr child) +{ + if (children_.IsEmpty()) + return; + + if (child) + { + child->parent_ = nullptr; + children_.Remove(child); + } + else + { + SDL_LogError(0, "Actor::RemoveChild failed, NULL pointer exception"); + } +} \ No newline at end of file diff --git a/source/EngineFrame/Base/Node.h b/source/EngineFrame/Base/Node.h new file mode 100644 index 0000000..8a5fab3 --- /dev/null +++ b/source/EngineFrame/Base/Node.h @@ -0,0 +1,355 @@ +#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 + }; +}; diff --git a/source/EngineFrame/Component/Animation.cpp b/source/EngineFrame/Component/Animation.cpp index 227282d..4ccb070 100644 --- a/source/EngineFrame/Component/Animation.cpp +++ b/source/EngineFrame/Component/Animation.cpp @@ -2,7 +2,7 @@ #include "Asset/AssetManager.h" #include "Asset/Asset_Script.h" #include "Tool/Math.h" -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" #include "EngineCore/Game.h" Animation::Animation() diff --git a/source/EngineFrame/Component/Animation.h b/source/EngineFrame/Component/Animation.h index ebf6167..2f2abc3 100644 --- a/source/EngineFrame/Component/Animation.h +++ b/source/EngineFrame/Component/Animation.h @@ -1,5 +1,5 @@ #pragma once -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" #include "EngineFrame/Component/Sprite.h" #include "Asset/AnimationStruct.h" #include diff --git a/source/EngineFrame/Component/Canvas.h b/source/EngineFrame/Component/Canvas.h index 092c2d5..2f63318 100644 --- a/source/EngineFrame/Component/Canvas.h +++ b/source/EngineFrame/Component/Canvas.h @@ -1,5 +1,5 @@ #pragma once -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" #include "EngineFrame/Render/Texture.h" #include "EngineFrame/Component/Sprite.h" class Canvas : public Actor diff --git a/source/EngineFrame/Component/Component.cpp b/source/EngineFrame/Component/Component.cpp deleted file mode 100644 index 86a7b67..0000000 --- a/source/EngineFrame/Component/Component.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "Component.h" -#include "EngineFrame/Actor/Actor.h" - -void Component::Init() -{ - addTag(Tag::COMPONENT); -} diff --git a/source/EngineFrame/Component/Component.h b/source/EngineFrame/Component/Component.h deleted file mode 100644 index e93c7e3..0000000 --- a/source/EngineFrame/Component/Component.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "EngineFrame/Base/BaseNode.h" - -#include -class Actor; -class Component : public BaseNode -{ - -public: - void Init() override; -}; diff --git a/source/EngineFrame/Component/RenderBase.cpp b/source/EngineFrame/Component/RenderBase.cpp index 1074f04..886beb5 100644 --- a/source/EngineFrame/Component/RenderBase.cpp +++ b/source/EngineFrame/Component/RenderBase.cpp @@ -1,13 +1,6 @@ #include "RenderBase.h" -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" -RenderBase::RenderBase() -{ -} - -RenderBase::~RenderBase() -{ -} void RenderBase::CalcRenderInfo() { @@ -16,39 +9,23 @@ void RenderBase::CalcRenderInfo() void RenderBase::Init() { - Component::Init(); - // 标记该组件需要渲染和更新 - addTag(Tag::RENDER); - addTag(Tag::UPDATE); - addTag(Tag::TRANSFORM); // 计算渲染信息 CalcRenderInfo(); } -void RenderBase::Update(float deltaTime) -{ - if (!Visible) - return; - Component::Update(deltaTime); - -} -void RenderBase::Render() -{ - if (!Visible) - return; - Component::Render(); -} + + void RenderBase::SetIterationPos(Vec2 pos) { - Component::SetIterationPos(pos); + Actor::SetIterationPos(pos); CalcRenderInfo(); // 更新渲染信息 } void RenderBase::SetIterationScale(Vec2 scale) { - Component::SetIterationScale(scale); + Actor::SetIterationScale(scale); CalcRenderInfo(); // 更新渲染信息 } @@ -56,31 +33,31 @@ void RenderBase::SetIterationRotation(float angle) { if (!Visible) return; - Component::SetIterationRotation(angle); + Actor::SetIterationRotation(angle); CalcRenderInfo(); // 更新渲染信息 } void RenderBase::SetPos(Vec2 pos) { - Component::SetPos(pos); + Actor::SetPos(pos); CalcRenderInfo(); // 更新渲染信息 } void RenderBase::SetScale(Vec2 scale) { - Component::SetScale(scale); + Actor::SetScale(scale); CalcRenderInfo(); // 更新渲染信息 } void RenderBase::SetRotation(float angle) { - Component::SetRotation(angle); + Actor::SetRotation(angle); CalcRenderInfo(); // 更新渲染信息 } void RenderBase::SetAnchor(Vec2 anchor) { - Component::SetAnchor(anchor); + Actor::SetAnchor(anchor); CalcRenderInfo(); // 更新渲染信息 } diff --git a/source/EngineFrame/Component/RenderBase.h b/source/EngineFrame/Component/RenderBase.h index 98b542c..5279432 100644 --- a/source/EngineFrame/Component/RenderBase.h +++ b/source/EngineFrame/Component/RenderBase.h @@ -1,8 +1,7 @@ #pragma once +#include "EngineFrame/Base/Actor.h" -#include "EngineFrame/Component/Component.h" - -class RenderBase : public Component +class RenderBase : public Actor { public: @@ -19,21 +18,11 @@ public: bool Visible = true; // 是否在屏幕内 bool IsInScreen = false; - //渲染矩阵 - GlMatrix RenderMatrix; }; -public: - RenderBase(/* args */); - ~RenderBase(); - public: void Init() override; - void Update(float deltaTime) override; - void Render() override; - -public: public: // 设置迭代的坐标 void SetIterationPos(Vec2 pos) override; diff --git a/source/EngineFrame/Component/Sprite.cpp b/source/EngineFrame/Component/Sprite.cpp index c800e5a..7ab2917 100644 --- a/source/EngineFrame/Component/Sprite.cpp +++ b/source/EngineFrame/Component/Sprite.cpp @@ -43,35 +43,6 @@ RefPtr Sprite::GetTexture() return m_texture; } -GlMatrix Sprite::matrix3x2ToGLMatrix(const Matrix3x2 &mat) -{ - return { - // 列0:x轴线性变换 - mat._11, // [0][0] - mat._12, // [1][0] - 0.0f, // [2][0] - 0.0f, // [3][0] - - // 列1:y轴线性变换 - mat._21, // [0][1] - mat._22, // [1][1] - 0.0f, // [2][1] - 0.0f, // [3][1] - - // 列2:z轴(固定) - 0.0f, // [0][2] - 0.0f, // [1][2] - 1.0f, // [2][2] - 0.0f, // [3][2] - - // 列3:平移 - mat._31, // [0][3](x平移) - mat._32, // [1][3](y平移) - 0.0f, // [2][3] - 1.0f // [3][3] - }; -} - void Sprite::CalcRenderInfoLogic() { // 获取至在最终的父对象检查是否显示 @@ -105,8 +76,8 @@ void Sprite::CalcRenderInfoLogic() // 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上 auto T_Size = m_texture->getSize(); auto T_Pos = m_texture->getPos(); - float texturePosX = flipX ? -(T_Size.width + T_Pos.x) + SDL_abs(transform.position.x * 2) : T_Pos.x; - float texturePosY = flipY ? -(T_Size.height + T_Pos.y) + SDL_abs(transform.position.y * 2) : T_Pos.y; + float texturePosX = flipX ? -((float)T_Size.width + (float)T_Pos.x) + SDL_fabsf(transform.position.x * 2.0f) : (float)T_Pos.x; + float texturePosY = flipY ? -((float)T_Size.height + (float)T_Pos.y) + SDL_fabsf(transform.position.y * 2.0f) : (float)T_Pos.y; // 先计算Img坐标与精灵坐标合成后的真实坐标 float RealPosX = transform.position.x + texturePosX; @@ -117,22 +88,22 @@ void Sprite::CalcRenderInfoLogic() float baseY = transformIter.position.y + RealPosY; // 获取当前帧的原始尺寸 - int frameWidth = Size.width; - int frameHeight = Size.height; + float frameWidth = (float)Size.width; + float frameHeight = (float)Size.height; // 原始锚点偏移(基于帧尺寸) - float origAnchorOffsetX = int(frameWidth * Anchor.x); - float origAnchorOffsetY = int(frameHeight * Anchor.y); + float origAnchorOffsetX = frameWidth * Anchor.x; + float origAnchorOffsetY = frameHeight * Anchor.y; // 缩放的绝对值 - float absScaleX = SDL_fabs(scaleX); - float absScaleY = SDL_fabs(scaleY); + float absScaleX = SDL_fabsf(scaleX); + float absScaleY = SDL_fabsf(scaleY); // 缩放后的尺寸 float scaledWidth = frameWidth * absScaleX; float scaledHeight = frameHeight * absScaleY; // 缩放后的锚点偏移 - float scaledAnchorOffsetX = int(origAnchorOffsetX * absScaleX); - float scaledAnchorOffsetY = int(origAnchorOffsetY * absScaleY); + float scaledAnchorOffsetX = origAnchorOffsetX * absScaleX; + float scaledAnchorOffsetY = origAnchorOffsetY * absScaleY; // 计算缩放后的锚点偏移与原锚点偏移的差值 float scaleOffsetX = scaledAnchorOffsetX - origAnchorOffsetX; @@ -142,9 +113,6 @@ void Sprite::CalcRenderInfoLogic() float Xpos = baseX - scaleOffsetX; float Ypos = baseY - scaleOffsetY; - Xpos = (int)Xpos; // 强制转换为整数 - Ypos = (int)Ypos; // 强制转换为整数 - // 更新渲染信息 _RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight}; _RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY}; @@ -152,8 +120,8 @@ void Sprite::CalcRenderInfoLogic() m_texture->setAlpha(this->Alpha); // 屏幕内检测 - int screenWidth = Game::GetInstance().Screen_W; - int screenHeight = Game::GetInstance().Screen_H; + float screenWidth = (float)Game::GetInstance().Screen_W; + float screenHeight = (float)Game::GetInstance().Screen_H; bool isInScreen = (Xpos + scaledWidth >= 0 && Xpos <= screenWidth && Ypos + scaledHeight >= 0 && Ypos <= screenHeight); _RenderGuidanceInfo.IsInScreen = isInScreen; diff --git a/source/EngineFrame/Component/Sprite.h b/source/EngineFrame/Component/Sprite.h index f2b4b40..1d3ba67 100644 --- a/source/EngineFrame/Component/Sprite.h +++ b/source/EngineFrame/Component/Sprite.h @@ -33,10 +33,6 @@ public: std::string imgPath; int Index; - Matrix3x2 transform_matrix_; - - GlMatrix matrix3x2ToGLMatrix(const Matrix3x2 &mat); - public: // 计算渲染信息 void CalcRenderInfoLogic(); diff --git a/source/EngineFrame/Component/Text.h b/source/EngineFrame/Component/Text.h index bd66cf0..80a1281 100644 --- a/source/EngineFrame/Component/Text.h +++ b/source/EngineFrame/Component/Text.h @@ -10,7 +10,7 @@ public: ~Text(); // 显式引入基类的Init方法,避免隐藏 - using Component::Init; + using Actor::Init; void Init(std::string Str, TTF_Font *font, SDL_Color color); void Render() override; diff --git a/source/EngineFrame/Render/RenderManager.cpp b/source/EngineFrame/Render/RenderManager.cpp index 13d1357..ad873ab 100644 --- a/source/EngineFrame/Render/RenderManager.cpp +++ b/source/EngineFrame/Render/RenderManager.cpp @@ -28,7 +28,7 @@ RenderManager::RenderManager(SDL_Window *window) _windowHeight = height; // 游戏的初始正交投影矩阵 - _GameOrthoMatrix = glm::ortho(0.0f, (float)width / 1.2f, (float)height / 1.2f, 0.0f, -1.0f, 1.0f); + _GameOrthoMatrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f); // UI的初始正交投影矩阵 _UIOrthoMatrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f); @@ -36,6 +36,7 @@ RenderManager::RenderManager(SDL_Window *window) glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 启用混合模式 glEnable(GL_BLEND); + // 默认设置标准alpha混合 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -228,8 +229,8 @@ void RenderManager::Init2DTextureProgram() glUniform1i(_currentRenderParams.UnimLocs[2], 0); // 处理纹理裁剪 - int texWidth = textureObj->getSize().width; - int texHeight = textureObj->getSize().height; + float texWidth = (float)textureObj->getSize().width; + float texHeight = (float)textureObj->getSize().height; // 计算纹理坐标 float minu, minv, maxu, maxv; @@ -336,6 +337,16 @@ void RenderManager::SetOrthoMatrixType(int type) _OrthoMatrix = _UIOrthoMatrix; } +glm::mat4 RenderManager::GetOrthoMatrix() +{ + return _OrthoMatrix; +} + +void RenderManager::SetOrthoMatrix(glm::mat4 matrix) +{ + _OrthoMatrix = matrix; +} + GLuint RenderManager::CompileShader(GLenum type, std::string Path) { std::ifstream Source("shader/" + Path); diff --git a/source/EngineFrame/Render/RenderManager.h b/source/EngineFrame/Render/RenderManager.h index ec9dc79..60b5a30 100644 --- a/source/EngineFrame/Render/RenderManager.h +++ b/source/EngineFrame/Render/RenderManager.h @@ -78,6 +78,11 @@ public: void DrawTexture(RefPtr texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata = nullptr); // 设置正交投影矩阵类型 void SetOrthoMatrixType(int type); + // 获取渲染的正交投影矩阵 + glm::mat4 GetOrthoMatrix(); + // 设置渲染的正交投影矩阵 + void SetOrthoMatrix(glm::mat4 matrix); + private: diff --git a/source/EngineFrame/Render/Texture.cpp b/source/EngineFrame/Render/Texture.cpp index 6b4fd70..ba455fe 100644 --- a/source/EngineFrame/Render/Texture.cpp +++ b/source/EngineFrame/Render/Texture.cpp @@ -32,8 +32,9 @@ bool Texture::Init(std::string PngPath) glBindTexture(GL_TEXTURE_2D, m_TextureID); // 环绕方式 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // 对2D纹理设置环绕模式(S=X轴,T=Y轴) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 缩小过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 放大过滤:使用最近邻采样 @@ -100,8 +101,9 @@ bool Texture::Init(std::string ImgPath, int Index) // 设置纹理参数(保持与原有SDL纹理相同的采样模式) // 环绕方式:重复 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // 对2D纹理设置环绕模式(S=X轴,T=Y轴) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 过滤方式:最近邻(与SDL_ScaleModeNearest对应) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -139,8 +141,9 @@ bool Texture::Init(SDL_Surface *rgbaSurface) glBindTexture(GL_TEXTURE_2D, m_TextureID); // 环绕方式 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // 对2D纹理设置环绕模式(S=X轴,T=Y轴) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 缩小过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 放大过滤:使用最近邻采样 @@ -192,8 +195,9 @@ bool Texture::Init(VecSize size) m_FrameSize = size; // 环绕方式 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // 对2D纹理设置环绕模式(S=X轴,T=Y轴) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 缩小过滤:使用最近邻采样 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 放大过滤:使用最近邻采样 diff --git a/source/Tool/Common.h b/source/Tool/Common.h index be0aad9..1ad5348 100644 --- a/source/Tool/Common.h +++ b/source/Tool/Common.h @@ -111,12 +111,41 @@ typedef struct VecPos3 } VecPos3; +typedef struct VecFPos3 +{ + float x; + float y; + float z; + VecFPos3(float x_ = 0, float y_ = 0, float z_ = 0) : x(x_), y(y_), z(z_) {} + + VecFPos3 operator+(const VecFPos3 &other) const + { + return VecFPos3(x + other.x, y + other.y, z + other.z); + } + + VecFPos3 operator-(const VecFPos3 &other) const + { + return VecFPos3(x - other.x, y - other.y, z - other.z); + } + + bool operator==(const VecFPos3 &other) const + { + return x == other.x && y == other.y && z == other.z; + } + + bool operator!=(const VecFPos3 &other) const + { + return x != other.x || y != other.y || z != other.z; + } + +} VecFPos3; + typedef struct VecSpeed3 { - int x; - int y; - int z; - VecSpeed3(int x_ = 0, int y_ = 0, int z_ = 0) : x(x_), y(y_), z(z_) {} + float x; + float y; + float z; + VecSpeed3(float x_ = 0, float y_ = 0, float z_ = 0) : x(x_), y(y_), z(z_) {} VecSpeed3 operator+(const VecSpeed3 &other) const { diff --git a/source/math/Math.h b/source/math/Math.h index 57a594e..c7aeff0 100644 --- a/source/math/Math.h +++ b/source/math/Math.h @@ -27,13 +27,13 @@ #include #include + using Vec2 = ember::math::Vec2T; using VecPos = ember::math::Vec2T; using Rect = ember::math::RectT; using Matrix3x2 = ember::math::Matrix3x2T; using Transform = ember::math::TransformT; -using GlMatrix = std::array; using Point = Vec2; using Size = Vec2; diff --git a/source/math/Matrix.hpp b/source/math/Matrix.hpp index b8eba37..ef08fea 100644 --- a/source/math/Matrix.hpp +++ b/source/math/Matrix.hpp @@ -20,8 +20,12 @@ #pragma once #include +#include #include #include +#include +#include +#include namespace ember { @@ -34,7 +38,7 @@ namespace ember struct Matrix3x2T { using ValueType = _Ty; - using Vec2Type = Vec2T; + using Vec2Type = glm::vec2; using RectType = RectT; union @@ -160,13 +164,13 @@ namespace ember return RectType{left, top, right, bottom}; } - inline void Translate(const Vec2Type &v) + inline void Translate(const glm::vec2 &v) { _31 += _11 * v.x + _21 * v.y; _32 += _12 * v.x + _22 * v.y; } - static inline Matrix3x2T Translation(const Vec2Type &v) + static inline Matrix3x2T Translation(const glm::vec2 &v) { return Matrix3x2T(1.f, 0.f, 0.f, 1.f, v.x, v.y); } diff --git a/source_game/Actor/Map/GameMap.cpp b/source_game/Actor/Map/GameMap.cpp index 7060917..19498a8 100644 --- a/source_game/Actor/Map/GameMap.cpp +++ b/source_game/Actor/Map/GameMap.cpp @@ -1,10 +1,10 @@ #include "GameMap.h" #include "Asset/AssetManager.h" +#include "EngineCore/Game.h" #include "EngineFrame/Scene/Scene.h" #include "EngineFrame/Component/Animation.h" -#include "Actor/Map/GameMapCamera.h" +#include "Global/Global_Game.h" #include "Actor/Object/CharacterObject.h" -#include "EngineCore/Game.h" GameMap::GameMap() { @@ -217,34 +217,21 @@ void GameMap::InitTile() { NormalTileCount = tileArr.size(); _MapLength = NormalTileCount * 224; - for (int i = 0; i < NormalTileCount; i++) - { - std::string path = tileArr[i]; - RefPtr tile = new Tile(path); - tile->SetPos(Vec2{i * 224, -200 - std::get(_MapInfo["background_pos"])}); - _LayerMap["bottom"]->AddComponent(tile); - } _MapHeight = 560; } - if (_MapInfo.count("extended_tile")) + if (!_MapInfo.count("extended_tile")) + return; + + std::vector extileArr = std::get>(_MapInfo["extended_tile"]); + if (extileArr.size() > 0) { - std::vector extileArr = std::get>(_MapInfo["extended_tile"]); - if (extileArr.size() > 0) - { - int ExTileCount = extileArr.size(); - int Buffer = (ExTileCount / NormalTileCount); - _MapHeight += (Buffer < 1 ? 1 : Buffer) * 40; - for (int i = 0; i < ExTileCount; i++) - { - std::string path = extileArr[i]; - RefPtr tile = new Tile(path); - int xbuf = i % NormalTileCount * 224; - int ybuf = -200 - std::get(_MapInfo["background_pos"]) + NormalTileHeight + 120 * (i / NormalTileCount); - tile->SetPos(Vec2{xbuf, ybuf}); - _LayerMap["bottom"]->AddComponent(tile); - } - } + int ExTileCount = extileArr.size(); + int Buffer = (ExTileCount / NormalTileCount); + _MapHeight += (Buffer < 1 ? 1 : Buffer) * 40; } + + _Tile = new Tile(this, tileArr, extileArr); + _LayerMap["bottom"]->AddChild(_Tile); } void GameMap::InitBackgroundAnimation() @@ -340,45 +327,42 @@ void GameMap::LoadMap(std::string mapName) void GameMap::Enter(Scene *scene) { - _Scene = scene; - scene->AddChild(_LayerMap["contact"]); - scene->AddChild(_LayerMap["distantback"]); - scene->AddChild(_LayerMap["middleback"]); - scene->AddChild(_LayerMap["bottom"]); - scene->AddChild(_LayerMap["closeback"]); - scene->AddChild(_LayerMap["normal"]); - scene->AddChild(_LayerMap["close"]); - scene->AddChild(_LayerMap["cover"]); - scene->AddChild(_LayerMap["max"]); -} - -void GameMap::HandleEvents(SDL_Event *e) -{ + AddChild(_LayerMap["contact"]); + AddChild(_LayerMap["distantback"]); + AddChild(_LayerMap["middleback"]); + AddChild(_LayerMap["bottom"]); + AddChild(_LayerMap["closeback"]); + AddChild(_LayerMap["normal"]); + AddChild(_LayerMap["close"]); + AddChild(_LayerMap["cover"]); + AddChild(_LayerMap["max"]); } void GameMap::Update(float deltaTime) { - if (_Scene->GetCamera() == nullptr) + Actor::Update(deltaTime); + + RefPtr Cam = Global_Game::GetInstance().GetCamera(); + if (Cam == nullptr) return; - GameMapCamera *Cam = (GameMapCamera *)(_Scene->GetCamera().Get()); - int targetX = Cam->_currentPosition.x; - int targetY = Cam->_currentPosition.y; + float targetX = Cam->_currentPosition.x; + float targetY = Cam->_currentPosition.y; // 屏幕中心 - int width_Separate = 1067 / 2; - int height_Separate = 600 / 2; + float width_Separate = 1280.0f / 1.2f / 2.0f; + float height_Separate = 600.0f / 2.0f; // 获取摄像机可行区域限制 auto limitIt = _MapInfo.find("limit_map_camera_move"); if (limitIt != _MapInfo.end()) { std::vector limit = std::get>(_MapInfo["limit_map_camera_move"]); - int X_Limit_Min = limit[0]; - int X_Limit_Max = limit[1]; - int Y_Limit_Min = limit[2]; - int Y_Limit_Max = limit[3]; + float X_Limit_Min = limit[0]; + float X_Limit_Max = limit[1]; + float Y_Limit_Min = limit[2]; + float Y_Limit_Max = limit[3]; // 应用地图边界限制 - targetX = std::clamp(targetX, width_Separate, _MapLength - width_Separate); - targetY = std::clamp(targetY, height_Separate, _MapHeight - height_Separate); + targetX = std::clamp(targetX, width_Separate, (float)_MapLength - width_Separate); + targetY = std::clamp(targetY, height_Separate, (float)_MapHeight - height_Separate); // 应用自定义摄像机移动限制 if (X_Limit_Min != -1) targetX = std::max(targetX, X_Limit_Min); @@ -393,12 +377,12 @@ void GameMap::Update(float deltaTime) // 更新图层位置 for (auto &Layer : _LayerMap) { - int posX = -targetX + width_Separate; - int posY = -targetY + height_Separate + MapOffsetY; + float posX = -targetX + width_Separate; + float posY = -targetY + height_Separate + MapOffsetY; if (Layer.first == "distantback") { posX *= BackgroundMoveSpeed; - posX /= 100; + posX /= 100.0f; } Layer.second->SetPos(Vec2(posX, posY)); } @@ -412,14 +396,17 @@ void GameMap::AddObject(RefPtr object) if (object->m_objecttype == ObjectType::CHARACTER) { CharacterObject *chr = (CharacterObject *)(object.Get()); - if( chr->_Shadow != nullptr)_LayerMap["bottom"]->AddComponent(chr->_Shadow); + Global_Game::GetInstance().GetCamera()->SetFromActor(chr); + + if (chr->_Shadow) + _LayerMap["bottom"]->AddChild(chr->_Shadow); } } -VecPos3 GameMap::CheckIsItMovable(VecPos3 CurPos, VecPos3 PosOffset) +VecFPos3 GameMap::CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset) { // 初始化结果为原坐标(默认不移动) - VecPos3 result = CurPos; + VecFPos3 result = CurPos; // 如果没有可移动区域限制,直接全量位移 if (_MovableArea.empty()) diff --git a/source_game/Actor/Map/GameMap.h b/source_game/Actor/Map/GameMap.h index 8fea3ee..aff7d3c 100644 --- a/source_game/Actor/Map/GameMap.h +++ b/source_game/Actor/Map/GameMap.h @@ -8,7 +8,7 @@ class BaseObject; class GameMapCamera; -class GameMap +class GameMap : public Actor { struct BackGroundAni { @@ -58,6 +58,8 @@ public: std::string _MapPath; // 地图文件夹 std::string _MapDir; + // 地板画布 + RefPtr _Tile = nullptr; // 地图宽度 int _MapLength = 0; // 地图高度 @@ -70,8 +72,6 @@ public: public: // 图层Map 图层类型 显示对象 std::unordered_map> _LayerMap; - // 所属场景 - Scene *_Scene = nullptr; // 背景层移动速率 int BackgroundMoveSpeed = 103; @@ -88,11 +88,10 @@ public: void InitMapAnimation(); void InitVirtualMovableArea(); void Enter(Scene *scene); - void HandleEvents(SDL_Event *e); - void Update(float deltaTime); + void Update(float deltaTime) override; void AddObject(RefPtr object); public: // 检查是否可移动 - VecPos3 CheckIsItMovable(VecPos3 CurPos, VecPos3 PosOffset); + VecFPos3 CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset); }; diff --git a/source_game/Actor/Map/GameMapCamera.h b/source_game/Actor/Map/GameMapCamera.h deleted file mode 100644 index 172fa2f..0000000 --- a/source_game/Actor/Map/GameMapCamera.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "EngineFrame/Actor/Actor.h" -class GameMap; -class BaseObject; -class GameMapCamera : public Actor -{ -private: - // 跟随对象 - BaseObject *_FromActor = nullptr; - -public: - // 摄像机记录的跟随对象坐标 - VecPos3 FromActorPos = {0, 0, 0}; - - // 缩放比率 - float CameraRate = 1.0; - - // 添加平滑移动相关的成员变量 - bool _isSmoothMoving = false; - VecPos _currentPosition; // 当前摄像机位置 - VecPos _velocity; // 当前移动速度(用于平滑移动) - float _smoothTime = 0.1f; // 平滑时间(秒),可调整 - int _maxSpeed = 2000; // 最大移动速度,防止过快 - -public: - GameMapCamera(); - ~GameMapCamera(); - - void SetFromActor(BaseObject *actor); - void Update(float deltaTime); - - void SetPos(int x, int y, int z); - void AddPos(int x, int y, int z); - - //同步坐标相关 - void SyncPos(float deltaTime); - void SyncPosByFromParent(float deltaTime); - - // 平滑阻尼函数(类似Unity的Mathf.SmoothDamp) - VecPos SmoothDamp(const VecPos ¤t, const VecPos &target, VecPos ¤tVelocity, float smoothTime, int maxSpeed, float deltaTime); -}; diff --git a/source_game/Actor/Map/GameMapLayer.cpp b/source_game/Actor/Map/GameMapLayer.cpp index 7b6e2d4..63c7b24 100644 --- a/source_game/Actor/Map/GameMapLayer.cpp +++ b/source_game/Actor/Map/GameMapLayer.cpp @@ -1,31 +1,25 @@ #include "GameMapLayer.h" #include "EngineCore/Game.h" -GameMapLayer::GameMapLayer() -{ -} - -GameMapLayer::~GameMapLayer() -{ -} void GameMapLayer::Render() { - Actor::Render(); - RenderManager *renderer = Game::GetInstance().GetRenderer(); - // 自身坐标 - float Xpos = GetIterationPos().x + GetPos().x; - float Ypos = GetIterationPos().y + GetPos().y; - for (auto &info : this->FeasibleAreaInfoList) - { - SDL_Rect buf; - buf.x = info.x + Xpos; - buf.y = info.y + Ypos; - buf.w = info.w; - buf.h = info.h; - //TODO: 渲染可行区域 - } + Actor::Render(); + // RenderManager *renderer = Game::GetInstance().GetRenderer(); + + // // 自身坐标 + // float Xpos = GetIterationPos().x + GetPos().x; + // float Ypos = GetIterationPos().y + GetPos().y; + // for (auto &info : this->FeasibleAreaInfoList) + // { + // SDL_Rect buf; + // buf.x = info.x + Xpos; + // buf.y = info.y + Ypos; + // buf.w = info.w; + // buf.h = info.h; + // //TODO: 渲染可行区域 + // } } void GameMapLayer::AddDebugFeasibleAreaInfo(Vec2 pos, VecSize size) diff --git a/source_game/Actor/Map/GameMapLayer.h b/source_game/Actor/Map/GameMapLayer.h index eebcdad..60351bc 100644 --- a/source_game/Actor/Map/GameMapLayer.h +++ b/source_game/Actor/Map/GameMapLayer.h @@ -1,6 +1,6 @@ #pragma once -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" #include "EngineFrame/Component/Sprite.h" class BaseObject; @@ -11,9 +11,6 @@ private: std::vector FeasibleAreaInfoList; public: - GameMapLayer(/* args */); - ~GameMapLayer(); - // 重载Render以实现绘制可行区域 void Render() override; // 添加调试可行区域信息 diff --git a/source_game/Actor/Map/Tile.cpp b/source_game/Actor/Map/Tile.cpp index f1f6c52..2f4ef4a 100644 --- a/source_game/Actor/Map/Tile.cpp +++ b/source_game/Actor/Map/Tile.cpp @@ -1,33 +1,137 @@ #include "Tile.h" #include "Tool/Tool_String.h" #include "EngineCore/Game.h" -Tile::Tile() -{ -} +#include "Actor/Map/GameMap.h" +#include "Global/Global_Game.h" -Tile::Tile(std::string Path) : Sprite() -{ - InitInfo(Path); - if (std::get(m_data["path"]) == "") - m_data["path"] = "sprite/character/common/circlecooltime.img"; +// Tile::Tile(std::string Path) : Sprite() +// { +// InitInfo(Path); +// if (std::get(m_data["path"]) == "") +// m_data["path"] = "sprite/character/common/circlecooltime.img"; +// m_texture = new Texture(); +// m_texture->Init(std::get(m_data["path"]), std::get(m_data["idx"])); +// Sprite::Init(); +// this->imgPath = Path; +// } + +Tile::Tile(GameMap *parentMap, std::vector normal, std::vector ex) +{ + m_parentMap = parentMap; m_texture = new Texture(); - m_texture->Init(std::get(m_data["path"]), std::get(m_data["idx"])); - Sprite::Init(); - this->imgPath = Path; + + // 通过父对象获取地图大小 + int Width = m_parentMap->_MapLength; + int Height = m_parentMap->_MapHeight; + + // 通过大小纹理大小 + m_texture->Init(VecSize(Width, Height)); + m_rect = {0, 0, (float)Width, (float)Height}; + + Actor::Init(); + + glGenFramebuffers(1, &m_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + // 将目标纹理附加到FBO的颜色附着点 + glFramebufferTexture2D( + GL_FRAMEBUFFER, // 帧缓冲类型 + GL_COLOR_ATTACHMENT0, // 颜色附着点(可多个,这里用第一个) + GL_TEXTURE_2D, // 纹理类型 + m_texture->getID(), // 目标纹理ID + 0 // 多级渐远纹理级别 + ); + glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO + + for (size_t i = 0; i < normal.size(); i++) + { + InitTile(normal[i], i); + } + m_tileX = normal.size(); + for (size_t i = 0; i < ex.size(); i++) + { + InitExTile(ex[i], i); + } + + SetPos(Vec2(0, 80 - 200 - std::get(m_parentMap->_MapInfo["background_pos"]))); } Tile::~Tile() { } -void Tile::SetPos(Vec2 pos) +void Tile::InitTile(std::string Path, int Index) { - pos.y += std::get(m_data["pos"]); - Sprite::SetPos(pos); + // 读取文件 + TileInfo data; + InitInfo(Path, data); + // 读取信息 + std::string path = std::get(data["path"]); + int index = std::get(data["idx"]); + // 如果是个空地板 给他默认赋值 + if (path == "") + path = "sprite/character/common/circlecooltime.img"; + + // 构造纹理标识符 + ImgKey key = {path, index}; + // 判断是否存在标识符对应的纹理,如果不存在则创建 + if (m_imgMap.find(key) == m_imgMap.end()) + { + RefPtr tex = new Texture(); + tex->Init(path, index); + m_imgMap[key] = tex; + } + // 构造绘制信息 + DrawInfo info; + info.rect.x = Index * m_imgMap[key]->getSize().width + m_imgMap[key]->getPos().x; + info.rect.y = m_imgMap[key]->getPos().y; + info.rect.w = m_imgMap[key]->getSize().width; + info.rect.h = m_imgMap[key]->getSize().height; + info.texture = key; + // 添加到绘制信息列表 + m_drawQueue.push_back(info); } -void Tile::InitInfo(std::string Path) +void Tile::InitExTile(std::string Path, int Index) +{ + // 读取文件 + TileInfo data; + InitInfo(Path, data); + // 读取信息 + std::string path = std::get(data["path"]); + int index = std::get(data["idx"]); + // 如果是个空地板 给他默认赋值 + if (path == "") + path = "sprite/character/common/circlecooltime.img"; + + // 构造纹理标识符 + ImgKey key = {path, index}; + // 判断是否存在标识符对应的纹理,如果不存在则创建 + if (m_imgMap.find(key) == m_imgMap.end()) + { + RefPtr tex = new Texture(); + tex->Init(path, index); + m_imgMap[key] = tex; + } + + // 构造绘制信息 + DrawInfo info; + info.rect.x = Index * m_imgMap[key]->getSize().width + m_imgMap[key]->getPos().x; + info.rect.y = m_imgMap[key]->getPos().y + 560 + ((Index / m_tileX) * 120); + info.rect.w = m_imgMap[key]->getSize().width; + info.rect.h = m_imgMap[key]->getSize().height; + info.texture = key; + // 添加到绘制信息列表 + m_drawQueue.push_back(info); +} + +// void Tile::SetPos(Vec2 pos) +// { +// // pos.y += std::get(m_data["pos"]); +// // Sprite::SetPos(pos); +// } + +void Tile::InitInfo(std::string Path, TileInfo &m_data) { ScriptData Data = AssetManager::GetInstance().GetScriptInfo(Path); m_data["pos"] = 0; @@ -46,3 +150,47 @@ void Tile::InitInfo(std::string Path) } } } + +void Tile::PreRender() +{ + m_rect.x = GetWorldPos().x; + m_rect.y = GetWorldPos().y; + + //计算摄像机位置 知道自己需要渲染多大的区域 + // m_srcRect = {0, 0, m_parentMap->_MapLength, m_parentMap->_MapHeight}; + // Vec2 Pos = Global_Game::GetInstance().GetCamera() -> _currentPosition; + // m_srcRect = {Pos.x < 1067 ? 0 : Pos.x - 1067, Pos.y, 1067, 600}; +} + +void Tile::Render() +{ + RenderManager *renderer = Game::GetInstance().GetRenderer(); + SDL_FPoint AnchorPos = {0, 0}; + if (!m_isBuild) + { + // 保存原始的正交矩阵 设置纹理对应的正交矩阵 和 视口 + auto oldOm = Game::GetInstance().GetRenderer()->GetOrthoMatrix(); + Game::GetInstance().GetRenderer()->SetOrthoMatrix(glm::ortho(0.0f, (float)m_texture->getSize().width, (float)m_texture->getSize().height, 0.0f, -1.0f, 1.0f)); + glViewport(0, 0, m_texture->getSize().width, m_texture->getSize().height); + + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // 绑定FBO + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + for (auto &info : m_drawQueue) + { + renderer->DrawTexture(m_imgMap[info.texture], nullptr, &info.rect, 0.f, &AnchorPos, SDL_FLIP_NONE); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO + + // 还原原始的正交矩阵 和 视口 + Game::GetInstance().GetRenderer()->SetOrthoMatrix(oldOm); + glViewport(0, 0, Game::GetInstance().Screen_W, Game::GetInstance().Screen_H); + m_isBuild = true; + } + + renderer->SetCurrentShaderProgram("flip_y"); + + renderer->DrawTexture(m_texture, nullptr, &m_rect, 0.f, &AnchorPos, SDL_FLIP_NONE); + + renderer->SetCurrentShaderProgram("normal"); +} diff --git a/source_game/Actor/Map/Tile.h b/source_game/Actor/Map/Tile.h index 5578d94..b2a1343 100644 --- a/source_game/Actor/Map/Tile.h +++ b/source_game/Actor/Map/Tile.h @@ -1,22 +1,65 @@ #pragma once #include "Asset/AssetManager.h" -#include "EngineFrame/Component/Sprite.h" -class Tile : public Sprite +#include "EngineFrame/Component/Canvas.h" +class GameMap; +class Tile : public Actor { + struct ImgKey + { + std::string img; + int index; - using TileInfoBody = std::variant< - int, - std::string>; - -private: - std::unordered_map m_data; + bool operator<(const ImgKey &other) const + { + if (img != other.img) + { + return img < other.img; // 字符串按字典序比较 + } + return index < other.index; // 字符串相同则比较index + } + }; + struct DrawInfo + { + ImgKey texture; + SDL_FRect rect = {0, 0, 0, 0}; + }; public: - Tile(/* args */); - Tile(std::string Path); + using TileInfoBody = std::variant; + using TileInfo = std::unordered_map; + +private: + /**纹理 */ + RefPtr m_texture = nullptr; + /**FBO */ + GLuint m_fbo = 0; + /**地图父对象 */ + GameMap* m_parentMap; + + /**绘制纹理集 */ + std::map> m_imgMap; + /**绘制队列 */ + std::vector m_drawQueue; + + /**渲染大小 */ + SDL_Rect m_srcRect; + SDL_FRect m_rect; + + /**大纹理构造完成Flag */ + bool m_isBuild = false; + + /**Tile横轴个数 */ + int m_tileX = 0; + +public: + Tile(GameMap *parentMap, std::vector normal,std::vector ex); ~Tile(); - void SetPos(Vec2 pos) override; + void InitTile(std::string Path,int Index); + void InitExTile(std::string Path, int Index); + void InitInfo(std::string Path, TileInfo &m_data); - void InitInfo(std::string Path); + void PreRender() override; + void Render() override; + // void SetPos(Vec2 pos) override; }; diff --git a/source_game/Actor/Object/ActiveObject.cpp b/source_game/Actor/Object/ActiveObject.cpp index b375d00..26cfdd1 100644 --- a/source_game/Actor/Object/ActiveObject.cpp +++ b/source_game/Actor/Object/ActiveObject.cpp @@ -1,5 +1,5 @@ #include "ActiveObject.h" -void ActiveObject::SetPosition(VecPos3 pos) +void ActiveObject::SetPosition(VecFPos3 pos) { BaseObject::SetPosition(pos); } @@ -21,49 +21,36 @@ VecSpeed3 ActiveObject::GetSpeed() void ActiveObject::Update(float deltaTime) { - int IntegerDelta = static_cast(deltaTime * 1000); - const int Gravity = 1020; + VecFPos3 MovePos; // X轴移动(含余数补偿) if (Speed.x != 0) { - int totalX = Speed.x * IntegerDelta + Remainder.x; // 加上上次余数 - int moveX = totalX / 1000; // 整数部分为实际移动 - Remainder.x = totalX % 1000; // 保留余数(-999~999) - MoveBy(moveX, 0, 0); + MovePos.x = Speed.x * deltaTime; } // Y轴移动(同上) if (Speed.y != 0) { - int totalY = Speed.y * IntegerDelta + Remainder.y; - int moveY = totalY / 1000; - Remainder.y = totalY % 1000; - MoveBy(0, moveY, 0); + MovePos.y = Speed.y * deltaTime; } // Z轴重力与移动(含余数补偿) if (Position.z > 0 || Speed.z > 0) { - // 重力对速度的影响(先更新Speed.z,含余数) - int speedZTotal = -Gravity * IntegerDelta + Remainder.z; // 注意负号(减速) - Speed.z += speedZTotal / 1000; // 速度的整数部分 - Remainder.z = speedZTotal % 1000; // 速度的余数 + int speedZTotal = -1020 * deltaTime; // 基于更新后的Speed.z计算移动量(同样含余数) - int moveZTotal = Speed.z * IntegerDelta + _zRemainderMove; // 新增_zRemainderMove记录移动余数 - int moveZ = moveZTotal / 1000; - _zRemainderMove = moveZTotal % 1000; - MoveBy(0, 0, moveZ); + MovePos.z = Speed.z * deltaTime; } else if (Position.z < 0) { Position.z = 0; Speed.z = 0; - Remainder.z = 0; // 重置余数 - _zRemainderMove = 0; SetPosition(Position); } + MoveBy(MovePos); + BaseObject::Update(deltaTime); } diff --git a/source_game/Actor/Object/ActiveObject.h b/source_game/Actor/Object/ActiveObject.h index 09f721f..b0022ca 100644 --- a/source_game/Actor/Object/ActiveObject.h +++ b/source_game/Actor/Object/ActiveObject.h @@ -7,13 +7,12 @@ class ActiveObject : public BaseObject public: // 三轴速度 VecSpeed3 Speed; - // 三轴移动余数 - VecPos3 Remainder; + int _zRemainderMove = 0; public: void - SetPosition(VecPos3 pos) override; + SetPosition(VecFPos3 pos) override; void SetYpos(int y) override; void SetSpeed(VecSpeed3 speed); diff --git a/source_game/Actor/Object/BaseObject.cpp b/source_game/Actor/Object/BaseObject.cpp index c7cba11..8b0d0d5 100644 --- a/source_game/Actor/Object/BaseObject.cpp +++ b/source_game/Actor/Object/BaseObject.cpp @@ -1,6 +1,5 @@ #include "BaseObject.h" #include "Actor/Map/GameMap.h" -#include "Actor/Map/GameMapCamera.h" BaseObject::BaseObject() { @@ -14,15 +13,13 @@ BaseObject::~BaseObject() void BaseObject::Update(float deltaTime) { - if (_AffCamera != nullptr) - { - _AffCamera->SyncPos(deltaTime); - } Actor::Update(deltaTime); } -void BaseObject::SetPosition(VecPos3 pos) +void BaseObject::SetPosition(VecFPos3 pos) { + if(pos == this->Position) + return; if (pos.y != this->Position.y) { SetRenderZOrder(pos.y); // 设置渲染顺序 @@ -31,19 +28,23 @@ void BaseObject::SetPosition(VecPos3 pos) SetPos(Vec2{this->Position.x, this->Position.y - this->Position.z}); } -VecPos3 BaseObject::GetPosition() +VecFPos3 BaseObject::GetPosition() { return this->Position; } void BaseObject::SetXpos(int x) { + if (x == this->Position.x) + return; this->Position.x = x; SetPos({this->Position.x, this->Position.y - this->Position.z}); } void BaseObject::SetYpos(int y) { + if (y == this->Position.y) + return; if (y != this->Position.y) { SetRenderZOrder(y); // 设置渲染顺序 @@ -54,6 +55,8 @@ void BaseObject::SetYpos(int y) void BaseObject::SetZpos(int z) { + if (z == this->Position.z) + return; this->Position.z = z; SetPos({this->Position.x, this->Position.y - this->Position.z}); } @@ -73,10 +76,12 @@ int BaseObject::GetZpos() return this->Position.z; } -void BaseObject::MoveBy(VecPos3 pos) +void BaseObject::MoveBy(VecFPos3 pos) { // 只有moveby移动时判断所在地图中是否能够这样移动 - VecPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), pos); + VecFPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), pos); + if (RealPos == this->Position) + return; if (RealPos.y != this->Position.y) { SetRenderZOrder(RealPos.y); // 设置渲染顺序 @@ -90,7 +95,9 @@ void BaseObject::MoveBy(VecPos3 pos) void BaseObject::MoveBy(int x, int y, int z) { // 只有moveby移动时判断所在地图中是否能够这样移动 - VecPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), VecPos3({x, y, z})); + VecFPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), VecFPos3({x, y, z})); + if (RealPos == this->Position) + return; if (RealPos.y != this->Position.y) { SetRenderZOrder(RealPos.y); // 设置渲染顺序 diff --git a/source_game/Actor/Object/BaseObject.h b/source_game/Actor/Object/BaseObject.h index b7dd02d..8bd0cb0 100644 --- a/source_game/Actor/Object/BaseObject.h +++ b/source_game/Actor/Object/BaseObject.h @@ -1,18 +1,16 @@ #pragma once -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" #include "Asset/Common/ObjectVars.h" #include "Global/Global_Enum.h" class GameMap; -class GameMapCamera; class BaseObject : public Actor { public: public: ObjectType m_objecttype; // 对象类型 - VecPos3 Position; // 位置 + VecFPos3 Position; // 位置 int Direction = 0; // 方向 GameMap *_AffMap = nullptr; // 所在地图 - GameMapCamera *_AffCamera = nullptr; // 跟随相机 public: BaseObject(/* args */); @@ -24,17 +22,17 @@ public: ObjectVars _ObjectVars; public: - virtual void SetPosition(VecPos3 pos); + virtual void SetPosition(VecFPos3 pos); virtual void SetXpos(int x); virtual void SetYpos(int y); virtual void SetZpos(int z); - VecPos3 GetPosition(); + VecFPos3 GetPosition(); int GetXpos(); int GetYpos(); int GetZpos(); - virtual void MoveBy(VecPos3 pos); + virtual void MoveBy(VecFPos3 pos); virtual void MoveBy(int x, int y, int z); virtual void SetDirection(int dir); diff --git a/source_game/Asset/Character/Chr_Equipment.h b/source_game/Asset/Character/Chr_Equipment.h index 35dcdc7..cd63f66 100644 --- a/source_game/Asset/Character/Chr_Equipment.h +++ b/source_game/Asset/Character/Chr_Equipment.h @@ -1,9 +1,8 @@ #pragma once -#include "EngineFrame/Component/Component.h" #include "Asset/Common/Equipment.h" - +#include "EngineFrame/Base/Actor.h" class CharacterObject; -class Chr_Equipment : public Component +class Chr_Equipment : public Actor { public: // 默认装备 diff --git a/source_game/Asset/Character/Chr_StateMachine.h b/source_game/Asset/Character/Chr_StateMachine.h index 68a3494..b6ae9d4 100644 --- a/source_game/Asset/Character/Chr_StateMachine.h +++ b/source_game/Asset/Character/Chr_StateMachine.h @@ -1,9 +1,8 @@ #pragma once -#include "EngineFrame/Component/Component.h" #include "Global/Global_Enum.h" - +#include "EngineFrame/Base/Actor.h" class CharacterObject; -class Chr_StateMachine : public Component +class Chr_StateMachine : public Actor { private: // 父对象 diff --git a/source_game/Asset/Common/Equipment.h b/source_game/Asset/Common/Equipment.h index d0a0d66..2dbc514 100644 --- a/source_game/Asset/Common/Equipment.h +++ b/source_game/Asset/Common/Equipment.h @@ -1,7 +1,7 @@ #pragma once -#include "EngineFrame/Component/Component.h" #include "Global/Global_Enum.h" -class Equipment : public Component +#include "EngineFrame/Base/Actor.h" +class Equipment : public Actor { public: // 职业动画结构体 diff --git a/source_game/Asset/Squirrel/Sqr_BaseObject.hpp b/source_game/Asset/Squirrel/Sqr_BaseObject.hpp index 75ae349..7d8a487 100644 --- a/source_game/Asset/Squirrel/Sqr_BaseObject.hpp +++ b/source_game/Asset/Squirrel/Sqr_BaseObject.hpp @@ -15,7 +15,7 @@ static SQInteger SQR_GetPosition(HSQUIRRELVM v) SQUserPointer ptr; sq_getuserpointer(v, 2, &ptr); BaseObject *obj = (BaseObject *)ptr; - VecPos3 Pos = obj->GetPosition(); + VecFPos3 Pos = obj->GetPosition(); sq_newtable(v); sq_pushstring(v, _SC("x"), -1); @@ -40,7 +40,7 @@ static SQInteger SQR_SetPosition(HSQUIRRELVM v) sq_getfloat(v, 3, &PosX); sq_getfloat(v, 4, &PosY); sq_getfloat(v, 5, &PosZ); - obj->SetPosition(VecPos3(PosX, PosY, PosZ)); + obj->SetPosition(VecFPos3(PosX, PosY, PosZ)); return 0; } diff --git a/source_game/Asset/Squirrel/Sqr_CommonFunc.hpp b/source_game/Asset/Squirrel/Sqr_CommonFunc.hpp index 598beb1..88c65b3 100644 --- a/source_game/Asset/Squirrel/Sqr_CommonFunc.hpp +++ b/source_game/Asset/Squirrel/Sqr_CommonFunc.hpp @@ -1,7 +1,7 @@ #pragma once #include "squirrel/SquirrelEx.h" #include "Global/Global_Game.h" -#include "EngineFrame/Actor/Actor.h" +#include "EngineFrame/Base/Actor.h" static SQRESULT sq_GetVecSize(HSQUIRRELVM v, int Index, VecSize *Size) { diff --git a/source_game/Actor/Map/GameMapCamera.cpp b/source_game/Global/GameCamera.cpp similarity index 55% rename from source_game/Actor/Map/GameMapCamera.cpp rename to source_game/Global/GameCamera.cpp index 598c34c..bd0be79 100644 --- a/source_game/Actor/Map/GameMapCamera.cpp +++ b/source_game/Global/GameCamera.cpp @@ -1,59 +1,58 @@ -#include "GameMapCamera.h" +#include "GameCamera.h" #include "EngineCore/Game.h" #include "Actor/Map/GameMap.h" #include "Actor/Object/BaseObject.h" +#include "Global/Global_Game.h" #include -GameMapCamera::GameMapCamera() -{ -} - -GameMapCamera::~GameMapCamera() -{ -} - -void GameMapCamera::SetFromActor(BaseObject *actor) +void GameCamera::SetFromActor(BaseObject *actor) { + // 如果原来有跟随对象 + if (this->_FromActor) + { + this->_FromActor->RemoveCallbackOnUpdate("Camear Update"); + } this->_FromActor = actor; - _FromActor->_AffCamera = this; + actor->SetCallbackOnUpdate("Camear Update", [](float deltaTime) mutable + { Global_Game::GetInstance().GetCamera()->Update(deltaTime); }); } -void GameMapCamera::Update(float deltaTime) +void GameCamera::Update(float deltaTime) { SyncPosByFromParent(deltaTime); } -void GameMapCamera::SyncPos(float deltaTime) +void GameCamera::SyncPos(float deltaTime) { } -void GameMapCamera::SetPos(int x, int y, int z) +void GameCamera::SetPos(float x, float y, float z) { // this->X = x; // this->Y = y; // this->Z = z; } -void GameMapCamera::AddPos(int x, int y, int z) +void GameCamera::AddPos(float x, float y, float z) { // this->X += x; // this->Y += y; // this->Z += z; } -void GameMapCamera::SyncPosByFromParent(float deltaTime) +void GameCamera::SyncPosByFromParent(float deltaTime) { if (this->_FromActor == nullptr) { return; } - int targetX = _FromActor->Position.x; - int targetY = _FromActor->Position.y; + float targetX = _FromActor->Position.x; + float targetY = _FromActor->Position.y; if (_isSmoothMoving) { // 平滑移动计算 - VecPos targetPosition(targetX, targetY); + Vec2 targetPosition(targetX, targetY); _currentPosition = SmoothDamp(_currentPosition, targetPosition, _velocity, _smoothTime, _maxSpeed, deltaTime); } else @@ -63,12 +62,12 @@ void GameMapCamera::SyncPosByFromParent(float deltaTime) } } -VecPos GameMapCamera::SmoothDamp(const VecPos ¤t, const VecPos &target, VecPos ¤tVelocity, float smoothTime, int maxSpeed, float deltaTime) +Vec2 GameCamera::SmoothDamp(const Vec2 ¤t, const Vec2 &target, Vec2 ¤tVelocity, float smoothTime, float maxSpeed, float deltaTime) { // 平滑时间为0时直接返回目标位置并重置速度 if (smoothTime <= 0.f) { - currentVelocity = VecPos(0, 0); + currentVelocity = Vec2(0, 0); return target; } @@ -78,49 +77,43 @@ VecPos GameMapCamera::SmoothDamp(const VecPos ¤t, const VecPos &target, Ve const float expTerm = 1.0f / (1.0f + x + 0.48f * x * x + 0.235f * x * x * x); // 计算当前位置与目标的差值 - VecPos delta = target - current; + Vec2 delta = target - current; // 计算目标速度(基于阻尼公式和当前差值) // 注意:这里先通过浮点计算保持精度,最后转换为整数 const float tx = delta.x * (omega * omega * deltaTime) - currentVelocity.x * (1.0f + 0.48f * x) * x; const float ty = delta.y * (omega * omega * deltaTime) - currentVelocity.y * (1.0f + 0.48f * x) * x; - VecPos targetVelocity(static_cast(tx), static_cast(ty)); + Vec2 targetVelocity(tx, ty); // 应用速度衰减(指数平滑) currentVelocity += targetVelocity; - currentVelocity = VecPos( - static_cast(currentVelocity.x * expTerm), - static_cast(currentVelocity.y * expTerm)); + currentVelocity = Vec2(currentVelocity.x * expTerm, currentVelocity.y * expTerm); // 限制最大速度(如果设置了maxSpeed) if (maxSpeed > 0) { // 计算当前速度的模长(浮点精度) - const float speedSq = static_cast(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y); - const float maxSpeedSq = static_cast(maxSpeed * maxSpeed); + const float speedSq = currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y; + const float maxSpeedSq = maxSpeed * maxSpeed; if (speedSq > maxSpeedSq) { // 速度超限,按比例缩放至最大速度 const float scale = maxSpeed / sqrtf(speedSq); - currentVelocity = VecPos( - static_cast(currentVelocity.x * scale), - static_cast(currentVelocity.y * scale)); + currentVelocity = Vec2(currentVelocity.x * scale, currentVelocity.y * scale); } } // 计算新位置(当前位置 + 速度 * 时间) - VecPos newPos = current + VecPos( - static_cast(currentVelocity.x * deltaTime), - static_cast(currentVelocity.y * deltaTime)); + Vec2 newPos = current + Vec2(currentVelocity.x * deltaTime, currentVelocity.y * deltaTime); // 检测过冲:如果新位置已越过目标,直接锁定目标并重置速度 // 点积 > 0 表示方向相反(已超过目标) - const int dot = delta.x * (newPos.x - target.x) + delta.y * (newPos.y - target.y); + const float dot = delta.x * (newPos.x - target.x) + delta.y * (newPos.y - target.y); if (dot > 0) { newPos = target; - currentVelocity = VecPos(0, 0); + currentVelocity = Vec2(0, 0); } return newPos; diff --git a/source_game/Global/GameCamera.h b/source_game/Global/GameCamera.h new file mode 100644 index 0000000..2bff0c4 --- /dev/null +++ b/source_game/Global/GameCamera.h @@ -0,0 +1,35 @@ +#pragma once +#include "EngineFrame/Base/Actor.h" +class GameMap; +class BaseObject; +class GameCamera : public Actor +{ +private: + // 跟随对象 + BaseObject *_FromActor = nullptr; + +public: + // 缩放比率 + float CameraRate = 1.0; + + // 添加平滑移动相关的成员变量 + bool _isSmoothMoving = false; + Vec2 _currentPosition; // 当前摄像机位置 + Vec2 _velocity; // 当前移动速度(用于平滑移动) + float _smoothTime = 0.1f; // 平滑时间(秒),可调整 + float _maxSpeed = 2000; // 最大移动速度,防止过快 + +public: + void SetFromActor(BaseObject *actor); + void Update(float deltaTime); + + void SetPos(float x, float y, float z); + void AddPos(float x, float y, float z); + + // 同步坐标相关 + void SyncPos(float deltaTime); + void SyncPosByFromParent(float deltaTime); + + // 平滑阻尼函数(类似Unity的Mathf.SmoothDamp) + Vec2 SmoothDamp(const Vec2 ¤t, const Vec2 &target, Vec2 ¤tVelocity, float smoothTime, float maxSpeed, float deltaTime); +}; diff --git a/source_game/Global/Global_Game.cpp b/source_game/Global/Global_Game.cpp index a4e30ba..d42190a 100644 --- a/source_game/Global/Global_Game.cpp +++ b/source_game/Global/Global_Game.cpp @@ -4,9 +4,6 @@ Global_Game::Global_Game() { } -Global_Game::~Global_Game() -{ -} void Global_Game::InitFont() { @@ -65,11 +62,6 @@ void Global_Game::InitFont() void Global_Game::Init() { InitFont(); - - // TTF_Font *FontBuf = TTF_OpenFont("Fonts/NotoSansSC-Regular.otf", 24); - // TTF_Font *FontBuf = TTF_OpenFont("Fonts/calibri.ttf", 24); - - } void Global_Game::InitGame() @@ -83,9 +75,11 @@ void Global_Game::InitGame() // 初始化松鼠脚本管理器 SquirrelManager::GetInstance().Init(); - // 读取存档 SavaManager::GetInstance().Init(); + + //创建摄像机 + _GameCamera = new GameCamera(); // 游戏初始化完成标志 InitFlag = true; } @@ -109,4 +103,9 @@ GlobalMonsterScript::MonsterConfig Global_Game::GetMonsterInfo(int id) MonsterConfig.id = id; MonsterInfoMap[id] = MonsterConfig; return MonsterConfig; -} \ No newline at end of file +} + +RefPtr Global_Game::GetCamera() +{ + return _GameCamera; +} diff --git a/source_game/Global/Global_Game.h b/source_game/Global/Global_Game.h index 74b2152..d219ebc 100644 --- a/source_game/Global/Global_Game.h +++ b/source_game/Global/Global_Game.h @@ -4,6 +4,7 @@ #include "Global/Script/EquipmentConfig.h" #include "Global/Script/MonsterConfig.h" #include "Global/Save/SavaManager.h" +#include "Global/GameCamera.h" class Global_Game { @@ -19,14 +20,15 @@ public: return instance; } + Global_Game(); + // 游戏资源加载之前的初始化 void Init(); // 游戏资源加载之后的初始化 void InitGame(); -public: - // 当前游戏状态 0未初始化 - int game_state = 0; +private: + void InitFont(); public: // 字体资源 @@ -39,14 +41,14 @@ public: // 怪物相关 std::map MonsterPathMap; // 路径 std::map MonsterInfoMap; // 信息 - GlobalMonsterScript::MonsterConfig GetMonsterInfo(int id); // 获取怪物信息 + GlobalMonsterScript::MonsterConfig GetMonsterInfo(int id); // 获取怪物信息 - // 游戏资源初始化标志 + // 游戏摄像机 + RefPtr _GameCamera = nullptr; + + // 游戏资源初始化标志 bool InitFlag = false; -private: - Global_Game(/* args */); - ~Global_Game(); - - void InitFont(); +public: + RefPtr GetCamera(); }; diff --git a/source_game/Scene/Scene_Loading_UI.cpp b/source_game/Scene/Scene_Loading_UI.cpp index 509f20d..d8cc7d2 100644 --- a/source_game/Scene/Scene_Loading_UI.cpp +++ b/source_game/Scene/Scene_Loading_UI.cpp @@ -20,18 +20,18 @@ void Scene_Loading_UI::Enter() AddChild(actor); RefPtr BackGroundSp = new Sprite("ImagePacks2/Loading1.png"); - actor->AddComponent(BackGroundSp); + actor->AddChild(BackGroundSp); RefPtr BackGround2Sp = new Sprite("ImagePacks2/Loading0.png"); BackGround2Sp->SetPos(Vec2{0, 686}); - actor->AddComponent(BackGround2Sp); + actor->AddChild(BackGround2Sp); RefPtr LoadCircleSp = new Sprite("ImagePacks2/Loading2.png"); LoadCircleSp->SetName("LoadCircle"); LoadCircleSp->SetPos(Vec2{1280 - 60, 686 - 60}); LoadCircleSp->SetBlendMode(LINEARDODGE); LoadCircleSp->SetAnchor(Vec2{0.5f, 0.5f}); - actor->AddComponent(LoadCircleSp); + actor->AddChild(LoadCircleSp); - actor->SetCallbackOnUpdate([LoadCircleSp](float deltaTime) mutable + actor->SetCallbackOnUpdate("Rotate", [LoadCircleSp](float deltaTime) mutable { float angle = LoadCircleSp->GetRotation(); LoadCircleSp->SetRotation(angle + 180.0f * deltaTime); }); diff --git a/source_game/Scene/Scene_Test.cpp b/source_game/Scene/Scene_Test.cpp index 61b8ee6..7ced874 100644 --- a/source_game/Scene/Scene_Test.cpp +++ b/source_game/Scene/Scene_Test.cpp @@ -17,23 +17,25 @@ Scene_Test::~Scene_Test() void Scene_Test::Enter() { map = new GameMap; - map->LoadMap("map/cataclysm/town/elvengard/new_d_elvengard_l.map"); + map->LoadMap("map/cataclysm/town/elvengard/new_elvengard.map"); map->Enter(this); + AddChild(map); + map->SetCallbackOnUpdate("csas", [this](float dt) + { + Vec2 pos = map->GetPos(); + pos.x -= 10 * dt; + map->SetPos(pos); }); - RefPtr obj = new CharacterObject(); - obj->SetPosition({1000, 300, 0}); - obj->Construction(0); + // RefPtr obj = new CharacterObject(); + // obj->SetPosition({1000, 300, 0}); + // obj->Construction(0); + // map->AddObject(obj); - map->AddObject(obj); - - RefPtr monster = new MonsterObject(); - monster->SetPosition({1200, 301, 0}); - monster->Construction(1); - monster->SetDirection(1); - map->AddObject(monster); - - _camera = new GameMapCamera; - _camera->SetFromActor(obj.Get()); + // RefPtr monster = new MonsterObject(); + // monster->SetPosition({1200, 301, 0}); + // monster->Construction(1); + // monster->SetDirection(1); + // map->AddObject(monster); return; @@ -107,11 +109,6 @@ void Scene_Test::HandleEvents(SDL_Event *e) void Scene_Test::Update(float deltaTime) { Scene::Update(deltaTime); - // 摄像机中有检测宿主坐标 所以要在场景的update后调用以便读取到本帧最新的坐标 - if (_camera) - _camera->Update(deltaTime); - if (map) - map->Update(deltaTime); } void Scene_Test::Render() @@ -123,8 +120,3 @@ void Scene_Test::Exit() { SDL_Log("Scene_Test::退出测试场景!当前引用计数%d", this->GetRefCount()); } - -RefPtr Scene_Test::GetCamera() -{ - return this->_camera; -} diff --git a/source_game/Scene/Scene_Test.h b/source_game/Scene/Scene_Test.h index 5644985..f007493 100644 --- a/source_game/Scene/Scene_Test.h +++ b/source_game/Scene/Scene_Test.h @@ -3,7 +3,6 @@ #include "Asset/AssetManager.h" #include "EngineFrame/Component/Animation.h" #include "Actor/Map/GameMap.h" -#include "Actor/Map/GameMapCamera.h" #include "Actor/Object/CharacterObject.h" #include "Actor/Object/MonsterObject.h" @@ -11,7 +10,6 @@ class Scene_Test : public Scene { private: GameMap *map = nullptr; - RefPtr _camera = nullptr; public: Scene_Test(/* args */); @@ -23,7 +21,7 @@ public: void Update(float deltaTime) override; void Render() override; void Exit() override; - RefPtr GetCamera() override; + public: int MyId = 0;