加入 Node节点类 还未测试新框架
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -96,5 +96,6 @@
|
|||||||
"semaphore": "cpp",
|
"semaphore": "cpp",
|
||||||
"cinttypes": "cpp",
|
"cinttypes": "cpp",
|
||||||
"netfwd": "cpp"
|
"netfwd": "cpp"
|
||||||
}
|
},
|
||||||
|
"Codegeex.RepoIndex": true
|
||||||
}
|
}
|
||||||
@@ -214,5 +214,8 @@
|
|||||||
},
|
},
|
||||||
"source/EngineFrame/Component/NumberText.h": {
|
"source/EngineFrame/Component/NumberText.h": {
|
||||||
"description": "数字文本"
|
"description": "数字文本"
|
||||||
|
},
|
||||||
|
"source/EngineFrame/Attribute": {
|
||||||
|
"description": "属性"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "squirrel/SquirrelEx.h"
|
#include "squirrel/SquirrelEx.h"
|
||||||
#include "EngineFrame/Component/Sprite.h"
|
#include "EngineFrame/Component/Sprite.h"
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
#include "EngineFrame/Base/Actor.h"
|
||||||
#include "EngineFrame/Component/Text.h"
|
#include "EngineFrame/Component/Text.h"
|
||||||
|
|
||||||
Game::Game()
|
Game::Game()
|
||||||
@@ -25,10 +25,11 @@ void Game::Init(std::function<void()> CallBack)
|
|||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // 双缓冲
|
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_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)
|
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
|
||||||
{
|
{
|
||||||
|
|||||||
26
source/EngineFrame/Attribute/Bits.h
Normal file
26
source/EngineFrame/Attribute/Bits.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace bits
|
||||||
|
{
|
||||||
|
template <typename _Ty>
|
||||||
|
inline void Set(_Ty &old, _Ty flag)
|
||||||
|
{
|
||||||
|
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
|
||||||
|
old |= flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename _Ty>
|
||||||
|
inline void Unset(_Ty &old, _Ty flag)
|
||||||
|
{
|
||||||
|
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
|
||||||
|
old &= ~flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename _Ty>
|
||||||
|
inline bool Has(_Ty old, _Ty flag)
|
||||||
|
{
|
||||||
|
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
|
||||||
|
return !!(old & flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
57
source/EngineFrame/Attribute/Flag.h
Normal file
57
source/EngineFrame/Attribute/Flag.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint> // uint8_t
|
||||||
|
#include "Bits.h"
|
||||||
|
template <typename _Ty>
|
||||||
|
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 <typename _Ty>
|
||||||
|
struct IsFlag : public std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename _Ty>
|
||||||
|
struct IsFlag<Flag<_Ty>> : public std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Flag<uint8_t> FlagUint8;
|
||||||
|
typedef Flag<uint16_t> FlagUint16;
|
||||||
|
typedef Flag<uint32_t> FlagUint32;
|
||||||
|
typedef Flag<uint64_t> FlagUint64;
|
||||||
|
typedef Flag<int8_t> FlagInt8;
|
||||||
|
typedef Flag<int16_t> FlagInt16;
|
||||||
|
typedef Flag<int32_t> FlagInt32;
|
||||||
|
typedef Flag<int64_t> FlagInt64;
|
||||||
61
source/EngineFrame/Attribute/Y_Transform.cpp
Normal file
61
source/EngineFrame/Attribute/Y_Transform.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#include "Y_Transform.h"
|
||||||
|
#include <cmath>
|
||||||
|
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;
|
||||||
|
}
|
||||||
26
source/EngineFrame/Attribute/Y_Transform.h
Normal file
26
source/EngineFrame/Attribute/Y_Transform.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "math/Math.h"
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
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;
|
||||||
|
};
|
||||||
@@ -18,8 +18,17 @@ void Actor::Init()
|
|||||||
addTag(Tag::UPDATE);
|
addTag(Tag::UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Actor::Update(float deltaTime)
|
||||||
|
{
|
||||||
|
if (!Visible)
|
||||||
|
return;
|
||||||
|
BaseNode::Update(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
void Actor::Render()
|
void Actor::Render()
|
||||||
{
|
{
|
||||||
|
if (!Visible)
|
||||||
|
return;
|
||||||
// 如果有裁切视口
|
// 如果有裁切视口
|
||||||
if (this->_CropViewportFlag)
|
if (this->_CropViewportFlag)
|
||||||
{
|
{
|
||||||
@@ -34,16 +43,6 @@ void Actor::Render()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::AddComponent(RefPtr<Component> Component)
|
|
||||||
{
|
|
||||||
BaseNode::AddChild(Component);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Actor::RemoveComponent(RefPtr<Component> Component)
|
|
||||||
{
|
|
||||||
BaseNode::RemoveChild(Component);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Actor::SetCropViewport(SDL_Rect CropViewport)
|
void Actor::SetCropViewport(SDL_Rect CropViewport)
|
||||||
{
|
{
|
||||||
if (CropViewport.x == 0 && CropViewport.y == 0 && CropViewport.w == 0 && CropViewport.h == 0)
|
if (CropViewport.x == 0 && CropViewport.y == 0 && CropViewport.w == 0 && CropViewport.h == 0)
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EngineFrame/Base/BaseNode.h"
|
#include "EngineFrame/Base/BaseNode.h"
|
||||||
#include "EngineFrame/Component/Component.h"
|
|
||||||
#include "Tool/IntrusiveList.hpp"
|
#include "Tool/IntrusiveList.hpp"
|
||||||
class Scene;
|
class Scene;
|
||||||
/**
|
/**
|
||||||
@@ -21,9 +20,8 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void Init() override;
|
void Init() override;
|
||||||
|
void Update(float deltaTime) override;
|
||||||
void Render() override;
|
void Render() override;
|
||||||
void AddComponent(RefPtr<Component> Component);
|
|
||||||
void RemoveComponent(RefPtr<Component> Component);
|
|
||||||
|
|
||||||
// 设置裁切视口(放在Actor里 他与他的子对象都会被裁切)
|
// 设置裁切视口(放在Actor里 他与他的子对象都会被裁切)
|
||||||
void SetCropViewport(SDL_Rect CropViewport);
|
void SetCropViewport(SDL_Rect CropViewport);
|
||||||
@@ -27,11 +27,6 @@ void BaseNode::HandleEvents(SDL_Event *e)
|
|||||||
|
|
||||||
void BaseNode::Update(float deltaTime)
|
void BaseNode::Update(float deltaTime)
|
||||||
{
|
{
|
||||||
// 如果有回调函数,则调用回调函数
|
|
||||||
if (cb_update_)
|
|
||||||
{
|
|
||||||
cb_update_(deltaTime);
|
|
||||||
}
|
|
||||||
// 如果有子节点并含有刷新标签,则更新子节点
|
// 如果有子节点并含有刷新标签,则更新子节点
|
||||||
RefPtr<BaseNode> child = m_BaseNodes.GetFirst();
|
RefPtr<BaseNode> child = m_BaseNodes.GetFirst();
|
||||||
while (child)
|
while (child)
|
||||||
@@ -40,6 +35,14 @@ void BaseNode::Update(float deltaTime)
|
|||||||
child->Update(deltaTime);
|
child->Update(deltaTime);
|
||||||
child = child->GetNext();
|
child = child->GetNext();
|
||||||
}
|
}
|
||||||
|
// 如果有回调函数,则调用回调函数
|
||||||
|
if (cb_update_.size() > 0)
|
||||||
|
{
|
||||||
|
for (auto &cb : cb_update_)
|
||||||
|
{
|
||||||
|
cb.second(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseNode::PreRender()
|
void BaseNode::PreRender()
|
||||||
@@ -53,7 +56,6 @@ void BaseNode::PreRender()
|
|||||||
child = child->GetNext();
|
child = child->GetNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseNode::Render()
|
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()
|
void BaseNode::SetChildIterationTransform()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// 更新时的回调函数
|
// 更新时的回调函数
|
||||||
UpdateCallback cb_update_;
|
std::map<std::string ,UpdateCallback> cb_update_;
|
||||||
// 节点名称
|
// 节点名称
|
||||||
std::string m_Name;
|
std::string m_Name;
|
||||||
// 子节点列表
|
// 子节点列表
|
||||||
@@ -60,7 +60,8 @@ public:
|
|||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 设置更新时的回调函数
|
/// @brief 设置更新时的回调函数
|
||||||
void SetCallbackOnUpdate(const UpdateCallback &cb);
|
void SetCallbackOnUpdate(std::string Key,const UpdateCallback &cb);
|
||||||
|
void RemoveCallbackOnUpdate(std::string Key);
|
||||||
|
|
||||||
void SetChildIterationTransform();
|
void SetChildIterationTransform();
|
||||||
|
|
||||||
|
|||||||
549
source/EngineFrame/Base/Node.cpp
Normal file
549
source/EngineFrame/Base/Node.cpp
Normal file
@@ -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<Node> 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<Node> me = this;
|
||||||
|
|
||||||
|
parent_->children_.Remove(me);
|
||||||
|
|
||||||
|
RefPtr<Node> 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<Node> next;
|
||||||
|
for (RefPtr<Node> 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<Node> 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<Node> child)
|
||||||
|
{
|
||||||
|
if (children_.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
child->parent_ = nullptr;
|
||||||
|
children_.Remove(child);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_LogError(0, "Actor::RemoveChild failed, NULL pointer exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
355
source/EngineFrame/Base/Node.h
Normal file
355
source/EngineFrame/Base/Node.h
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SDL.h>
|
||||||
|
#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<RefPtr<Node>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::function<void(float deltaTime)> UpdateCallback;
|
||||||
|
typedef IntrusiveList<RefPtr<Node>> NodeList;
|
||||||
|
|
||||||
|
using IntrusiveListValue<RefPtr<Node>>::GetNext;
|
||||||
|
using IntrusiveListValue<RefPtr<Node>>::GetPrev;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**变换属性 */
|
||||||
|
Y_Transform transform_;
|
||||||
|
/**变换矩阵 */
|
||||||
|
mutable Matrix3x2 transform_matrix_;
|
||||||
|
mutable Matrix3x2 transform_matrix_inverse_;
|
||||||
|
mutable Matrix3x2 transform_matrix_to_parent_;
|
||||||
|
/**更新时的回调函数 */
|
||||||
|
std::map<std::string, UpdateCallback> 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<uint8_t> 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<Node> child);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取全部子角色
|
||||||
|
NodeList &GetAllChildren();
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取全部子角色
|
||||||
|
const NodeList &GetAllChildren() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 移除子角色
|
||||||
|
void RemoveChild(RefPtr<Node> 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
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "Asset/AssetManager.h"
|
#include "Asset/AssetManager.h"
|
||||||
#include "Asset/Asset_Script.h"
|
#include "Asset/Asset_Script.h"
|
||||||
#include "Tool/Math.h"
|
#include "Tool/Math.h"
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
#include "EngineFrame/Base/Actor.h"
|
||||||
#include "EngineCore/Game.h"
|
#include "EngineCore/Game.h"
|
||||||
|
|
||||||
Animation::Animation()
|
Animation::Animation()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
#include "EngineFrame/Base/Actor.h"
|
||||||
#include "EngineFrame/Component/Sprite.h"
|
#include "EngineFrame/Component/Sprite.h"
|
||||||
#include "Asset/AnimationStruct.h"
|
#include "Asset/AnimationStruct.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
#include "EngineFrame/Base/Actor.h"
|
||||||
#include "EngineFrame/Render/Texture.h"
|
#include "EngineFrame/Render/Texture.h"
|
||||||
#include "EngineFrame/Component/Sprite.h"
|
#include "EngineFrame/Component/Sprite.h"
|
||||||
class Canvas : public Actor
|
class Canvas : public Actor
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
#include "Component.h"
|
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
|
||||||
|
|
||||||
void Component::Init()
|
|
||||||
{
|
|
||||||
addTag(Tag::COMPONENT);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "EngineFrame/Base/BaseNode.h"
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
class Actor;
|
|
||||||
class Component : public BaseNode
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
void Init() override;
|
|
||||||
};
|
|
||||||
@@ -1,13 +1,6 @@
|
|||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
#include "EngineFrame/Base/Actor.h"
|
||||||
|
|
||||||
RenderBase::RenderBase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderBase::~RenderBase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderBase::CalcRenderInfo()
|
void RenderBase::CalcRenderInfo()
|
||||||
{
|
{
|
||||||
@@ -16,39 +9,23 @@ void RenderBase::CalcRenderInfo()
|
|||||||
|
|
||||||
void RenderBase::Init()
|
void RenderBase::Init()
|
||||||
{
|
{
|
||||||
Component::Init();
|
|
||||||
// 标记该组件需要渲染和更新
|
|
||||||
addTag(Tag::RENDER);
|
|
||||||
addTag(Tag::UPDATE);
|
|
||||||
addTag(Tag::TRANSFORM);
|
|
||||||
// 计算渲染信息
|
// 计算渲染信息
|
||||||
CalcRenderInfo();
|
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)
|
void RenderBase::SetIterationPos(Vec2 pos)
|
||||||
{
|
{
|
||||||
Component::SetIterationPos(pos);
|
Actor::SetIterationPos(pos);
|
||||||
CalcRenderInfo(); // 更新渲染信息
|
CalcRenderInfo(); // 更新渲染信息
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBase::SetIterationScale(Vec2 scale)
|
void RenderBase::SetIterationScale(Vec2 scale)
|
||||||
{
|
{
|
||||||
Component::SetIterationScale(scale);
|
Actor::SetIterationScale(scale);
|
||||||
CalcRenderInfo(); // 更新渲染信息
|
CalcRenderInfo(); // 更新渲染信息
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,31 +33,31 @@ void RenderBase::SetIterationRotation(float angle)
|
|||||||
{
|
{
|
||||||
if (!Visible)
|
if (!Visible)
|
||||||
return;
|
return;
|
||||||
Component::SetIterationRotation(angle);
|
Actor::SetIterationRotation(angle);
|
||||||
CalcRenderInfo(); // 更新渲染信息
|
CalcRenderInfo(); // 更新渲染信息
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBase::SetPos(Vec2 pos)
|
void RenderBase::SetPos(Vec2 pos)
|
||||||
{
|
{
|
||||||
Component::SetPos(pos);
|
Actor::SetPos(pos);
|
||||||
|
|
||||||
CalcRenderInfo(); // 更新渲染信息
|
CalcRenderInfo(); // 更新渲染信息
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBase::SetScale(Vec2 scale)
|
void RenderBase::SetScale(Vec2 scale)
|
||||||
{
|
{
|
||||||
Component::SetScale(scale);
|
Actor::SetScale(scale);
|
||||||
CalcRenderInfo(); // 更新渲染信息
|
CalcRenderInfo(); // 更新渲染信息
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBase::SetRotation(float angle)
|
void RenderBase::SetRotation(float angle)
|
||||||
{
|
{
|
||||||
Component::SetRotation(angle);
|
Actor::SetRotation(angle);
|
||||||
CalcRenderInfo(); // 更新渲染信息
|
CalcRenderInfo(); // 更新渲染信息
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBase::SetAnchor(Vec2 anchor)
|
void RenderBase::SetAnchor(Vec2 anchor)
|
||||||
{
|
{
|
||||||
Component::SetAnchor(anchor);
|
Actor::SetAnchor(anchor);
|
||||||
CalcRenderInfo(); // 更新渲染信息
|
CalcRenderInfo(); // 更新渲染信息
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "EngineFrame/Base/Actor.h"
|
||||||
|
|
||||||
#include "EngineFrame/Component/Component.h"
|
class RenderBase : public Actor
|
||||||
|
|
||||||
class RenderBase : public Component
|
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -19,21 +18,11 @@ public:
|
|||||||
bool Visible = true;
|
bool Visible = true;
|
||||||
// 是否在屏幕内
|
// 是否在屏幕内
|
||||||
bool IsInScreen = false;
|
bool IsInScreen = false;
|
||||||
//渲染矩阵
|
|
||||||
GlMatrix RenderMatrix;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
|
||||||
RenderBase(/* args */);
|
|
||||||
~RenderBase();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init() override;
|
void Init() override;
|
||||||
|
|
||||||
void Update(float deltaTime) override;
|
|
||||||
void Render() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
public:
|
public:
|
||||||
// 设置迭代的坐标
|
// 设置迭代的坐标
|
||||||
void SetIterationPos(Vec2 pos) override;
|
void SetIterationPos(Vec2 pos) override;
|
||||||
|
|||||||
@@ -43,35 +43,6 @@ RefPtr<Texture> Sprite::GetTexture()
|
|||||||
return m_texture;
|
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()
|
void Sprite::CalcRenderInfoLogic()
|
||||||
{
|
{
|
||||||
// 获取至在最终的父对象检查是否显示
|
// 获取至在最终的父对象检查是否显示
|
||||||
@@ -105,8 +76,8 @@ void Sprite::CalcRenderInfoLogic()
|
|||||||
// 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上
|
// 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上
|
||||||
auto T_Size = m_texture->getSize();
|
auto T_Size = m_texture->getSize();
|
||||||
auto T_Pos = m_texture->getPos();
|
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 texturePosX = flipX ? -((float)T_Size.width + (float)T_Pos.x) + SDL_fabsf(transform.position.x * 2.0f) : (float)T_Pos.x;
|
||||||
float texturePosY = flipY ? -(T_Size.height + T_Pos.y) + SDL_abs(transform.position.y * 2) : T_Pos.y;
|
float texturePosY = flipY ? -((float)T_Size.height + (float)T_Pos.y) + SDL_fabsf(transform.position.y * 2.0f) : (float)T_Pos.y;
|
||||||
|
|
||||||
// 先计算Img坐标与精灵坐标合成后的真实坐标
|
// 先计算Img坐标与精灵坐标合成后的真实坐标
|
||||||
float RealPosX = transform.position.x + texturePosX;
|
float RealPosX = transform.position.x + texturePosX;
|
||||||
@@ -117,22 +88,22 @@ void Sprite::CalcRenderInfoLogic()
|
|||||||
float baseY = transformIter.position.y + RealPosY;
|
float baseY = transformIter.position.y + RealPosY;
|
||||||
|
|
||||||
// 获取当前帧的原始尺寸
|
// 获取当前帧的原始尺寸
|
||||||
int frameWidth = Size.width;
|
float frameWidth = (float)Size.width;
|
||||||
int frameHeight = Size.height;
|
float frameHeight = (float)Size.height;
|
||||||
|
|
||||||
// 原始锚点偏移(基于帧尺寸)
|
// 原始锚点偏移(基于帧尺寸)
|
||||||
float origAnchorOffsetX = int(frameWidth * Anchor.x);
|
float origAnchorOffsetX = frameWidth * Anchor.x;
|
||||||
float origAnchorOffsetY = int(frameHeight * Anchor.y);
|
float origAnchorOffsetY = frameHeight * Anchor.y;
|
||||||
|
|
||||||
// 缩放的绝对值
|
// 缩放的绝对值
|
||||||
float absScaleX = SDL_fabs(scaleX);
|
float absScaleX = SDL_fabsf(scaleX);
|
||||||
float absScaleY = SDL_fabs(scaleY);
|
float absScaleY = SDL_fabsf(scaleY);
|
||||||
// 缩放后的尺寸
|
// 缩放后的尺寸
|
||||||
float scaledWidth = frameWidth * absScaleX;
|
float scaledWidth = frameWidth * absScaleX;
|
||||||
float scaledHeight = frameHeight * absScaleY;
|
float scaledHeight = frameHeight * absScaleY;
|
||||||
// 缩放后的锚点偏移
|
// 缩放后的锚点偏移
|
||||||
float scaledAnchorOffsetX = int(origAnchorOffsetX * absScaleX);
|
float scaledAnchorOffsetX = origAnchorOffsetX * absScaleX;
|
||||||
float scaledAnchorOffsetY = int(origAnchorOffsetY * absScaleY);
|
float scaledAnchorOffsetY = origAnchorOffsetY * absScaleY;
|
||||||
|
|
||||||
// 计算缩放后的锚点偏移与原锚点偏移的差值
|
// 计算缩放后的锚点偏移与原锚点偏移的差值
|
||||||
float scaleOffsetX = scaledAnchorOffsetX - origAnchorOffsetX;
|
float scaleOffsetX = scaledAnchorOffsetX - origAnchorOffsetX;
|
||||||
@@ -142,9 +113,6 @@ void Sprite::CalcRenderInfoLogic()
|
|||||||
float Xpos = baseX - scaleOffsetX;
|
float Xpos = baseX - scaleOffsetX;
|
||||||
float Ypos = baseY - scaleOffsetY;
|
float Ypos = baseY - scaleOffsetY;
|
||||||
|
|
||||||
Xpos = (int)Xpos; // 强制转换为整数
|
|
||||||
Ypos = (int)Ypos; // 强制转换为整数
|
|
||||||
|
|
||||||
// 更新渲染信息
|
// 更新渲染信息
|
||||||
_RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight};
|
_RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight};
|
||||||
_RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY};
|
_RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY};
|
||||||
@@ -152,8 +120,8 @@ void Sprite::CalcRenderInfoLogic()
|
|||||||
m_texture->setAlpha(this->Alpha);
|
m_texture->setAlpha(this->Alpha);
|
||||||
|
|
||||||
// 屏幕内检测
|
// 屏幕内检测
|
||||||
int screenWidth = Game::GetInstance().Screen_W;
|
float screenWidth = (float)Game::GetInstance().Screen_W;
|
||||||
int screenHeight = Game::GetInstance().Screen_H;
|
float screenHeight = (float)Game::GetInstance().Screen_H;
|
||||||
bool isInScreen = (Xpos + scaledWidth >= 0 && Xpos <= screenWidth && Ypos + scaledHeight >= 0 && Ypos <= screenHeight);
|
bool isInScreen = (Xpos + scaledWidth >= 0 && Xpos <= screenWidth && Ypos + scaledHeight >= 0 && Ypos <= screenHeight);
|
||||||
_RenderGuidanceInfo.IsInScreen = isInScreen;
|
_RenderGuidanceInfo.IsInScreen = isInScreen;
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,6 @@ public:
|
|||||||
std::string imgPath;
|
std::string imgPath;
|
||||||
int Index;
|
int Index;
|
||||||
|
|
||||||
Matrix3x2 transform_matrix_;
|
|
||||||
|
|
||||||
GlMatrix matrix3x2ToGLMatrix(const Matrix3x2 &mat);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 计算渲染信息
|
// 计算渲染信息
|
||||||
void CalcRenderInfoLogic();
|
void CalcRenderInfoLogic();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
~Text();
|
~Text();
|
||||||
|
|
||||||
// 显式引入基类的Init方法,避免隐藏
|
// 显式引入基类的Init方法,避免隐藏
|
||||||
using Component::Init;
|
using Actor::Init;
|
||||||
void Init(std::string Str, TTF_Font *font, SDL_Color color);
|
void Init(std::string Str, TTF_Font *font, SDL_Color color);
|
||||||
void Render() override;
|
void Render() override;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ RenderManager::RenderManager(SDL_Window *window)
|
|||||||
_windowHeight = height;
|
_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的初始正交投影矩阵
|
// UI的初始正交投影矩阵
|
||||||
_UIOrthoMatrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f);
|
_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);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
// 启用混合模式
|
// 启用混合模式
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
// 默认设置标准alpha混合
|
// 默认设置标准alpha混合
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
@@ -228,8 +229,8 @@ void RenderManager::Init2DTextureProgram()
|
|||||||
glUniform1i(_currentRenderParams.UnimLocs[2], 0);
|
glUniform1i(_currentRenderParams.UnimLocs[2], 0);
|
||||||
|
|
||||||
// 处理纹理裁剪
|
// 处理纹理裁剪
|
||||||
int texWidth = textureObj->getSize().width;
|
float texWidth = (float)textureObj->getSize().width;
|
||||||
int texHeight = textureObj->getSize().height;
|
float texHeight = (float)textureObj->getSize().height;
|
||||||
|
|
||||||
// 计算纹理坐标
|
// 计算纹理坐标
|
||||||
float minu, minv, maxu, maxv;
|
float minu, minv, maxu, maxv;
|
||||||
@@ -336,6 +337,16 @@ void RenderManager::SetOrthoMatrixType(int type)
|
|||||||
_OrthoMatrix = _UIOrthoMatrix;
|
_OrthoMatrix = _UIOrthoMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 RenderManager::GetOrthoMatrix()
|
||||||
|
{
|
||||||
|
return _OrthoMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderManager::SetOrthoMatrix(glm::mat4 matrix)
|
||||||
|
{
|
||||||
|
_OrthoMatrix = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint RenderManager::CompileShader(GLenum type, std::string Path)
|
GLuint RenderManager::CompileShader(GLenum type, std::string Path)
|
||||||
{
|
{
|
||||||
std::ifstream Source("shader/" + Path);
|
std::ifstream Source("shader/" + Path);
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ public:
|
|||||||
void DrawTexture(RefPtr<Texture> texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata = nullptr);
|
void DrawTexture(RefPtr<Texture> 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);
|
void SetOrthoMatrixType(int type);
|
||||||
|
// 获取渲染的正交投影矩阵
|
||||||
|
glm::mat4 GetOrthoMatrix();
|
||||||
|
// 设置渲染的正交投影矩阵
|
||||||
|
void SetOrthoMatrix(glm::mat4 matrix);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ bool Texture::Init(std::string PngPath)
|
|||||||
glBindTexture(GL_TEXTURE_2D, m_TextureID);
|
glBindTexture(GL_TEXTURE_2D, m_TextureID);
|
||||||
|
|
||||||
// 环绕方式
|
// 环绕方式
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
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);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
// 放大过滤:使用最近邻采样
|
// 放大过滤:使用最近邻采样
|
||||||
@@ -100,8 +101,9 @@ bool Texture::Init(std::string ImgPath, int Index)
|
|||||||
|
|
||||||
// 设置纹理参数(保持与原有SDL纹理相同的采样模式)
|
// 设置纹理参数(保持与原有SDL纹理相同的采样模式)
|
||||||
// 环绕方式:重复
|
// 环绕方式:重复
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
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对应)
|
// 过滤方式:最近邻(与SDL_ScaleModeNearest对应)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
|
glBindTexture(GL_TEXTURE_2D, m_TextureID);
|
||||||
|
|
||||||
// 环绕方式
|
// 环绕方式
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
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);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
// 放大过滤:使用最近邻采样
|
// 放大过滤:使用最近邻采样
|
||||||
@@ -192,8 +195,9 @@ bool Texture::Init(VecSize size)
|
|||||||
m_FrameSize = size;
|
m_FrameSize = size;
|
||||||
|
|
||||||
// 环绕方式
|
// 环绕方式
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
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);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
// 放大过滤:使用最近邻采样
|
// 放大过滤:使用最近邻采样
|
||||||
|
|||||||
@@ -111,12 +111,41 @@ typedef struct VecPos3
|
|||||||
|
|
||||||
} 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
|
typedef struct VecSpeed3
|
||||||
{
|
{
|
||||||
int x;
|
float x;
|
||||||
int y;
|
float y;
|
||||||
int z;
|
float z;
|
||||||
VecSpeed3(int x_ = 0, int y_ = 0, int z_ = 0) : x(x_), y(y_), z(z_) {}
|
VecSpeed3(float x_ = 0, float y_ = 0, float z_ = 0) : x(x_), y(y_), z(z_) {}
|
||||||
|
|
||||||
VecSpeed3 operator+(const VecSpeed3 &other) const
|
VecSpeed3 operator+(const VecSpeed3 &other) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,13 +27,13 @@
|
|||||||
#include <math/EaseFunctions.h>
|
#include <math/EaseFunctions.h>
|
||||||
#include <math/Scalar.h>
|
#include <math/Scalar.h>
|
||||||
|
|
||||||
|
|
||||||
using Vec2 = ember::math::Vec2T<float>;
|
using Vec2 = ember::math::Vec2T<float>;
|
||||||
using VecPos = ember::math::Vec2T<int>;
|
using VecPos = ember::math::Vec2T<int>;
|
||||||
using Rect = ember::math::RectT<float>;
|
using Rect = ember::math::RectT<float>;
|
||||||
using Matrix3x2 = ember::math::Matrix3x2T<float>;
|
using Matrix3x2 = ember::math::Matrix3x2T<float>;
|
||||||
using Transform = ember::math::TransformT<float>;
|
using Transform = ember::math::TransformT<float>;
|
||||||
|
|
||||||
using GlMatrix = std::array<float, 16>;
|
|
||||||
|
|
||||||
using Point = Vec2;
|
using Point = Vec2;
|
||||||
using Size = Vec2;
|
using Size = Vec2;
|
||||||
|
|||||||
@@ -20,8 +20,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
#include <math/Rect.hpp>
|
#include <math/Rect.hpp>
|
||||||
#include <math/Vec2.hpp>
|
#include <math/Vec2.hpp>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
namespace ember
|
namespace ember
|
||||||
{
|
{
|
||||||
@@ -34,7 +38,7 @@ namespace ember
|
|||||||
struct Matrix3x2T
|
struct Matrix3x2T
|
||||||
{
|
{
|
||||||
using ValueType = _Ty;
|
using ValueType = _Ty;
|
||||||
using Vec2Type = Vec2T<ValueType>;
|
using Vec2Type = glm::vec2;
|
||||||
using RectType = RectT<ValueType>;
|
using RectType = RectT<ValueType>;
|
||||||
|
|
||||||
union
|
union
|
||||||
@@ -160,13 +164,13 @@ namespace ember
|
|||||||
return RectType{left, top, right, bottom};
|
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;
|
_31 += _11 * v.x + _21 * v.y;
|
||||||
_32 += _12 * v.x + _22 * 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);
|
return Matrix3x2T(1.f, 0.f, 0.f, 1.f, v.x, v.y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "GameMap.h"
|
#include "GameMap.h"
|
||||||
#include "Asset/AssetManager.h"
|
#include "Asset/AssetManager.h"
|
||||||
|
#include "EngineCore/Game.h"
|
||||||
#include "EngineFrame/Scene/Scene.h"
|
#include "EngineFrame/Scene/Scene.h"
|
||||||
#include "EngineFrame/Component/Animation.h"
|
#include "EngineFrame/Component/Animation.h"
|
||||||
#include "Actor/Map/GameMapCamera.h"
|
#include "Global/Global_Game.h"
|
||||||
#include "Actor/Object/CharacterObject.h"
|
#include "Actor/Object/CharacterObject.h"
|
||||||
#include "EngineCore/Game.h"
|
|
||||||
|
|
||||||
GameMap::GameMap()
|
GameMap::GameMap()
|
||||||
{
|
{
|
||||||
@@ -217,34 +217,21 @@ void GameMap::InitTile()
|
|||||||
{
|
{
|
||||||
NormalTileCount = tileArr.size();
|
NormalTileCount = tileArr.size();
|
||||||
_MapLength = NormalTileCount * 224;
|
_MapLength = NormalTileCount * 224;
|
||||||
for (int i = 0; i < NormalTileCount; i++)
|
|
||||||
{
|
|
||||||
std::string path = tileArr[i];
|
|
||||||
RefPtr<Tile> tile = new Tile(path);
|
|
||||||
tile->SetPos(Vec2{i * 224, -200 - std::get<int>(_MapInfo["background_pos"])});
|
|
||||||
_LayerMap["bottom"]->AddComponent(tile);
|
|
||||||
}
|
|
||||||
_MapHeight = 560;
|
_MapHeight = 560;
|
||||||
}
|
}
|
||||||
if (_MapInfo.count("extended_tile"))
|
if (!_MapInfo.count("extended_tile"))
|
||||||
{
|
return;
|
||||||
|
|
||||||
std::vector<std::string> extileArr = std::get<std::vector<std::string>>(_MapInfo["extended_tile"]);
|
std::vector<std::string> extileArr = std::get<std::vector<std::string>>(_MapInfo["extended_tile"]);
|
||||||
if (extileArr.size() > 0)
|
if (extileArr.size() > 0)
|
||||||
{
|
{
|
||||||
int ExTileCount = extileArr.size();
|
int ExTileCount = extileArr.size();
|
||||||
int Buffer = (ExTileCount / NormalTileCount);
|
int Buffer = (ExTileCount / NormalTileCount);
|
||||||
_MapHeight += (Buffer < 1 ? 1 : Buffer) * 40;
|
_MapHeight += (Buffer < 1 ? 1 : Buffer) * 40;
|
||||||
for (int i = 0; i < ExTileCount; i++)
|
|
||||||
{
|
|
||||||
std::string path = extileArr[i];
|
|
||||||
RefPtr<Tile> tile = new Tile(path);
|
|
||||||
int xbuf = i % NormalTileCount * 224;
|
|
||||||
int ybuf = -200 - std::get<int>(_MapInfo["background_pos"]) + NormalTileHeight + 120 * (i / NormalTileCount);
|
|
||||||
tile->SetPos(Vec2{xbuf, ybuf});
|
|
||||||
_LayerMap["bottom"]->AddComponent(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_Tile = new Tile(this, tileArr, extileArr);
|
||||||
|
_LayerMap["bottom"]->AddChild(_Tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMap::InitBackgroundAnimation()
|
void GameMap::InitBackgroundAnimation()
|
||||||
@@ -340,45 +327,42 @@ void GameMap::LoadMap(std::string mapName)
|
|||||||
|
|
||||||
void GameMap::Enter(Scene *scene)
|
void GameMap::Enter(Scene *scene)
|
||||||
{
|
{
|
||||||
_Scene = scene;
|
AddChild(_LayerMap["contact"]);
|
||||||
scene->AddChild(_LayerMap["contact"]);
|
AddChild(_LayerMap["distantback"]);
|
||||||
scene->AddChild(_LayerMap["distantback"]);
|
AddChild(_LayerMap["middleback"]);
|
||||||
scene->AddChild(_LayerMap["middleback"]);
|
AddChild(_LayerMap["bottom"]);
|
||||||
scene->AddChild(_LayerMap["bottom"]);
|
AddChild(_LayerMap["closeback"]);
|
||||||
scene->AddChild(_LayerMap["closeback"]);
|
AddChild(_LayerMap["normal"]);
|
||||||
scene->AddChild(_LayerMap["normal"]);
|
AddChild(_LayerMap["close"]);
|
||||||
scene->AddChild(_LayerMap["close"]);
|
AddChild(_LayerMap["cover"]);
|
||||||
scene->AddChild(_LayerMap["cover"]);
|
AddChild(_LayerMap["max"]);
|
||||||
scene->AddChild(_LayerMap["max"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameMap::HandleEvents(SDL_Event *e)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMap::Update(float deltaTime)
|
void GameMap::Update(float deltaTime)
|
||||||
{
|
{
|
||||||
if (_Scene->GetCamera() == nullptr)
|
Actor::Update(deltaTime);
|
||||||
|
|
||||||
|
RefPtr<GameCamera> Cam = Global_Game::GetInstance().GetCamera();
|
||||||
|
if (Cam == nullptr)
|
||||||
return;
|
return;
|
||||||
GameMapCamera *Cam = (GameMapCamera *)(_Scene->GetCamera().Get());
|
float targetX = Cam->_currentPosition.x;
|
||||||
int targetX = Cam->_currentPosition.x;
|
float targetY = Cam->_currentPosition.y;
|
||||||
int targetY = Cam->_currentPosition.y;
|
|
||||||
// 屏幕中心
|
// 屏幕中心
|
||||||
int width_Separate = 1067 / 2;
|
float width_Separate = 1280.0f / 1.2f / 2.0f;
|
||||||
int height_Separate = 600 / 2;
|
float height_Separate = 600.0f / 2.0f;
|
||||||
|
|
||||||
// 获取摄像机可行区域限制
|
// 获取摄像机可行区域限制
|
||||||
auto limitIt = _MapInfo.find("limit_map_camera_move");
|
auto limitIt = _MapInfo.find("limit_map_camera_move");
|
||||||
if (limitIt != _MapInfo.end())
|
if (limitIt != _MapInfo.end())
|
||||||
{
|
{
|
||||||
std::vector<int> limit = std::get<std::vector<int>>(_MapInfo["limit_map_camera_move"]);
|
std::vector<int> limit = std::get<std::vector<int>>(_MapInfo["limit_map_camera_move"]);
|
||||||
int X_Limit_Min = limit[0];
|
float X_Limit_Min = limit[0];
|
||||||
int X_Limit_Max = limit[1];
|
float X_Limit_Max = limit[1];
|
||||||
int Y_Limit_Min = limit[2];
|
float Y_Limit_Min = limit[2];
|
||||||
int Y_Limit_Max = limit[3];
|
float Y_Limit_Max = limit[3];
|
||||||
// 应用地图边界限制
|
// 应用地图边界限制
|
||||||
targetX = std::clamp(targetX, width_Separate, _MapLength - width_Separate);
|
targetX = std::clamp(targetX, width_Separate, (float)_MapLength - width_Separate);
|
||||||
targetY = std::clamp(targetY, height_Separate, _MapHeight - height_Separate);
|
targetY = std::clamp(targetY, height_Separate, (float)_MapHeight - height_Separate);
|
||||||
// 应用自定义摄像机移动限制
|
// 应用自定义摄像机移动限制
|
||||||
if (X_Limit_Min != -1)
|
if (X_Limit_Min != -1)
|
||||||
targetX = std::max(targetX, X_Limit_Min);
|
targetX = std::max(targetX, X_Limit_Min);
|
||||||
@@ -393,12 +377,12 @@ void GameMap::Update(float deltaTime)
|
|||||||
// 更新图层位置
|
// 更新图层位置
|
||||||
for (auto &Layer : _LayerMap)
|
for (auto &Layer : _LayerMap)
|
||||||
{
|
{
|
||||||
int posX = -targetX + width_Separate;
|
float posX = -targetX + width_Separate;
|
||||||
int posY = -targetY + height_Separate + MapOffsetY;
|
float posY = -targetY + height_Separate + MapOffsetY;
|
||||||
if (Layer.first == "distantback")
|
if (Layer.first == "distantback")
|
||||||
{
|
{
|
||||||
posX *= BackgroundMoveSpeed;
|
posX *= BackgroundMoveSpeed;
|
||||||
posX /= 100;
|
posX /= 100.0f;
|
||||||
}
|
}
|
||||||
Layer.second->SetPos(Vec2(posX, posY));
|
Layer.second->SetPos(Vec2(posX, posY));
|
||||||
}
|
}
|
||||||
@@ -412,14 +396,17 @@ void GameMap::AddObject(RefPtr<BaseObject> object)
|
|||||||
if (object->m_objecttype == ObjectType::CHARACTER)
|
if (object->m_objecttype == ObjectType::CHARACTER)
|
||||||
{
|
{
|
||||||
CharacterObject *chr = (CharacterObject *)(object.Get());
|
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())
|
if (_MovableArea.empty())
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
class BaseObject;
|
class BaseObject;
|
||||||
class GameMapCamera;
|
class GameMapCamera;
|
||||||
class GameMap
|
class GameMap : public Actor
|
||||||
{
|
{
|
||||||
struct BackGroundAni
|
struct BackGroundAni
|
||||||
{
|
{
|
||||||
@@ -58,6 +58,8 @@ public:
|
|||||||
std::string _MapPath;
|
std::string _MapPath;
|
||||||
// 地图文件夹
|
// 地图文件夹
|
||||||
std::string _MapDir;
|
std::string _MapDir;
|
||||||
|
// 地板画布
|
||||||
|
RefPtr<Tile> _Tile = nullptr;
|
||||||
// 地图宽度
|
// 地图宽度
|
||||||
int _MapLength = 0;
|
int _MapLength = 0;
|
||||||
// 地图高度
|
// 地图高度
|
||||||
@@ -70,8 +72,6 @@ public:
|
|||||||
public:
|
public:
|
||||||
// 图层Map 图层类型 显示对象
|
// 图层Map 图层类型 显示对象
|
||||||
std::unordered_map<std::string, RefPtr<GameMapLayer>> _LayerMap;
|
std::unordered_map<std::string, RefPtr<GameMapLayer>> _LayerMap;
|
||||||
// 所属场景
|
|
||||||
Scene *_Scene = nullptr;
|
|
||||||
|
|
||||||
// 背景层移动速率
|
// 背景层移动速率
|
||||||
int BackgroundMoveSpeed = 103;
|
int BackgroundMoveSpeed = 103;
|
||||||
@@ -88,11 +88,10 @@ public:
|
|||||||
void InitMapAnimation();
|
void InitMapAnimation();
|
||||||
void InitVirtualMovableArea();
|
void InitVirtualMovableArea();
|
||||||
void Enter(Scene *scene);
|
void Enter(Scene *scene);
|
||||||
void HandleEvents(SDL_Event *e);
|
void Update(float deltaTime) override;
|
||||||
void Update(float deltaTime);
|
|
||||||
void AddObject(RefPtr<BaseObject> object);
|
void AddObject(RefPtr<BaseObject> object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 检查是否可移动
|
// 检查是否可移动
|
||||||
VecPos3 CheckIsItMovable(VecPos3 CurPos, VecPos3 PosOffset);
|
VecFPos3 CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
|
||||||
};
|
|
||||||
@@ -1,31 +1,25 @@
|
|||||||
#include "GameMapLayer.h"
|
#include "GameMapLayer.h"
|
||||||
#include "EngineCore/Game.h"
|
#include "EngineCore/Game.h"
|
||||||
|
|
||||||
GameMapLayer::GameMapLayer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GameMapLayer::~GameMapLayer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameMapLayer::Render()
|
void GameMapLayer::Render()
|
||||||
{
|
{
|
||||||
Actor::Render();
|
|
||||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
|
||||||
|
|
||||||
// 自身坐标
|
Actor::Render();
|
||||||
float Xpos = GetIterationPos().x + GetPos().x;
|
// RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||||
float Ypos = GetIterationPos().y + GetPos().y;
|
|
||||||
for (auto &info : this->FeasibleAreaInfoList)
|
// // 自身坐标
|
||||||
{
|
// float Xpos = GetIterationPos().x + GetPos().x;
|
||||||
SDL_Rect buf;
|
// float Ypos = GetIterationPos().y + GetPos().y;
|
||||||
buf.x = info.x + Xpos;
|
// for (auto &info : this->FeasibleAreaInfoList)
|
||||||
buf.y = info.y + Ypos;
|
// {
|
||||||
buf.w = info.w;
|
// SDL_Rect buf;
|
||||||
buf.h = info.h;
|
// buf.x = info.x + Xpos;
|
||||||
//TODO: 渲染可行区域
|
// buf.y = info.y + Ypos;
|
||||||
}
|
// buf.w = info.w;
|
||||||
|
// buf.h = info.h;
|
||||||
|
// //TODO: 渲染可行区域
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMapLayer::AddDebugFeasibleAreaInfo(Vec2 pos, VecSize size)
|
void GameMapLayer::AddDebugFeasibleAreaInfo(Vec2 pos, VecSize size)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
#include "EngineFrame/Base/Actor.h"
|
||||||
#include "EngineFrame/Component/Sprite.h"
|
#include "EngineFrame/Component/Sprite.h"
|
||||||
|
|
||||||
class BaseObject;
|
class BaseObject;
|
||||||
@@ -11,9 +11,6 @@ private:
|
|||||||
std::vector<SDL_Rect> FeasibleAreaInfoList;
|
std::vector<SDL_Rect> FeasibleAreaInfoList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameMapLayer(/* args */);
|
|
||||||
~GameMapLayer();
|
|
||||||
|
|
||||||
// 重载Render以实现绘制可行区域
|
// 重载Render以实现绘制可行区域
|
||||||
void Render() override;
|
void Render() override;
|
||||||
// 添加调试可行区域信息
|
// 添加调试可行区域信息
|
||||||
|
|||||||
@@ -1,33 +1,137 @@
|
|||||||
#include "Tile.h"
|
#include "Tile.h"
|
||||||
#include "Tool/Tool_String.h"
|
#include "Tool/Tool_String.h"
|
||||||
#include "EngineCore/Game.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<std::string>(m_data["path"]) == "")
|
||||||
|
// m_data["path"] = "sprite/character/common/circlecooltime.img";
|
||||||
|
|
||||||
|
// m_texture = new Texture();
|
||||||
|
// m_texture->Init(std::get<std::string>(m_data["path"]), std::get<int>(m_data["idx"]));
|
||||||
|
// Sprite::Init();
|
||||||
|
// this->imgPath = Path;
|
||||||
|
// }
|
||||||
|
|
||||||
|
Tile::Tile(GameMap *parentMap, std::vector<std::string> normal, std::vector<std::string> ex)
|
||||||
{
|
{
|
||||||
|
m_parentMap = parentMap;
|
||||||
|
m_texture = new Texture();
|
||||||
|
|
||||||
|
// 通过父对象获取地图大小
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile::Tile(std::string Path) : Sprite()
|
SetPos(Vec2(0, 80 - 200 - std::get<int>(m_parentMap->_MapInfo["background_pos"])));
|
||||||
{
|
|
||||||
InitInfo(Path);
|
|
||||||
if (std::get<std::string>(m_data["path"]) == "")
|
|
||||||
m_data["path"] = "sprite/character/common/circlecooltime.img";
|
|
||||||
|
|
||||||
m_texture = new Texture();
|
|
||||||
m_texture->Init(std::get<std::string>(m_data["path"]), std::get<int>(m_data["idx"]));
|
|
||||||
Sprite::Init();
|
|
||||||
this->imgPath = Path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile::~Tile()
|
Tile::~Tile()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tile::SetPos(Vec2 pos)
|
void Tile::InitTile(std::string Path, int Index)
|
||||||
{
|
{
|
||||||
pos.y += std::get<int>(m_data["pos"]);
|
// 读取文件
|
||||||
Sprite::SetPos(pos);
|
TileInfo data;
|
||||||
|
InitInfo(Path, data);
|
||||||
|
// 读取信息
|
||||||
|
std::string path = std::get<std::string>(data["path"]);
|
||||||
|
int index = std::get<int>(data["idx"]);
|
||||||
|
// 如果是个空地板 给他默认赋值
|
||||||
|
if (path == "")
|
||||||
|
path = "sprite/character/common/circlecooltime.img";
|
||||||
|
|
||||||
|
// 构造纹理标识符
|
||||||
|
ImgKey key = {path, index};
|
||||||
|
// 判断是否存在标识符对应的纹理,如果不存在则创建
|
||||||
|
if (m_imgMap.find(key) == m_imgMap.end())
|
||||||
|
{
|
||||||
|
RefPtr<Texture> 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<std::string>(data["path"]);
|
||||||
|
int index = std::get<int>(data["idx"]);
|
||||||
|
// 如果是个空地板 给他默认赋值
|
||||||
|
if (path == "")
|
||||||
|
path = "sprite/character/common/circlecooltime.img";
|
||||||
|
|
||||||
|
// 构造纹理标识符
|
||||||
|
ImgKey key = {path, index};
|
||||||
|
// 判断是否存在标识符对应的纹理,如果不存在则创建
|
||||||
|
if (m_imgMap.find(key) == m_imgMap.end())
|
||||||
|
{
|
||||||
|
RefPtr<Texture> 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<int>(m_data["pos"]);
|
||||||
|
// // Sprite::SetPos(pos);
|
||||||
|
// }
|
||||||
|
|
||||||
|
void Tile::InitInfo(std::string Path, TileInfo &m_data)
|
||||||
{
|
{
|
||||||
ScriptData Data = AssetManager::GetInstance().GetScriptInfo(Path);
|
ScriptData Data = AssetManager::GetInstance().GetScriptInfo(Path);
|
||||||
m_data["pos"] = 0;
|
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");
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,22 +1,65 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Asset/AssetManager.h"
|
#include "Asset/AssetManager.h"
|
||||||
#include "EngineFrame/Component/Sprite.h"
|
#include "EngineFrame/Component/Canvas.h"
|
||||||
class Tile : public Sprite
|
class GameMap;
|
||||||
|
class Tile : public Actor
|
||||||
{
|
{
|
||||||
|
struct ImgKey
|
||||||
|
{
|
||||||
|
std::string img;
|
||||||
|
int index;
|
||||||
|
|
||||||
using TileInfoBody = std::variant<
|
bool operator<(const ImgKey &other) const
|
||||||
int,
|
{
|
||||||
std::string>;
|
if (img != other.img)
|
||||||
|
{
|
||||||
private:
|
return img < other.img; // 字符串按字典序比较
|
||||||
std::unordered_map<std::string, TileInfoBody> m_data;
|
}
|
||||||
|
return index < other.index; // 字符串相同则比较index
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct DrawInfo
|
||||||
|
{
|
||||||
|
ImgKey texture;
|
||||||
|
SDL_FRect rect = {0, 0, 0, 0};
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Tile(/* args */);
|
using TileInfoBody = std::variant<int,std::string>;
|
||||||
Tile(std::string Path);
|
using TileInfo = std::unordered_map<std::string, TileInfoBody>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**纹理 */
|
||||||
|
RefPtr<Texture> m_texture = nullptr;
|
||||||
|
/**FBO */
|
||||||
|
GLuint m_fbo = 0;
|
||||||
|
/**地图父对象 */
|
||||||
|
GameMap* m_parentMap;
|
||||||
|
|
||||||
|
/**绘制纹理集 */
|
||||||
|
std::map<ImgKey, RefPtr<Texture>> m_imgMap;
|
||||||
|
/**绘制队列 */
|
||||||
|
std::vector<DrawInfo> 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<std::string> normal,std::vector<std::string> ex);
|
||||||
~Tile();
|
~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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "ActiveObject.h"
|
#include "ActiveObject.h"
|
||||||
void ActiveObject::SetPosition(VecPos3 pos)
|
void ActiveObject::SetPosition(VecFPos3 pos)
|
||||||
{
|
{
|
||||||
BaseObject::SetPosition(pos);
|
BaseObject::SetPosition(pos);
|
||||||
}
|
}
|
||||||
@@ -21,49 +21,36 @@ VecSpeed3 ActiveObject::GetSpeed()
|
|||||||
|
|
||||||
void ActiveObject::Update(float deltaTime)
|
void ActiveObject::Update(float deltaTime)
|
||||||
{
|
{
|
||||||
int IntegerDelta = static_cast<int>(deltaTime * 1000);
|
|
||||||
const int Gravity = 1020;
|
|
||||||
|
|
||||||
|
VecFPos3 MovePos;
|
||||||
// X轴移动(含余数补偿)
|
// X轴移动(含余数补偿)
|
||||||
if (Speed.x != 0)
|
if (Speed.x != 0)
|
||||||
{
|
{
|
||||||
int totalX = Speed.x * IntegerDelta + Remainder.x; // 加上上次余数
|
MovePos.x = Speed.x * deltaTime;
|
||||||
int moveX = totalX / 1000; // 整数部分为实际移动
|
|
||||||
Remainder.x = totalX % 1000; // 保留余数(-999~999)
|
|
||||||
MoveBy(moveX, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Y轴移动(同上)
|
// Y轴移动(同上)
|
||||||
if (Speed.y != 0)
|
if (Speed.y != 0)
|
||||||
{
|
{
|
||||||
int totalY = Speed.y * IntegerDelta + Remainder.y;
|
MovePos.y = Speed.y * deltaTime;
|
||||||
int moveY = totalY / 1000;
|
|
||||||
Remainder.y = totalY % 1000;
|
|
||||||
MoveBy(0, moveY, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Z轴重力与移动(含余数补偿)
|
// Z轴重力与移动(含余数补偿)
|
||||||
if (Position.z > 0 || Speed.z > 0)
|
if (Position.z > 0 || Speed.z > 0)
|
||||||
{
|
{
|
||||||
// 重力对速度的影响(先更新Speed.z,含余数)
|
int speedZTotal = -1020 * deltaTime;
|
||||||
int speedZTotal = -Gravity * IntegerDelta + Remainder.z; // 注意负号(减速)
|
|
||||||
Speed.z += speedZTotal / 1000; // 速度的整数部分
|
|
||||||
Remainder.z = speedZTotal % 1000; // 速度的余数
|
|
||||||
|
|
||||||
// 基于更新后的Speed.z计算移动量(同样含余数)
|
// 基于更新后的Speed.z计算移动量(同样含余数)
|
||||||
int moveZTotal = Speed.z * IntegerDelta + _zRemainderMove; // 新增_zRemainderMove记录移动余数
|
MovePos.z = Speed.z * deltaTime;
|
||||||
int moveZ = moveZTotal / 1000;
|
|
||||||
_zRemainderMove = moveZTotal % 1000;
|
|
||||||
MoveBy(0, 0, moveZ);
|
|
||||||
}
|
}
|
||||||
else if (Position.z < 0)
|
else if (Position.z < 0)
|
||||||
{
|
{
|
||||||
Position.z = 0;
|
Position.z = 0;
|
||||||
Speed.z = 0;
|
Speed.z = 0;
|
||||||
Remainder.z = 0; // 重置余数
|
|
||||||
_zRemainderMove = 0;
|
|
||||||
SetPosition(Position);
|
SetPosition(Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoveBy(MovePos);
|
||||||
|
|
||||||
BaseObject::Update(deltaTime);
|
BaseObject::Update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ class ActiveObject : public BaseObject
|
|||||||
public:
|
public:
|
||||||
// 三轴速度
|
// 三轴速度
|
||||||
VecSpeed3 Speed;
|
VecSpeed3 Speed;
|
||||||
// 三轴移动余数
|
|
||||||
VecPos3 Remainder;
|
|
||||||
int _zRemainderMove = 0;
|
int _zRemainderMove = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void
|
void
|
||||||
SetPosition(VecPos3 pos) override;
|
SetPosition(VecFPos3 pos) override;
|
||||||
void SetYpos(int y) override;
|
void SetYpos(int y) override;
|
||||||
|
|
||||||
void SetSpeed(VecSpeed3 speed);
|
void SetSpeed(VecSpeed3 speed);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "BaseObject.h"
|
#include "BaseObject.h"
|
||||||
#include "Actor/Map/GameMap.h"
|
#include "Actor/Map/GameMap.h"
|
||||||
#include "Actor/Map/GameMapCamera.h"
|
|
||||||
|
|
||||||
BaseObject::BaseObject()
|
BaseObject::BaseObject()
|
||||||
{
|
{
|
||||||
@@ -14,15 +13,13 @@ BaseObject::~BaseObject()
|
|||||||
|
|
||||||
void BaseObject::Update(float deltaTime)
|
void BaseObject::Update(float deltaTime)
|
||||||
{
|
{
|
||||||
if (_AffCamera != nullptr)
|
|
||||||
{
|
|
||||||
_AffCamera->SyncPos(deltaTime);
|
|
||||||
}
|
|
||||||
Actor::Update(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)
|
if (pos.y != this->Position.y)
|
||||||
{
|
{
|
||||||
SetRenderZOrder(pos.y); // 设置渲染顺序
|
SetRenderZOrder(pos.y); // 设置渲染顺序
|
||||||
@@ -31,19 +28,23 @@ void BaseObject::SetPosition(VecPos3 pos)
|
|||||||
SetPos(Vec2{this->Position.x, this->Position.y - this->Position.z});
|
SetPos(Vec2{this->Position.x, this->Position.y - this->Position.z});
|
||||||
}
|
}
|
||||||
|
|
||||||
VecPos3 BaseObject::GetPosition()
|
VecFPos3 BaseObject::GetPosition()
|
||||||
{
|
{
|
||||||
return this->Position;
|
return this->Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseObject::SetXpos(int x)
|
void BaseObject::SetXpos(int x)
|
||||||
{
|
{
|
||||||
|
if (x == this->Position.x)
|
||||||
|
return;
|
||||||
this->Position.x = x;
|
this->Position.x = x;
|
||||||
SetPos({this->Position.x, this->Position.y - this->Position.z});
|
SetPos({this->Position.x, this->Position.y - this->Position.z});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseObject::SetYpos(int y)
|
void BaseObject::SetYpos(int y)
|
||||||
{
|
{
|
||||||
|
if (y == this->Position.y)
|
||||||
|
return;
|
||||||
if (y != this->Position.y)
|
if (y != this->Position.y)
|
||||||
{
|
{
|
||||||
SetRenderZOrder(y); // 设置渲染顺序
|
SetRenderZOrder(y); // 设置渲染顺序
|
||||||
@@ -54,6 +55,8 @@ void BaseObject::SetYpos(int y)
|
|||||||
|
|
||||||
void BaseObject::SetZpos(int z)
|
void BaseObject::SetZpos(int z)
|
||||||
{
|
{
|
||||||
|
if (z == this->Position.z)
|
||||||
|
return;
|
||||||
this->Position.z = z;
|
this->Position.z = z;
|
||||||
SetPos({this->Position.x, this->Position.y - this->Position.z});
|
SetPos({this->Position.x, this->Position.y - this->Position.z});
|
||||||
}
|
}
|
||||||
@@ -73,10 +76,12 @@ int BaseObject::GetZpos()
|
|||||||
return this->Position.z;
|
return this->Position.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseObject::MoveBy(VecPos3 pos)
|
void BaseObject::MoveBy(VecFPos3 pos)
|
||||||
{
|
{
|
||||||
// 只有moveby移动时判断所在地图中是否能够这样移动
|
// 只有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)
|
if (RealPos.y != this->Position.y)
|
||||||
{
|
{
|
||||||
SetRenderZOrder(RealPos.y); // 设置渲染顺序
|
SetRenderZOrder(RealPos.y); // 设置渲染顺序
|
||||||
@@ -90,7 +95,9 @@ void BaseObject::MoveBy(VecPos3 pos)
|
|||||||
void BaseObject::MoveBy(int x, int y, int z)
|
void BaseObject::MoveBy(int x, int y, int z)
|
||||||
{
|
{
|
||||||
// 只有moveby移动时判断所在地图中是否能够这样移动
|
// 只有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)
|
if (RealPos.y != this->Position.y)
|
||||||
{
|
{
|
||||||
SetRenderZOrder(RealPos.y); // 设置渲染顺序
|
SetRenderZOrder(RealPos.y); // 设置渲染顺序
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EngineFrame/Actor/Actor.h"
|
#include "EngineFrame/Base/Actor.h"
|
||||||
#include "Asset/Common/ObjectVars.h"
|
#include "Asset/Common/ObjectVars.h"
|
||||||
#include "Global/Global_Enum.h"
|
#include "Global/Global_Enum.h"
|
||||||
class GameMap;
|
class GameMap;
|
||||||
class GameMapCamera;
|
|
||||||
class BaseObject : public Actor
|
class BaseObject : public Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
public:
|
public:
|
||||||
ObjectType m_objecttype; // 对象类型
|
ObjectType m_objecttype; // 对象类型
|
||||||
VecPos3 Position; // 位置
|
VecFPos3 Position; // 位置
|
||||||
int Direction = 0; // 方向
|
int Direction = 0; // 方向
|
||||||
GameMap *_AffMap = nullptr; // 所在地图
|
GameMap *_AffMap = nullptr; // 所在地图
|
||||||
GameMapCamera *_AffCamera = nullptr; // 跟随相机
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BaseObject(/* args */);
|
BaseObject(/* args */);
|
||||||
@@ -24,17 +22,17 @@ public:
|
|||||||
ObjectVars _ObjectVars;
|
ObjectVars _ObjectVars;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void SetPosition(VecPos3 pos);
|
virtual void SetPosition(VecFPos3 pos);
|
||||||
virtual void SetXpos(int x);
|
virtual void SetXpos(int x);
|
||||||
virtual void SetYpos(int y);
|
virtual void SetYpos(int y);
|
||||||
virtual void SetZpos(int z);
|
virtual void SetZpos(int z);
|
||||||
|
|
||||||
VecPos3 GetPosition();
|
VecFPos3 GetPosition();
|
||||||
int GetXpos();
|
int GetXpos();
|
||||||
int GetYpos();
|
int GetYpos();
|
||||||
int GetZpos();
|
int GetZpos();
|
||||||
|
|
||||||
virtual void MoveBy(VecPos3 pos);
|
virtual void MoveBy(VecFPos3 pos);
|
||||||
virtual void MoveBy(int x, int y, int z);
|
virtual void MoveBy(int x, int y, int z);
|
||||||
|
|
||||||
virtual void SetDirection(int dir);
|
virtual void SetDirection(int dir);
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EngineFrame/Component/Component.h"
|
|
||||||
#include "Asset/Common/Equipment.h"
|
#include "Asset/Common/Equipment.h"
|
||||||
|
#include "EngineFrame/Base/Actor.h"
|
||||||
class CharacterObject;
|
class CharacterObject;
|
||||||
class Chr_Equipment : public Component
|
class Chr_Equipment : public Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 默认装备
|
// 默认装备
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EngineFrame/Component/Component.h"
|
|
||||||
#include "Global/Global_Enum.h"
|
#include "Global/Global_Enum.h"
|
||||||
|
#include "EngineFrame/Base/Actor.h"
|
||||||
class CharacterObject;
|
class CharacterObject;
|
||||||
class Chr_StateMachine : public Component
|
class Chr_StateMachine : public Actor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// 父对象
|
// 父对象
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EngineFrame/Component/Component.h"
|
|
||||||
#include "Global/Global_Enum.h"
|
#include "Global/Global_Enum.h"
|
||||||
class Equipment : public Component
|
#include "EngineFrame/Base/Actor.h"
|
||||||
|
class Equipment : public Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 职业动画结构体
|
// 职业动画结构体
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ static SQInteger SQR_GetPosition(HSQUIRRELVM v)
|
|||||||
SQUserPointer ptr;
|
SQUserPointer ptr;
|
||||||
sq_getuserpointer(v, 2, &ptr);
|
sq_getuserpointer(v, 2, &ptr);
|
||||||
BaseObject *obj = (BaseObject *)ptr;
|
BaseObject *obj = (BaseObject *)ptr;
|
||||||
VecPos3 Pos = obj->GetPosition();
|
VecFPos3 Pos = obj->GetPosition();
|
||||||
|
|
||||||
sq_newtable(v);
|
sq_newtable(v);
|
||||||
sq_pushstring(v, _SC("x"), -1);
|
sq_pushstring(v, _SC("x"), -1);
|
||||||
@@ -40,7 +40,7 @@ static SQInteger SQR_SetPosition(HSQUIRRELVM v)
|
|||||||
sq_getfloat(v, 3, &PosX);
|
sq_getfloat(v, 3, &PosX);
|
||||||
sq_getfloat(v, 4, &PosY);
|
sq_getfloat(v, 4, &PosY);
|
||||||
sq_getfloat(v, 5, &PosZ);
|
sq_getfloat(v, 5, &PosZ);
|
||||||
obj->SetPosition(VecPos3(PosX, PosY, PosZ));
|
obj->SetPosition(VecFPos3(PosX, PosY, PosZ));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "squirrel/SquirrelEx.h"
|
#include "squirrel/SquirrelEx.h"
|
||||||
#include "Global/Global_Game.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)
|
static SQRESULT sq_GetVecSize(HSQUIRRELVM v, int Index, VecSize *Size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,59 +1,58 @@
|
|||||||
#include "GameMapCamera.h"
|
#include "GameCamera.h"
|
||||||
#include "EngineCore/Game.h"
|
#include "EngineCore/Game.h"
|
||||||
#include "Actor/Map/GameMap.h"
|
#include "Actor/Map/GameMap.h"
|
||||||
#include "Actor/Object/BaseObject.h"
|
#include "Actor/Object/BaseObject.h"
|
||||||
|
#include "Global/Global_Game.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
GameMapCamera::GameMapCamera()
|
void GameCamera::SetFromActor(BaseObject *actor)
|
||||||
{
|
{
|
||||||
|
// 如果原来有跟随对象
|
||||||
|
if (this->_FromActor)
|
||||||
|
{
|
||||||
|
this->_FromActor->RemoveCallbackOnUpdate("Camear Update");
|
||||||
}
|
}
|
||||||
|
|
||||||
GameMapCamera::~GameMapCamera()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameMapCamera::SetFromActor(BaseObject *actor)
|
|
||||||
{
|
|
||||||
this->_FromActor = actor;
|
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);
|
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->X = x;
|
||||||
// this->Y = y;
|
// this->Y = y;
|
||||||
// this->Z = z;
|
// 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->X += x;
|
||||||
// this->Y += y;
|
// this->Y += y;
|
||||||
// this->Z += z;
|
// this->Z += z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMapCamera::SyncPosByFromParent(float deltaTime)
|
void GameCamera::SyncPosByFromParent(float deltaTime)
|
||||||
{
|
{
|
||||||
if (this->_FromActor == nullptr)
|
if (this->_FromActor == nullptr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int targetX = _FromActor->Position.x;
|
float targetX = _FromActor->Position.x;
|
||||||
int targetY = _FromActor->Position.y;
|
float targetY = _FromActor->Position.y;
|
||||||
|
|
||||||
if (_isSmoothMoving)
|
if (_isSmoothMoving)
|
||||||
{
|
{
|
||||||
// 平滑移动计算
|
// 平滑移动计算
|
||||||
VecPos targetPosition(targetX, targetY);
|
Vec2 targetPosition(targetX, targetY);
|
||||||
_currentPosition = SmoothDamp(_currentPosition, targetPosition, _velocity, _smoothTime, _maxSpeed, deltaTime);
|
_currentPosition = SmoothDamp(_currentPosition, targetPosition, _velocity, _smoothTime, _maxSpeed, deltaTime);
|
||||||
}
|
}
|
||||||
else
|
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时直接返回目标位置并重置速度
|
// 平滑时间为0时直接返回目标位置并重置速度
|
||||||
if (smoothTime <= 0.f)
|
if (smoothTime <= 0.f)
|
||||||
{
|
{
|
||||||
currentVelocity = VecPos(0, 0);
|
currentVelocity = Vec2(0, 0);
|
||||||
return target;
|
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);
|
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 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;
|
const float ty = delta.y * (omega * omega * deltaTime) - currentVelocity.y * (1.0f + 0.48f * x) * x;
|
||||||
VecPos targetVelocity(static_cast<int>(tx), static_cast<int>(ty));
|
Vec2 targetVelocity(tx, ty);
|
||||||
|
|
||||||
// 应用速度衰减(指数平滑)
|
// 应用速度衰减(指数平滑)
|
||||||
currentVelocity += targetVelocity;
|
currentVelocity += targetVelocity;
|
||||||
currentVelocity = VecPos(
|
currentVelocity = Vec2(currentVelocity.x * expTerm, currentVelocity.y * expTerm);
|
||||||
static_cast<int>(currentVelocity.x * expTerm),
|
|
||||||
static_cast<int>(currentVelocity.y * expTerm));
|
|
||||||
|
|
||||||
// 限制最大速度(如果设置了maxSpeed)
|
// 限制最大速度(如果设置了maxSpeed)
|
||||||
if (maxSpeed > 0)
|
if (maxSpeed > 0)
|
||||||
{
|
{
|
||||||
// 计算当前速度的模长(浮点精度)
|
// 计算当前速度的模长(浮点精度)
|
||||||
const float speedSq = static_cast<float>(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y);
|
const float speedSq = currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y;
|
||||||
const float maxSpeedSq = static_cast<float>(maxSpeed * maxSpeed);
|
const float maxSpeedSq = maxSpeed * maxSpeed;
|
||||||
|
|
||||||
if (speedSq > maxSpeedSq)
|
if (speedSq > maxSpeedSq)
|
||||||
{
|
{
|
||||||
// 速度超限,按比例缩放至最大速度
|
// 速度超限,按比例缩放至最大速度
|
||||||
const float scale = maxSpeed / sqrtf(speedSq);
|
const float scale = maxSpeed / sqrtf(speedSq);
|
||||||
currentVelocity = VecPos(
|
currentVelocity = Vec2(currentVelocity.x * scale, currentVelocity.y * scale);
|
||||||
static_cast<int>(currentVelocity.x * scale),
|
|
||||||
static_cast<int>(currentVelocity.y * scale));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算新位置(当前位置 + 速度 * 时间)
|
// 计算新位置(当前位置 + 速度 * 时间)
|
||||||
VecPos newPos = current + VecPos(
|
Vec2 newPos = current + Vec2(currentVelocity.x * deltaTime, currentVelocity.y * deltaTime);
|
||||||
static_cast<int>(currentVelocity.x * deltaTime),
|
|
||||||
static_cast<int>(currentVelocity.y * deltaTime));
|
|
||||||
|
|
||||||
// 检测过冲:如果新位置已越过目标,直接锁定目标并重置速度
|
// 检测过冲:如果新位置已越过目标,直接锁定目标并重置速度
|
||||||
// 点积 > 0 表示方向相反(已超过目标)
|
// 点积 > 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)
|
if (dot > 0)
|
||||||
{
|
{
|
||||||
newPos = target;
|
newPos = target;
|
||||||
currentVelocity = VecPos(0, 0);
|
currentVelocity = Vec2(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newPos;
|
return newPos;
|
||||||
35
source_game/Global/GameCamera.h
Normal file
35
source_game/Global/GameCamera.h
Normal file
@@ -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);
|
||||||
|
};
|
||||||
@@ -4,9 +4,6 @@
|
|||||||
Global_Game::Global_Game()
|
Global_Game::Global_Game()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Global_Game::~Global_Game()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Global_Game::InitFont()
|
void Global_Game::InitFont()
|
||||||
{
|
{
|
||||||
@@ -65,11 +62,6 @@ void Global_Game::InitFont()
|
|||||||
void Global_Game::Init()
|
void Global_Game::Init()
|
||||||
{
|
{
|
||||||
InitFont();
|
InitFont();
|
||||||
|
|
||||||
// TTF_Font *FontBuf = TTF_OpenFont("Fonts/NotoSansSC-Regular.otf", 24);
|
|
||||||
// TTF_Font *FontBuf = TTF_OpenFont("Fonts/calibri.ttf", 24);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Global_Game::InitGame()
|
void Global_Game::InitGame()
|
||||||
@@ -83,9 +75,11 @@ void Global_Game::InitGame()
|
|||||||
|
|
||||||
// 初始化松鼠脚本管理器
|
// 初始化松鼠脚本管理器
|
||||||
SquirrelManager::GetInstance().Init();
|
SquirrelManager::GetInstance().Init();
|
||||||
|
|
||||||
// 读取存档
|
// 读取存档
|
||||||
SavaManager::GetInstance().Init();
|
SavaManager::GetInstance().Init();
|
||||||
|
|
||||||
|
//创建摄像机
|
||||||
|
_GameCamera = new GameCamera();
|
||||||
// 游戏初始化完成标志
|
// 游戏初始化完成标志
|
||||||
InitFlag = true;
|
InitFlag = true;
|
||||||
}
|
}
|
||||||
@@ -110,3 +104,8 @@ GlobalMonsterScript::MonsterConfig Global_Game::GetMonsterInfo(int id)
|
|||||||
MonsterInfoMap[id] = MonsterConfig;
|
MonsterInfoMap[id] = MonsterConfig;
|
||||||
return MonsterConfig;
|
return MonsterConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<GameCamera> Global_Game::GetCamera()
|
||||||
|
{
|
||||||
|
return _GameCamera;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "Global/Script/EquipmentConfig.h"
|
#include "Global/Script/EquipmentConfig.h"
|
||||||
#include "Global/Script/MonsterConfig.h"
|
#include "Global/Script/MonsterConfig.h"
|
||||||
#include "Global/Save/SavaManager.h"
|
#include "Global/Save/SavaManager.h"
|
||||||
|
#include "Global/GameCamera.h"
|
||||||
class Global_Game
|
class Global_Game
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -19,14 +20,15 @@ public:
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Global_Game();
|
||||||
|
|
||||||
// 游戏资源加载之前的初始化
|
// 游戏资源加载之前的初始化
|
||||||
void Init();
|
void Init();
|
||||||
// 游戏资源加载之后的初始化
|
// 游戏资源加载之后的初始化
|
||||||
void InitGame();
|
void InitGame();
|
||||||
|
|
||||||
public:
|
private:
|
||||||
// 当前游戏状态 0未初始化
|
void InitFont();
|
||||||
int game_state = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 字体资源
|
// 字体资源
|
||||||
@@ -41,12 +43,12 @@ public:
|
|||||||
std::map<int, GlobalMonsterScript::MonsterConfig> MonsterInfoMap; // 信息
|
std::map<int, GlobalMonsterScript::MonsterConfig> MonsterInfoMap; // 信息
|
||||||
GlobalMonsterScript::MonsterConfig GetMonsterInfo(int id); // 获取怪物信息
|
GlobalMonsterScript::MonsterConfig GetMonsterInfo(int id); // 获取怪物信息
|
||||||
|
|
||||||
|
// 游戏摄像机
|
||||||
|
RefPtr<GameCamera> _GameCamera = nullptr;
|
||||||
|
|
||||||
// 游戏资源初始化标志
|
// 游戏资源初始化标志
|
||||||
bool InitFlag = false;
|
bool InitFlag = false;
|
||||||
|
|
||||||
private:
|
public:
|
||||||
Global_Game(/* args */);
|
RefPtr<GameCamera> GetCamera();
|
||||||
~Global_Game();
|
|
||||||
|
|
||||||
void InitFont();
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,18 +20,18 @@ void Scene_Loading_UI::Enter()
|
|||||||
AddChild(actor);
|
AddChild(actor);
|
||||||
|
|
||||||
RefPtr<Sprite> BackGroundSp = new Sprite("ImagePacks2/Loading1.png");
|
RefPtr<Sprite> BackGroundSp = new Sprite("ImagePacks2/Loading1.png");
|
||||||
actor->AddComponent(BackGroundSp);
|
actor->AddChild(BackGroundSp);
|
||||||
RefPtr<Sprite> BackGround2Sp = new Sprite("ImagePacks2/Loading0.png");
|
RefPtr<Sprite> BackGround2Sp = new Sprite("ImagePacks2/Loading0.png");
|
||||||
BackGround2Sp->SetPos(Vec2{0, 686});
|
BackGround2Sp->SetPos(Vec2{0, 686});
|
||||||
actor->AddComponent(BackGround2Sp);
|
actor->AddChild(BackGround2Sp);
|
||||||
RefPtr<Sprite> LoadCircleSp = new Sprite("ImagePacks2/Loading2.png");
|
RefPtr<Sprite> LoadCircleSp = new Sprite("ImagePacks2/Loading2.png");
|
||||||
LoadCircleSp->SetName("LoadCircle");
|
LoadCircleSp->SetName("LoadCircle");
|
||||||
LoadCircleSp->SetPos(Vec2{1280 - 60, 686 - 60});
|
LoadCircleSp->SetPos(Vec2{1280 - 60, 686 - 60});
|
||||||
LoadCircleSp->SetBlendMode(LINEARDODGE);
|
LoadCircleSp->SetBlendMode(LINEARDODGE);
|
||||||
LoadCircleSp->SetAnchor(Vec2{0.5f, 0.5f});
|
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();
|
float angle = LoadCircleSp->GetRotation();
|
||||||
LoadCircleSp->SetRotation(angle + 180.0f * deltaTime); });
|
LoadCircleSp->SetRotation(angle + 180.0f * deltaTime); });
|
||||||
|
|||||||
@@ -17,23 +17,25 @@ Scene_Test::~Scene_Test()
|
|||||||
void Scene_Test::Enter()
|
void Scene_Test::Enter()
|
||||||
{
|
{
|
||||||
map = new GameMap;
|
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);
|
map->Enter(this);
|
||||||
|
AddChild(map);
|
||||||
|
map->SetCallbackOnUpdate("csas", [this](float dt)
|
||||||
|
{
|
||||||
|
Vec2 pos = map->GetPos();
|
||||||
|
pos.x -= 10 * dt;
|
||||||
|
map->SetPos(pos); });
|
||||||
|
|
||||||
RefPtr<CharacterObject> obj = new CharacterObject();
|
// RefPtr<CharacterObject> obj = new CharacterObject();
|
||||||
obj->SetPosition({1000, 300, 0});
|
// obj->SetPosition({1000, 300, 0});
|
||||||
obj->Construction(0);
|
// obj->Construction(0);
|
||||||
|
// map->AddObject(obj);
|
||||||
|
|
||||||
map->AddObject(obj);
|
// RefPtr<MonsterObject> monster = new MonsterObject();
|
||||||
|
// monster->SetPosition({1200, 301, 0});
|
||||||
RefPtr<MonsterObject> monster = new MonsterObject();
|
// monster->Construction(1);
|
||||||
monster->SetPosition({1200, 301, 0});
|
// monster->SetDirection(1);
|
||||||
monster->Construction(1);
|
// map->AddObject(monster);
|
||||||
monster->SetDirection(1);
|
|
||||||
map->AddObject(monster);
|
|
||||||
|
|
||||||
_camera = new GameMapCamera;
|
|
||||||
_camera->SetFromActor(obj.Get());
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -107,11 +109,6 @@ void Scene_Test::HandleEvents(SDL_Event *e)
|
|||||||
void Scene_Test::Update(float deltaTime)
|
void Scene_Test::Update(float deltaTime)
|
||||||
{
|
{
|
||||||
Scene::Update(deltaTime);
|
Scene::Update(deltaTime);
|
||||||
// 摄像机中有检测宿主坐标 所以要在场景的update后调用以便读取到本帧最新的坐标
|
|
||||||
if (_camera)
|
|
||||||
_camera->Update(deltaTime);
|
|
||||||
if (map)
|
|
||||||
map->Update(deltaTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene_Test::Render()
|
void Scene_Test::Render()
|
||||||
@@ -123,8 +120,3 @@ void Scene_Test::Exit()
|
|||||||
{
|
{
|
||||||
SDL_Log("Scene_Test::退出测试场景!当前引用计数%d", this->GetRefCount());
|
SDL_Log("Scene_Test::退出测试场景!当前引用计数%d", this->GetRefCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<BaseNode> Scene_Test::GetCamera()
|
|
||||||
{
|
|
||||||
return this->_camera;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "Asset/AssetManager.h"
|
#include "Asset/AssetManager.h"
|
||||||
#include "EngineFrame/Component/Animation.h"
|
#include "EngineFrame/Component/Animation.h"
|
||||||
#include "Actor/Map/GameMap.h"
|
#include "Actor/Map/GameMap.h"
|
||||||
#include "Actor/Map/GameMapCamera.h"
|
|
||||||
#include "Actor/Object/CharacterObject.h"
|
#include "Actor/Object/CharacterObject.h"
|
||||||
#include "Actor/Object/MonsterObject.h"
|
#include "Actor/Object/MonsterObject.h"
|
||||||
|
|
||||||
@@ -11,7 +10,6 @@ class Scene_Test : public Scene
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
GameMap *map = nullptr;
|
GameMap *map = nullptr;
|
||||||
RefPtr<GameMapCamera> _camera = nullptr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Scene_Test(/* args */);
|
Scene_Test(/* args */);
|
||||||
@@ -23,7 +21,7 @@ public:
|
|||||||
void Update(float deltaTime) override;
|
void Update(float deltaTime) override;
|
||||||
void Render() override;
|
void Render() override;
|
||||||
void Exit() override;
|
void Exit() override;
|
||||||
RefPtr<BaseNode> GetCamera() override;
|
|
||||||
public:
|
public:
|
||||||
int MyId = 0;
|
int MyId = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user