11111
This commit is contained in:
parent
c1c6c7fe7f
commit
1032578ed1
|
|
@ -4,3 +4,7 @@ MyGame.lst
|
|||
MyGame.elf
|
||||
build/
|
||||
romfs/
|
||||
SwitchGame.elf
|
||||
SwitchGame.nacp
|
||||
SwitchGame.nro
|
||||
.vscode/
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@
|
|||
"includePath": [
|
||||
"${workspaceFolder}/source/**",
|
||||
"${workspaceFolder}/source_game/**",
|
||||
"L:/Switch/devkitPro/devkitA64/aarch64-none-elf/include",
|
||||
"L:/Switch/devkitPro/libnx/include",
|
||||
"L:/Switch/devkitPro/portlibs/switch/include",
|
||||
"L:/Switch/devkitPro/portlibs/switch/include/SDL2"
|
||||
"D:/devkitPro/devkitA64/aarch64-none-elf/include",
|
||||
"D:/devkitPro/libnx/include",
|
||||
"D:/devkitPro/portlibs/switch/include",
|
||||
"D:/devkitPro/portlibs/switch/include/SDL2"
|
||||
],
|
||||
"defines": [
|
||||
"__SWITCH__"
|
||||
],
|
||||
"compilerPath": "L:/Switch/devkitPro/devkitA64/bin/aarch64-none-elf-gcc",
|
||||
"compilerPath": "D:/devkitPro/devkitA64/bin/aarch64-none-elf-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "gcc-arm",
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -55,6 +55,8 @@ ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
|||
|
||||
CFLAGS := `$(PREFIX)pkg-config --cflags sdl2 SDL2_mixer SDL2_image` -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
# CFLAGS := `$(PREFIX)pkg-config --cflags sdl2 SDL2_mixer SDL2_image` -Wall -g -O0 -ffunction-sections \
|
||||
# $(ARCH) $(DEFINES) -DDEBUG # 添加 -g -O0 -DDEBUG
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
|
|
|
|||
|
|
@ -76,5 +76,11 @@
|
|||
},
|
||||
"source_game/Asset/AnimationStruct.h": {
|
||||
"description": "Ani结构数据"
|
||||
},
|
||||
"source/EngineFrame/Component/Component.h": {
|
||||
"description": "组件基类"
|
||||
},
|
||||
"source/EngineFrame/Component/Animation.h": {
|
||||
"description": "动画类"
|
||||
}
|
||||
}
|
||||
|
|
@ -36,10 +36,6 @@ public:
|
|||
int Xpos;
|
||||
// Ypos
|
||||
int Ypos;
|
||||
// Xpos
|
||||
int XposEx = 0;
|
||||
// Ypos
|
||||
int YposEx = 0;
|
||||
// 帧域X
|
||||
int FrameXpos;
|
||||
// 帧域Y
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ void Game::Init(std::function<void()> CallBack)
|
|||
m_isRunning = false;
|
||||
}
|
||||
// SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
|
||||
|
||||
// 构造调试对象
|
||||
m_DebugInfoActor = new Debug_Actor();
|
||||
CallBack();
|
||||
}
|
||||
|
|
@ -127,6 +127,14 @@ void Game::HandleEvents(SDL_Event *e)
|
|||
SDL_Log("Game Exit2");
|
||||
}
|
||||
}
|
||||
// 处理屏幕按下事件
|
||||
else if (e->type == SDL_FINGERDOWN)
|
||||
{
|
||||
// 触发双击事件
|
||||
SDL_Log("退出程序");
|
||||
m_isRunning = false;
|
||||
SDL_Log("Game Exit3");
|
||||
}
|
||||
|
||||
if (m_scene != nullptr)
|
||||
m_scene->HandleEvents(e);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "Actor.h"
|
||||
#include "EngineFrame/Scene/Scene.h"
|
||||
#include <algorithm>
|
||||
|
||||
Actor::Actor()
|
||||
{
|
||||
|
|
@ -23,7 +24,11 @@ void Actor::Update(float deltaTime)
|
|||
RefPtr<Component> child = m_Components.GetFirst();
|
||||
while (child)
|
||||
{
|
||||
child->Update(deltaTime);
|
||||
if (child->hasTag(Tag::UPDATE))
|
||||
child->Update(deltaTime);
|
||||
if (child->hasTag(Tag::RENDER))
|
||||
{
|
||||
}
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +39,8 @@ void Actor::Render(float deltaTime)
|
|||
RefPtr<Component> child = m_Components.GetFirst();
|
||||
while (child)
|
||||
{
|
||||
child->Render(deltaTime);
|
||||
if (child->hasTag(Tag::RENDER))
|
||||
child->Render(deltaTime);
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
|
|
@ -46,5 +52,22 @@ void Actor::Clear()
|
|||
void Actor::AddComponent(RefPtr<Component> Component)
|
||||
{
|
||||
m_Components.PushBack(Component);
|
||||
Component->Parent = this;
|
||||
}
|
||||
Component->OnAdded(this);
|
||||
Component->ReorderComponents();
|
||||
}
|
||||
|
||||
void Actor::RemoveComponent(RefPtr<Component> Component)
|
||||
{
|
||||
Component->Parent = nullptr;
|
||||
m_Components.Remove(Component);
|
||||
}
|
||||
|
||||
void Actor::SetPos(SDL_Point pos)
|
||||
{
|
||||
this->Pos = pos;
|
||||
}
|
||||
|
||||
SDL_Point Actor::GetPos()
|
||||
{
|
||||
return this->Pos;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ class Scene;
|
|||
*/
|
||||
class Actor : public Actor_base, protected IntrusiveListValue<RefPtr<Actor>>
|
||||
{
|
||||
|
||||
public:
|
||||
Actor();
|
||||
~Actor() override;
|
||||
|
|
@ -26,10 +27,15 @@ public:
|
|||
|
||||
public:
|
||||
void AddComponent(RefPtr<Component> Component);
|
||||
void RemoveComponent(RefPtr<Component> Component);
|
||||
void SetPos(SDL_Point pos);
|
||||
SDL_Point GetPos();
|
||||
|
||||
public:
|
||||
Scene *Parent; // 指向父场景的指针,表示该Actor所属的场景
|
||||
Scene *Parent; // 指向父场景的指针,表示该Actor所属的场景
|
||||
SDL_Point Pos = {0, 0}; // 位置坐标
|
||||
|
||||
IntrusiveList<RefPtr<Component>> m_Components; // 组件列表
|
||||
|
||||
private:
|
||||
IntrusiveList<RefPtr<Component>> m_Components;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,3 +27,13 @@ void Actor_base::SetCallbackOnUpdate(const UpdateCallback &cb)
|
|||
{
|
||||
cb_update_ = cb;
|
||||
}
|
||||
|
||||
int Actor_base::GetRenderZOrder()
|
||||
{
|
||||
return this->RenderZOrder;
|
||||
}
|
||||
|
||||
void Actor_base::SetRenderZOrder(int zOrder)
|
||||
{
|
||||
this->RenderZOrder = zOrder;
|
||||
}
|
||||
|
|
@ -28,4 +28,9 @@ public:
|
|||
private:
|
||||
/* data */
|
||||
UpdateCallback cb_update_; // 更新时的回调函数
|
||||
int RenderZOrder = 0; // 渲染层级
|
||||
|
||||
public:
|
||||
int GetRenderZOrder();
|
||||
void SetRenderZOrder(int zOrder);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,307 @@
|
|||
#include "Animation.h"
|
||||
#include "Asset/AssetManager.h"
|
||||
#include "Tool/Math.h"
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
|
||||
Animation::Animation()
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(std::string AniPath)
|
||||
{
|
||||
Init(AniPath);
|
||||
}
|
||||
|
||||
Animation::Animation(std::string AniPath, std::function<std::string(std::string)> AdditionalOptions)
|
||||
{
|
||||
this->AdditionalOptions = AdditionalOptions;
|
||||
Init(AniPath);
|
||||
}
|
||||
|
||||
Animation::~Animation()
|
||||
{
|
||||
}
|
||||
|
||||
void Animation::Init(std::string AniPath)
|
||||
{
|
||||
// 标记该组件需要渲染和更新
|
||||
addTag(Tag::RENDER);
|
||||
addTag(Tag::UPDATE);
|
||||
|
||||
AniScriptParser::AniInfo Info = AssetManager::GetInstance().StructAniInfo(AniPath);
|
||||
this->AniPath = AniPath;
|
||||
this->AnimationFlag = Info.Flag;
|
||||
this->FrameArr = Info.Frame;
|
||||
|
||||
for (size_t i = 0; i < this->FrameArr.size(); i++)
|
||||
{
|
||||
AniScriptParser::AniFrame FrameObj = this->FrameArr[i];
|
||||
RefPtr<Sprite> SpriteObj = new Sprite();
|
||||
if (!FrameObj.Img_Path.empty())
|
||||
{
|
||||
if (AdditionalOptions)
|
||||
{
|
||||
FrameObj.Img_Path = AdditionalOptions(FrameObj.Img_Path);
|
||||
}
|
||||
SpriteObj->Init(FrameObj.Img_Path, FrameObj.Img_Index);
|
||||
}
|
||||
SpriteArr.push_back(SpriteObj);
|
||||
}
|
||||
|
||||
// 初始化完毕 如果是第一次初始化 而非重新构造 设置大小为第0帧大小否则天空 地板等依靠大小的初始化会有问题
|
||||
if (CurrentIndexT == 0)
|
||||
SetSize(SpriteArr[0]->GetSize());
|
||||
// 记录总帧数
|
||||
TotalFrameIndex = FrameArr.size();
|
||||
// TODO 染色
|
||||
}
|
||||
|
||||
void Animation::HandleEvents(SDL_Event *e)
|
||||
{
|
||||
}
|
||||
|
||||
void Animation::Update(float deltaTime)
|
||||
{
|
||||
Component::Update(deltaTime);
|
||||
// 可用性检查
|
||||
if (IsUsability)
|
||||
{
|
||||
int dt = (int)(deltaTime * 1000);
|
||||
// 累加当前帧时间
|
||||
CurrentIndexT += dt;
|
||||
// 插值模式判断
|
||||
InterpolationLogic();
|
||||
// 当前帧时间 超过 当前帧延迟就需要切换帧了
|
||||
if (CurrentIndexT >= NextFrameDelay)
|
||||
{
|
||||
CurrentIndexT = 0;
|
||||
// 如果当前帧小于总帧数就切换
|
||||
if (CurrentFrameIndex < (TotalFrameIndex - 1))
|
||||
{
|
||||
FlushFrame(CurrentFrameIndex + 1);
|
||||
}
|
||||
// 说明播放完毕了
|
||||
else
|
||||
{
|
||||
// 如果有循环
|
||||
if (AnimationFlag.count("LOOP"))
|
||||
{
|
||||
FlushFrame(0);
|
||||
}
|
||||
// 没有循环触发状态机回调
|
||||
else
|
||||
{
|
||||
// 将不再可用
|
||||
IsUsability = false;
|
||||
if (EndCallback)
|
||||
EndCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::Render(float deltaTime)
|
||||
{
|
||||
if (IsUsability)
|
||||
{
|
||||
if (CurrentFrame)
|
||||
{
|
||||
SDL_Point PosData = Pos;
|
||||
SDL_Point ParentPos = Parent->GetPos();
|
||||
if (Parent)
|
||||
{
|
||||
PosData.x += ParentPos.x;
|
||||
PosData.y += ParentPos.y;
|
||||
}
|
||||
CurrentFrame->RenderByAni(deltaTime, PosData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::OnAdded(Actor *actor)
|
||||
{
|
||||
Component::OnAdded(actor);
|
||||
FlushFrame(0);
|
||||
}
|
||||
|
||||
void Animation::Clear()
|
||||
{
|
||||
}
|
||||
|
||||
void Animation::FlushFrame(int Index)
|
||||
{
|
||||
// 同步当前帧
|
||||
CurrentFrameIndex = Index;
|
||||
// 当前帧更换为本帧
|
||||
CurrentFrame = SpriteArr[CurrentFrameIndex];
|
||||
// 如果是整体染色 则直接使用染色帧
|
||||
// if (DyeAllFlag) CurrentFrame = DyeFrameList[CurrentFrameIndex];
|
||||
|
||||
AniScriptParser::AniFrame FrameInfo = FrameArr[CurrentFrameIndex];
|
||||
// 设置坐标
|
||||
SetPos(FrameInfo.Img_Pos);
|
||||
// 设置下帧延迟
|
||||
NextFrameDelay = FrameInfo.Delay;
|
||||
|
||||
std::unordered_map<std::string, AniScriptParser::AniFlag> FlagBuf = FrameInfo.Flag;
|
||||
// 关键帧
|
||||
if (FlagBuf.count("SET_FLAG"))
|
||||
{
|
||||
if (ChangeFrameCallback)
|
||||
ChangeFrameCallback(std::get<int>(FlagBuf["SET_FLAG"]));
|
||||
}
|
||||
// 播放音效
|
||||
if (FlagBuf.count("PLAY_SOUND"))
|
||||
{
|
||||
// TODO 还没有做音效的播放
|
||||
}
|
||||
// 缩放
|
||||
if (FlagBuf.count("IMAGE_RATE"))
|
||||
{
|
||||
SDL_FPoint Rate = std::get<SDL_FPoint>(FlagBuf["IMAGE_RATE"]);
|
||||
SDL_Point Size = CurrentFrame->GetSize();
|
||||
CurrentFrame->SetSize(SDL_Point{int(Size.x * Rate.x), (int)(Size.y * Rate.y)});
|
||||
}
|
||||
// 线性减淡
|
||||
if (FlagBuf.count("GRAPHIC_EFFECT_LINEARDODGE"))
|
||||
{
|
||||
CurrentFrame->SetBlendMode(SDL_BLENDMODE_ADD);
|
||||
}
|
||||
// 旋转
|
||||
if (FlagBuf.count("IMAGE_ROTATE"))
|
||||
{
|
||||
CurrentFrame->SetAnchor(SDL_FPoint{0.5, 0.5});
|
||||
CurrentFrame->SetAngle(std::get<float>(FlagBuf["IMAGE_ROTATE"]));
|
||||
}
|
||||
// 染色
|
||||
// if (!DyeAllFlag)
|
||||
// 插值模式
|
||||
if (FlagBuf.count("INTERPOLATION"))
|
||||
{
|
||||
// 初始化插值数据
|
||||
if (InterpolationFlag.size() == 0)
|
||||
{
|
||||
// 旧插值数据
|
||||
InterpolationFlag.push_back(FrameArr[CurrentFrameIndex]);
|
||||
// 新插值数据
|
||||
InterpolationFlag.push_back(FrameArr[CurrentFrameIndex + 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (InterpolationFlag.size() > 0)
|
||||
{
|
||||
InterpolationFlag.clear();
|
||||
}
|
||||
}
|
||||
// 如果有描边
|
||||
if (IsOutline)
|
||||
{
|
||||
}
|
||||
// Ani的大小同步为精灵帧对象的大小
|
||||
SetSize(CurrentFrame->GetSize());
|
||||
// 裁切 //TODO
|
||||
}
|
||||
|
||||
void Animation::Reset()
|
||||
{
|
||||
IsUsability = true;
|
||||
CurrentIndexT = 0;
|
||||
FlushFrame(0);
|
||||
}
|
||||
|
||||
AniScriptParser::AniFrame Animation::GetCurrentFrameInfo()
|
||||
{
|
||||
return FrameArr[CurrentFrameIndex];
|
||||
}
|
||||
|
||||
void Animation::SetFrameIndex(int Index)
|
||||
{
|
||||
FlushFrame(Index);
|
||||
CurrentIndexT = 0;
|
||||
}
|
||||
|
||||
void Animation::InterpolationLogic()
|
||||
{
|
||||
if (InterpolationFlag.size() == 0)
|
||||
return;
|
||||
// 插值倍率
|
||||
float InterRate = Math::getUniformVelocity(0, 100, CurrentIndexT, NextFrameDelay) / 100.0f;
|
||||
AniScriptParser::AniFrame OldData = InterpolationFlag[0];
|
||||
AniScriptParser::AniFrame NewData = InterpolationFlag[1];
|
||||
// RGBA插值
|
||||
{
|
||||
std::vector<int> OldRgbaData = {255, 255, 255, 250};
|
||||
std::vector<int> NewRgbaData = {255, 255, 255, 250};
|
||||
if (OldData.Flag.count("RGBA"))
|
||||
OldRgbaData = std::get<std::vector<int>>(OldData.Flag["RGBA"]);
|
||||
if (NewData.Flag.count("RGBA"))
|
||||
NewRgbaData = std::get<std::vector<int>>(NewData.Flag["RGBA"]);
|
||||
std::vector<int> RgbaData = {
|
||||
(int)(OldRgbaData[0] + (NewRgbaData[0] - OldRgbaData[0]) * InterRate),
|
||||
(int)(OldRgbaData[1] + (NewRgbaData[1] - OldRgbaData[1]) * InterRate),
|
||||
(int)(OldRgbaData[2] + (NewRgbaData[2] - OldRgbaData[2]) * InterRate),
|
||||
(int)(OldRgbaData[3] + (NewRgbaData[3] - OldRgbaData[3]) * InterRate)};
|
||||
// TODO 染色 和 透明度还没弄
|
||||
}
|
||||
// 坐标
|
||||
{
|
||||
SDL_Point PosData = {
|
||||
(int)(OldData.Img_Pos.x + (NewData.Img_Pos.x - OldData.Img_Pos.x) * InterRate),
|
||||
(int)(OldData.Img_Pos.y + (NewData.Img_Pos.y - OldData.Img_Pos.y) * InterRate)};
|
||||
SetPos(PosData);
|
||||
}
|
||||
// 缩放
|
||||
{
|
||||
SDL_FPoint OldRateData = {1.0, 1.0};
|
||||
SDL_FPoint NewRateData = {1.0, 1.0};
|
||||
if (OldData.Flag.count("IMAGE_RATE"))
|
||||
{
|
||||
OldRateData = std::get<SDL_FPoint>(OldData.Flag["IMAGE_RATE"]);
|
||||
}
|
||||
if (NewData.Flag.count("IMAGE_RATE"))
|
||||
{
|
||||
NewRateData = std::get<SDL_FPoint>(NewData.Flag["IMAGE_RATE"]);
|
||||
}
|
||||
SDL_Point ScaleData = {
|
||||
(int)(CurrentFrame->GetSize().x * (OldRateData.x + (NewRateData.x - OldRateData.x) * InterRate)),
|
||||
(int)(CurrentFrame->GetSize().y * (OldRateData.y + (NewRateData.y - OldRateData.y) * InterRate))};
|
||||
SDL_Point Size = CurrentFrame->GetSize();
|
||||
CurrentFrame->SetSize(SDL_Point{int(Size.x * ScaleData.x), (int)(Size.y * ScaleData.y)});
|
||||
}
|
||||
// 旋转
|
||||
{
|
||||
float OldAngleData = 0.0;
|
||||
float NewAngleData = 0.0;
|
||||
if (OldData.Flag.count("IMAGE_ROTATE"))
|
||||
{
|
||||
OldAngleData = std::get<float>(OldData.Flag["IMAGE_ROTATE"]);
|
||||
}
|
||||
if (NewData.Flag.count("IMAGE_ROTATE"))
|
||||
{
|
||||
NewAngleData = std::get<float>(NewData.Flag["IMAGE_ROTATE"]);
|
||||
}
|
||||
CurrentFrame->SetAngle(OldAngleData + (NewAngleData - OldAngleData) * InterRate);
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::SetSize(SDL_Point size)
|
||||
{
|
||||
this->Size = size;
|
||||
}
|
||||
|
||||
void Animation::SetPos(SDL_Point pos)
|
||||
{
|
||||
this->Pos = pos;
|
||||
}
|
||||
|
||||
SDL_Point Animation::GetPos()
|
||||
{
|
||||
return this->Pos;
|
||||
}
|
||||
|
||||
SDL_Point Animation::GetSize()
|
||||
{
|
||||
return this->Size;
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
#pragma once
|
||||
#include "Tool/IntrusiveList.hpp"
|
||||
#include "EngineFrame/Component/Component.h"
|
||||
#include "EngineFrame/Component/Sprite.h"
|
||||
#include "Asset/AnimationStruct.h"
|
||||
#include <functional>
|
||||
|
||||
class Animation : public Component
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
Animation(/* args */);
|
||||
Animation(std::string AniPath);
|
||||
Animation(std::string AniPath, std::function<std::string(std::string)> AdditionalOptions);
|
||||
~Animation();
|
||||
|
||||
// 显式引入基类的Init方法,避免隐藏
|
||||
using Component::Init;
|
||||
|
||||
void Init(std::string AniPath);
|
||||
void HandleEvents(SDL_Event *e) override;
|
||||
void Update(float deltaTime) override;
|
||||
void Render(float deltaTime) override;
|
||||
void OnAdded(Actor *actor) override;
|
||||
void Clear() override;
|
||||
|
||||
public:
|
||||
void FlushFrame(int Index);
|
||||
void Reset();
|
||||
AniScriptParser::AniFrame GetCurrentFrameInfo();
|
||||
void SetFrameIndex(int Index);
|
||||
void InterpolationLogic();
|
||||
// TODO SetOutline
|
||||
// TODO SetDye
|
||||
// TODO SetCrop
|
||||
|
||||
public:
|
||||
// Ani是否可用
|
||||
bool IsUsability = true;
|
||||
// 当前帧数
|
||||
int CurrentFrameIndex = 0;
|
||||
// 总帧数
|
||||
int TotalFrameIndex = 0;
|
||||
// 当前帧时间
|
||||
int CurrentIndexT = 0;
|
||||
// 当前帧
|
||||
RefPtr<Sprite> CurrentFrame;
|
||||
// 下帧延迟
|
||||
int NextFrameDelay = 9999999;
|
||||
// 染色Flag
|
||||
bool DyeingFlag = false;
|
||||
// 插值模式
|
||||
std::vector<AniScriptParser::AniFrame> InterpolationFlag;
|
||||
// 关键帧回调
|
||||
std::function<void(int)> ChangeFrameCallback;
|
||||
// 结束回调
|
||||
std::function<void()> EndCallback;
|
||||
// Ani的标签
|
||||
std::unordered_map<std::string, AniScriptParser::AniFlag> AnimationFlag;
|
||||
// 帧对象数组
|
||||
std::vector<AniScriptParser::AniFrame> FrameArr;
|
||||
// 图片精灵帧对象
|
||||
std::vector<RefPtr<Sprite>> SpriteArr;
|
||||
// Ani类型
|
||||
std::string Type = "normal";
|
||||
// Ani路径
|
||||
std::string AniPath;
|
||||
// 是否描边
|
||||
bool IsOutline = false;
|
||||
// // 描边颜色
|
||||
// OutlineColor = null;
|
||||
// // 描边对象List
|
||||
// OutlineList = null;
|
||||
// // 当前描边对象
|
||||
// CurrentOutline = null;
|
||||
// // 染色颜色
|
||||
// DyeColor = null;
|
||||
// // 染色帧List
|
||||
// DyeFrameList = null;
|
||||
// // 整体染色
|
||||
// DyeAllFlag = false;
|
||||
// // 裁切数据
|
||||
// CropRect = null;
|
||||
|
||||
// 附加选项
|
||||
std::function<std::string(std::string)> AdditionalOptions;
|
||||
|
||||
SDL_Point Pos = {0, 0}; // 位置坐标
|
||||
SDL_Point Size = {0, 0}; // 大小
|
||||
int RenderZOrder = 0; // 渲染层级
|
||||
|
||||
public:
|
||||
void SetSize(SDL_Point size);
|
||||
void SetPos(SDL_Point pos);
|
||||
SDL_Point GetSize();
|
||||
SDL_Point GetPos();
|
||||
};
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "Component.h"
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
|
||||
Component::Component()
|
||||
{
|
||||
|
|
@ -31,3 +32,50 @@ void Component::SetName(std::string name)
|
|||
{
|
||||
m_Name = name;
|
||||
}
|
||||
|
||||
void Component::OnAdded(Actor *actor)
|
||||
{
|
||||
this->Parent = actor;
|
||||
}
|
||||
|
||||
int Component::GetRenderZOrder()
|
||||
{
|
||||
return this->RenderZOrder;
|
||||
}
|
||||
|
||||
void Component::ReorderComponents()
|
||||
{
|
||||
if (Parent)
|
||||
{
|
||||
RefPtr<Component> me = this;
|
||||
Parent->m_Components.Remove(me);
|
||||
RefPtr<Component> sibling = Parent->m_Components.GetLast();
|
||||
if (sibling && sibling->GetRenderZOrder() > RenderZOrder)
|
||||
{
|
||||
sibling = sibling->GetPrev();
|
||||
while (sibling)
|
||||
{
|
||||
if (sibling->GetRenderZOrder() <= RenderZOrder)
|
||||
break;
|
||||
sibling = sibling->GetPrev();
|
||||
}
|
||||
}
|
||||
if (sibling)
|
||||
{
|
||||
Parent->m_Components.InsertAfter(me, sibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
Parent->m_Components.PushFront(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Component::SetRenderZOrder(int zOrder)
|
||||
{
|
||||
if (zOrder != this->RenderZOrder)
|
||||
{
|
||||
this->RenderZOrder = zOrder;
|
||||
ReorderComponents();
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,16 @@
|
|||
class Actor;
|
||||
class Component : public RefObject, public TagGed, protected IntrusiveListValue<RefPtr<Component>>
|
||||
{
|
||||
friend IntrusiveList<RefPtr<Component>>;
|
||||
|
||||
public:
|
||||
using IntrusiveListValue<RefPtr<Component>>::GetNext;
|
||||
using IntrusiveListValue<RefPtr<Component>>::GetPrev;
|
||||
|
||||
private:
|
||||
/* data */
|
||||
std::string m_Name;
|
||||
|
||||
public:
|
||||
Component(/* args */);
|
||||
~Component();
|
||||
|
|
@ -21,11 +28,16 @@ public:
|
|||
virtual void Render(float deltaTime);
|
||||
virtual void Clear();
|
||||
|
||||
using IntrusiveListValue<RefPtr<Component>>::GetNext;
|
||||
using IntrusiveListValue<RefPtr<Component>>::GetPrev;
|
||||
|
||||
void SetName(std::string name);
|
||||
virtual void OnAdded(Actor *actor);
|
||||
// 设置渲染层级
|
||||
void SetRenderZOrder(int zOrder);
|
||||
// 获取渲染层级
|
||||
int GetRenderZOrder();
|
||||
// 重新排列组件
|
||||
void ReorderComponents();
|
||||
|
||||
public:
|
||||
Actor *Parent; // 指向父对象的指针,用于访问父对象
|
||||
Actor *Parent = nullptr; // 指向父对象的指针,用于访问父对象
|
||||
int RenderZOrder; // 渲染层级
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "Sprite.h"
|
||||
#include "EngineCore/Game.h"
|
||||
#include "Text.h"
|
||||
#include "Render/Texture.h"
|
||||
Sprite::Sprite()
|
||||
{
|
||||
}
|
||||
|
|
@ -12,37 +13,18 @@ Sprite::Sprite(std::string imgPath, int Index)
|
|||
|
||||
Sprite::~Sprite()
|
||||
{
|
||||
SDL_DestroyTexture(m_texture);
|
||||
}
|
||||
|
||||
void Sprite::Init(std::string imgPath, int Index)
|
||||
{
|
||||
Asset_ImagePack::IMG *Info = Asset_ImagePack::GetInstance().GetIMG(imgPath);
|
||||
Asset_ImagePack::ImgInfo &Buf = Info->lp_lplist[Index];
|
||||
// 标记该组件需要渲染和更新
|
||||
addTag(Tag::RENDER);
|
||||
addTag(Tag::UPDATE);
|
||||
|
||||
m_texture = SDL_CreateTexture(
|
||||
Game::GetInstance().GetRenderer(),
|
||||
SDL_PIXELFORMAT_ARGB8888, // 匹配RGBA数据格式
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
Buf.Width, Buf.Height);
|
||||
if (!m_texture)
|
||||
{
|
||||
SDL_Log("纹理创建失败: %s", SDL_GetError());
|
||||
}
|
||||
int pitch = Buf.Width * 4;
|
||||
SDL_UpdateTexture(m_texture, NULL, Buf.PNGdata, pitch);
|
||||
|
||||
if (Info != NULL)
|
||||
{
|
||||
// SDL_Log("第%d张图片的宽度为%d,高度为%d\n", Index, Buf.Width, Buf.Height);
|
||||
}
|
||||
TextureSize.x = Buf.Width;
|
||||
TextureSize.y = Buf.Height;
|
||||
Size.x = Buf.Width;
|
||||
Size.y = Buf.Height;
|
||||
m_texture = new Texture(imgPath, Index);
|
||||
}
|
||||
|
||||
SDL_Texture *Sprite::GetTexture()
|
||||
RefPtr<Texture> Sprite::GetTexture()
|
||||
{
|
||||
return m_texture;
|
||||
}
|
||||
|
|
@ -53,6 +35,14 @@ void Sprite::HandleEvents(SDL_Event *e)
|
|||
|
||||
void Sprite::Update(float deltaTime)
|
||||
{
|
||||
// // 检测是否超出屏幕
|
||||
// bool isFullyOutOfScreen =
|
||||
// (Pos.x + Size.x <= 0) // 完全在屏幕左侧外
|
||||
// || (Pos.x >= 1280) // 完全在屏幕右侧外
|
||||
// || (Pos.y + Size.y <= 0) // 完全在屏幕上侧外
|
||||
// || (Pos.y >= 720); // 完全在下侧外
|
||||
|
||||
// isRenderScreen = !isFullyOutOfScreen;
|
||||
}
|
||||
|
||||
void Sprite::Render(float deltaTime)
|
||||
|
|
@ -62,12 +52,30 @@ void Sprite::Render(float deltaTime)
|
|||
return;
|
||||
SDL_Rect dstrect = {Pos.x, Pos.y, Size.x, Size.y};
|
||||
|
||||
if (isRenderScreen)
|
||||
{
|
||||
if (Angle != 0 || flip != SDL_FLIP_NONE)
|
||||
{
|
||||
SDL_RenderCopyEx(renderer, m_texture->GetTexture(), NULL, &dstrect, Angle, &Anchor, flip);
|
||||
}
|
||||
else
|
||||
SDL_RenderCopy(renderer, m_texture->GetTexture(), NULL, &dstrect);
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite::RenderByAni(float deltaTime, SDL_Point pos)
|
||||
{
|
||||
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
|
||||
if (!m_texture)
|
||||
return;
|
||||
SDL_Rect dstrect = {Pos.x + pos.x, Pos.y + pos.y, Size.x, Size.y};
|
||||
|
||||
if (Angle != 0 || flip != SDL_FLIP_NONE)
|
||||
{
|
||||
SDL_RenderCopyEx(renderer, m_texture, NULL, &dstrect, Angle, &Anchor, flip);
|
||||
SDL_RenderCopyEx(renderer, m_texture->GetTexture(), NULL, &dstrect, Angle, &Anchor, flip);
|
||||
}
|
||||
else
|
||||
SDL_RenderCopy(renderer, m_texture, NULL, &dstrect);
|
||||
SDL_RenderCopy(renderer, m_texture->GetTexture(), NULL, &dstrect);
|
||||
}
|
||||
|
||||
void Sprite::Clear()
|
||||
|
|
@ -81,7 +89,7 @@ void Sprite::SetPos(SDL_Point pos)
|
|||
|
||||
void Sprite::SetBlendMode(SDL_BlendMode blendMode)
|
||||
{
|
||||
SDL_SetTextureBlendMode(m_texture, blendMode);
|
||||
m_texture->SetBlendMode(blendMode);
|
||||
}
|
||||
|
||||
void Sprite::SetAngle(float angle)
|
||||
|
|
@ -95,17 +103,24 @@ void Sprite::SetAnchor(SDL_FPoint anchor)
|
|||
Anchor.y = Size.y * anchor.y;
|
||||
}
|
||||
|
||||
void Sprite::SetSize(SDL_Point size)
|
||||
{
|
||||
Size = size;
|
||||
}
|
||||
|
||||
SDL_Point Sprite::GetSize()
|
||||
{
|
||||
return Size;
|
||||
}
|
||||
|
||||
SDL_Point Sprite::GetPos()
|
||||
{
|
||||
return Pos;
|
||||
}
|
||||
|
||||
|
||||
SDL_BlendMode Sprite::GetBlendMode()
|
||||
{
|
||||
SDL_BlendMode blendMode;
|
||||
SDL_GetTextureBlendMode(m_texture, &blendMode);
|
||||
return blendMode;
|
||||
return m_texture->GetBlendMode();
|
||||
}
|
||||
|
||||
float Sprite::GetAngle()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class Sprite : public Component
|
|||
{
|
||||
private:
|
||||
/* data */
|
||||
SDL_Texture *m_texture = nullptr; // 纹理指针,用于存储精灵的纹理资源
|
||||
RefPtr<Texture> m_texture = nullptr;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
|
@ -52,6 +52,11 @@ public:
|
|||
* @param deltaTime 时间增量
|
||||
*/
|
||||
void Render(float deltaTime) override;
|
||||
/**
|
||||
* @brief 渲染组件
|
||||
* @param deltaTime 时间增量
|
||||
*/
|
||||
void RenderByAni(float deltaTime, SDL_Point pos);
|
||||
/**
|
||||
* @brief 清理组件资源
|
||||
*/
|
||||
|
|
@ -61,12 +66,9 @@ public:
|
|||
* @brief 获取纹理
|
||||
* @return SDL_Texture* 纹理指针
|
||||
*/
|
||||
SDL_Texture *GetTexture();
|
||||
RefPtr<Texture> GetTexture();
|
||||
|
||||
public:
|
||||
// 组件标签
|
||||
Tag m_tag = Tag::RENDER | Tag::UPDATE; // 标记该组件需要渲染和更新
|
||||
|
||||
SDL_Point Pos = {0, 0}; // 位置坐标
|
||||
SDL_Point TextureSize = {0, 0}; // 纹理大小
|
||||
SDL_Point Size = {0, 0}; // 大小
|
||||
|
|
@ -74,6 +76,9 @@ public:
|
|||
float Angle = 0.0f; // 旋转角度
|
||||
SDL_RendererFlip flip = SDL_FLIP_NONE; // 翻转
|
||||
|
||||
// 是否在需要渲染的屏幕上
|
||||
bool isRenderScreen = true;
|
||||
|
||||
public:
|
||||
// 设置坐标
|
||||
void SetPos(SDL_Point pos);
|
||||
|
|
@ -81,8 +86,10 @@ public:
|
|||
void SetBlendMode(SDL_BlendMode blendMode);
|
||||
// 设置旋转角度
|
||||
void SetAngle(float angle);
|
||||
//设置中心点
|
||||
// 设置中心点
|
||||
void SetAnchor(SDL_FPoint anchor);
|
||||
// 设置大小
|
||||
void SetSize(SDL_Point size);
|
||||
|
||||
// 获取坐标
|
||||
SDL_Point GetPos();
|
||||
|
|
@ -92,4 +99,6 @@ public:
|
|||
float GetAngle();
|
||||
// 获取中心点
|
||||
SDL_FPoint GetAnchor();
|
||||
// 获取大小
|
||||
SDL_Point GetSize();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ Text::~Text()
|
|||
|
||||
void Text::Init(std::string Str, TTF_Font *font, SDL_Color color)
|
||||
{
|
||||
// 标记该组件需要渲染和更新
|
||||
addTag(Tag::RENDER);
|
||||
addTag(Tag::UPDATE);
|
||||
|
||||
// TTF_SetFontOutline(font, 1);
|
||||
// 先渲染为表面
|
||||
SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, Str.c_str(), color);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
#include "Texture.h"
|
||||
#include "EngineCore/Asset_ImagePack.h"
|
||||
#include "EngineCore/Game.h"
|
||||
|
||||
Texture::Texture()
|
||||
{
|
||||
}
|
||||
|
||||
Texture::Texture(std::string imgPath, int Index)
|
||||
{
|
||||
Init(imgPath, Index);
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
SDL_DestroyTexture(m_texture);
|
||||
}
|
||||
|
||||
void Texture::Init(std::string imgPath, int Index)
|
||||
{
|
||||
Asset_ImagePack::IMG *Info = Asset_ImagePack::GetInstance().GetIMG(imgPath);
|
||||
if (Info->lpImgName == "sprite/interface/base.img")
|
||||
return;
|
||||
Asset_ImagePack::ImgInfo &Buf = Info->lp_lplist[Index];
|
||||
|
||||
m_texture = SDL_CreateTexture(
|
||||
Game::GetInstance().GetRenderer(),
|
||||
SDL_PIXELFORMAT_ARGB8888, // 匹配RGBA数据格式
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
Buf.Width, Buf.Height);
|
||||
if (!m_texture)
|
||||
{
|
||||
SDL_Log("纹理创建失败: %s", SDL_GetError());
|
||||
}
|
||||
int pitch = Buf.Width * 4;
|
||||
SDL_UpdateTexture(m_texture, NULL, Buf.PNGdata, pitch);
|
||||
SDL_SetTextureBlendMode(m_texture, SDL_BLENDMODE_BLEND);
|
||||
|
||||
this->TexturePos.x = Buf.Xpos;
|
||||
this->TexturePos.y = Buf.Ypos;
|
||||
this->TextureSize.x = Buf.Width;
|
||||
this->TextureSize.y = Buf.Height;
|
||||
this->TextureFramepos.x = Buf.FrameXpos;
|
||||
this->TextureFramepos.y = Buf.FrameYpos;
|
||||
}
|
||||
|
||||
SDL_Texture *Texture::GetTexture()
|
||||
{
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
void Texture::SetBlendMode(SDL_BlendMode blendMode)
|
||||
{
|
||||
SDL_SetTextureBlendMode(m_texture, blendMode);
|
||||
}
|
||||
|
||||
SDL_BlendMode Texture::GetBlendMode()
|
||||
{
|
||||
SDL_BlendMode blendMode;
|
||||
SDL_GetTextureBlendMode(m_texture, &blendMode);
|
||||
return blendMode;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
#include <string>
|
||||
|
||||
class Texture : public RefObject
|
||||
{
|
||||
private:
|
||||
SDL_Texture *m_texture = nullptr;
|
||||
|
||||
public:
|
||||
SDL_Point TextureSize = {0, 0}; // 纹理大小
|
||||
SDL_Point TexturePos = {0, 0}; // 纹理位置
|
||||
SDL_Point TextureFramepos = {0, 0}; // 帧域宽高
|
||||
|
||||
public:
|
||||
Texture(/* args */);
|
||||
Texture(std::string imgPath, int Index);
|
||||
~Texture();
|
||||
|
||||
public:
|
||||
void Init(std::string imgPath, int Index);
|
||||
|
||||
void SetBlendMode(SDL_BlendMode blendMode);
|
||||
// 获取混合模式
|
||||
SDL_BlendMode GetBlendMode();
|
||||
SDL_Texture *GetTexture(); // 获取纹理
|
||||
};
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "EngineFrame/Scene/Scene.h"
|
||||
#include "Scene.h"
|
||||
#include "EngineFrame/Scene/Scene.h"
|
||||
#include <algorithm>
|
||||
|
||||
void Scene::Enter()
|
||||
{
|
||||
|
|
@ -7,7 +8,6 @@ void Scene::Enter()
|
|||
|
||||
void Scene::Exit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::AddChild(RefPtr<Actor> actor)
|
||||
|
|
@ -39,4 +39,3 @@ void Scene::Render(float deltaTime)
|
|||
void Scene::HandleEvents(SDL_Event *e)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public:
|
|||
|
||||
public:
|
||||
void AddChild(RefPtr<Actor> actor);
|
||||
|
||||
private:
|
||||
IntrusiveList<RefPtr<Actor>> m_Actors;
|
||||
};
|
||||
|
|
@ -237,7 +237,6 @@ public:
|
|||
|
||||
inline reference operator*() const
|
||||
{
|
||||
KGE_ASSERT(base_ && !is_end_);
|
||||
return const_cast<reference>(base_);
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +247,6 @@ public:
|
|||
|
||||
inline Iterator &operator++()
|
||||
{
|
||||
KGE_ASSERT(base_ && !is_end_);
|
||||
value_type next = base_->GetNext();
|
||||
if (next)
|
||||
base_ = next;
|
||||
|
|
@ -266,7 +264,6 @@ public:
|
|||
|
||||
inline Iterator &operator--()
|
||||
{
|
||||
KGE_ASSERT(base_);
|
||||
if (is_end_)
|
||||
is_end_ = false;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
class Math
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
Math(/* args */) = default;
|
||||
~Math() = default;
|
||||
|
||||
public:
|
||||
static void InitRandomSeed()
|
||||
{
|
||||
static bool seeded = false;
|
||||
if (!seeded)
|
||||
{
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
seeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 获取X轴方向(0:目标在左侧,1:目标在右侧)
|
||||
static int getDirectionToTargetX(float objX, float x)
|
||||
{
|
||||
return (objX > x) ? 0 : 1;
|
||||
}
|
||||
|
||||
// 2. 生成[Min, Max]范围内的随机整数(左闭右闭)
|
||||
static int Rand(int Min, int Max)
|
||||
{
|
||||
InitRandomSeed(); // 确保随机数种子已初始化
|
||||
if (Min > Max)
|
||||
{
|
||||
throw std::invalid_argument("Rand: Min must be less than or equal to Max");
|
||||
}
|
||||
// 计算随机数范围:(Max - Min + 1)个可能值
|
||||
int range = Max - Min + 1;
|
||||
// rand()返回[0, RAND_MAX],通过取模和偏移实现范围映射
|
||||
return Min + (rand() % range);
|
||||
}
|
||||
|
||||
// 3. 从数组中随机获取一个元素(支持任意可索引容器)
|
||||
template <typename T>
|
||||
static T GetRandomElementFromArray(const std::vector<T> &arr)
|
||||
{
|
||||
if (arr.empty())
|
||||
{
|
||||
throw std::invalid_argument("GetRandomElementFromArray: Array is empty");
|
||||
}
|
||||
int randomIndex = Rand(0, static_cast<int>(arr.size()) - 1);
|
||||
return arr[randomIndex];
|
||||
}
|
||||
|
||||
// 5. 根据方向计算偏移后的X坐标
|
||||
static float GetDistancePos(float startX, int direction, float offsetX)
|
||||
{
|
||||
return (direction == 0) ? (startX - offsetX) : (startX + offsetX);
|
||||
}
|
||||
|
||||
// 6. 通过两点坐标计算旋转角度(预留实现,需根据具体需求补充)
|
||||
static float getRorateAngleByCurrentPos(float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
{
|
||||
// 示例实现:计算X-Z平面内的角度(可根据需求调整为3D角度)
|
||||
float dx = x2 - x1;
|
||||
float dz = z2 - z1;
|
||||
// atan2(dz, dx):返回与X轴正方向的夹角(弧度),范围[-π, π]
|
||||
return std::atan2(dz, dx);
|
||||
}
|
||||
|
||||
// 8. 标准抛物线计算(y = a(x - c/2)² + b,开口向下)
|
||||
static float sq_Parabola(float x, float b, float c)
|
||||
{
|
||||
if (c == 0)
|
||||
{
|
||||
throw std::invalid_argument("sq_Parabola: c cannot be zero");
|
||||
}
|
||||
// 计算抛物线系数a(确保顶点在x=c/2,y=b)
|
||||
float a = (-4.0f * b) / (c * c);
|
||||
return a * (x - c / 2.0f) * (x - c / 2.0f) + b;
|
||||
}
|
||||
|
||||
// 9. 计算2D平面两点距离(Y轴权重0.29,用于透视校正)
|
||||
static float Get2D_Distance(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
float offsetX = x1 - x2;
|
||||
float offsetY = (y1 - y2) * 0.29f;
|
||||
// 勾股定理计算距离
|
||||
return std::sqrt(offsetX * offsetX + offsetY * offsetY);
|
||||
}
|
||||
|
||||
// 10. 判断角度是否在[startA, endA]形成的锐角范围内(角度单位:度)
|
||||
static bool CheckAngleIsInArea(float judge, float startA, float endA)
|
||||
{
|
||||
// 步骤1:将角度标准化到[0, 360)范围
|
||||
auto normalizeAngle = [](float angle)
|
||||
{
|
||||
angle = std::fmod(angle, 360.0f);
|
||||
return (angle < 0) ? (angle + 360.0f) : angle;
|
||||
};
|
||||
|
||||
startA = normalizeAngle(startA);
|
||||
endA = normalizeAngle(endA);
|
||||
judge = normalizeAngle(judge);
|
||||
|
||||
// 特殊情况:范围跨0度(如startA=350°,endA=10°)
|
||||
if (startA > 270.0f && startA < 360.0f && endA > 0.0f && endA < 90.0f)
|
||||
{
|
||||
return (judge >= startA && judge <= 360.0f) || (judge >= 0.0f && judge <= endA);
|
||||
}
|
||||
// 普通情况:范围不跨0度
|
||||
else
|
||||
{
|
||||
// 处理startA > endA的正常范围(如startA=30°,endA=60°)
|
||||
if (startA > endA)
|
||||
{
|
||||
std::swap(startA, endA);
|
||||
}
|
||||
return (judge >= startA && judge <= endA);
|
||||
}
|
||||
}
|
||||
|
||||
// 11. 弧度转角度
|
||||
static float toDegree(float radian)
|
||||
{
|
||||
return radian * 57.2957795f; // 180/π ≈ 57.2957795
|
||||
}
|
||||
|
||||
// 12. 角度转弧度
|
||||
static float toRadian(float degree)
|
||||
{
|
||||
return degree * 0.0174532925f; // π/180 ≈ 0.0174532925
|
||||
}
|
||||
|
||||
// 13. 判断点是否在立方体内(立方体由对角点定义)
|
||||
static bool pointIsInCubeArea(float px, float py, float pz,
|
||||
float startX, float startY, float startZ,
|
||||
float endX, float endY, float endZ)
|
||||
{
|
||||
// 计算立方体中心点和半边长
|
||||
float cubeCenterX = (startX + endX) / 2.0f;
|
||||
float cubeXLen = std::fabs(startX - endX) / 2.0f;
|
||||
|
||||
float cubeCenterY = (startY + endY) / 2.0f;
|
||||
float cubeYLen = std::fabs(startY - endY) / 2.0f;
|
||||
|
||||
float cubeCenterZ = (startZ + endZ) / 2.0f;
|
||||
float cubeZLen = std::fabs(startZ - endZ) / 2.0f;
|
||||
|
||||
// 点到各轴中心点的距离 ≤ 半边长 → 在立方体内
|
||||
return (std::fabs(px - cubeCenterX) <= cubeXLen + 1e-6f) &&
|
||||
(std::fabs(py - cubeCenterY) <= cubeYLen + 1e-6f) &&
|
||||
(std::fabs(pz - cubeCenterZ) <= cubeZLen + 1e-6f);
|
||||
}
|
||||
|
||||
// 14. 立方体与立方体碰撞检测(基于顶点和中心点判断)
|
||||
static bool CubeAndCubeCollection(float c1StartX, float c1StartY, float c1StartZ,
|
||||
float c1EndX, float c1EndY, float c1EndZ,
|
||||
float c2StartX, float c2StartY, float c2StartZ,
|
||||
float c2EndX, float c2EndY, float c2EndZ)
|
||||
{
|
||||
// 优化说明:原Squirrel代码判断过多冗余点,此处保留核心顶点+中心点判断
|
||||
const std::vector<std::tuple<float, float, float>> c1Points = {
|
||||
// 立方体1的8个顶点
|
||||
{c1StartX, c1StartY, c1StartZ},
|
||||
{c1EndX, c1StartY, c1StartZ},
|
||||
{c1StartX, c1EndY, c1StartZ},
|
||||
{c1EndX, c1EndY, c1StartZ},
|
||||
{c1StartX, c1StartY, c1EndZ},
|
||||
{c1EndX, c1StartY, c1EndZ},
|
||||
{c1StartX, c1EndY, c1EndZ},
|
||||
{c1EndX, c1EndY, c1EndZ},
|
||||
// 立方体1的中心点
|
||||
{(c1StartX + c1EndX) / 2, (c1StartY + c1EndY) / 2, (c1StartZ + c1EndZ) / 2}};
|
||||
|
||||
const std::vector<std::tuple<float, float, float>> c2Points = {
|
||||
// 立方体2的8个顶点
|
||||
{c2StartX, c2StartY, c2StartZ},
|
||||
{c2EndX, c2StartY, c2StartZ},
|
||||
{c2StartX, c2EndY, c2StartZ},
|
||||
{c2EndX, c2EndY, c2StartZ},
|
||||
{c2StartX, c2StartY, c2EndZ},
|
||||
{c2EndX, c2StartY, c2EndZ},
|
||||
{c2StartX, c2EndY, c2EndZ},
|
||||
{c2EndX, c2EndY, c2EndZ},
|
||||
// 立方体2的中心点
|
||||
{(c2StartX + c2EndX) / 2, (c2StartY + c2EndY) / 2, (c2StartZ + c2EndZ) / 2}};
|
||||
|
||||
// 检查立方体1的点是否在立方体2内
|
||||
for (const auto &[x, y, z] : c1Points)
|
||||
{
|
||||
if (pointIsInCubeArea(x, y, z, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查立方体2的点是否在立方体1内
|
||||
for (const auto &[x, y, z] : c2Points)
|
||||
{
|
||||
if (pointIsInCubeArea(x, y, z, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 15. 计算三角形面积(叉乘法,避免开方,效率更高)
|
||||
static float get3PointArea(float x1, float y1, float x2, float y2, float x3, float y3)
|
||||
{
|
||||
// 面积公式:0.5 * |x1(y2-y3) + x2(y3-y1) + x3(y1-y2)|
|
||||
return 0.5f * std::fabs(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2));
|
||||
}
|
||||
|
||||
// 16. 计算四边形面积(拆分为两个三角形面积之和)
|
||||
static float get4PointArea(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
|
||||
{
|
||||
// 四边形拆分为:(x1,y1)-(x2,y2)-(x3,y3) 和 (x2,y2)-(x3,y3)-(x4,y4)
|
||||
float area1 = get3PointArea(x1, y1, x2, y2, x3, y3);
|
||||
float area2 = get3PointArea(x2, y2, x3, y3, x4, y4);
|
||||
return area1 + area2;
|
||||
}
|
||||
|
||||
// 17. 判断点是否在四边形内(面积比较法,要求四边形顶点按顺序排列)
|
||||
static bool pointIsIn4PointArea(float px, float py,
|
||||
float x1, float y1, float x2, float y2,
|
||||
float x3, float y3, float x4, float y4)
|
||||
{
|
||||
const float eps = 10.0f; // 容差(原Squirrel代码定义为10.0)
|
||||
float totalArea = get4PointArea(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
// 点与四边形各边组成的4个三角形面积之和
|
||||
float sumArea = get3PointArea(x1, y1, x2, y2, px, py) +
|
||||
get3PointArea(x2, y2, x3, y3, px, py) +
|
||||
get3PointArea(x3, y3, x4, y4, px, py) +
|
||||
get3PointArea(x4, y4, x1, y1, px, py);
|
||||
|
||||
// 面积差在容差范围内 → 点在四边形内
|
||||
return std::fabs(totalArea - sumArea) < eps;
|
||||
}
|
||||
|
||||
// 18. 判断点是否在矩形内(矩形由坐标数组定义,格式:[x, y, width, height])
|
||||
static bool PointIsInSquare(float x1, float y1, const std::vector<float> &SquareArr)
|
||||
{
|
||||
if (SquareArr.size() != 4)
|
||||
{
|
||||
throw std::invalid_argument("PointIsInSquare: SquareArr must have 4 elements (x, y, width, height)");
|
||||
}
|
||||
float sqX = SquareArr[0];
|
||||
float sqY = SquareArr[1];
|
||||
float sqWidth = SquareArr[2];
|
||||
float sqHeight = SquareArr[3];
|
||||
|
||||
// 点的X在[sqX, sqX+width],Y在[sqY, sqY+height] → 在矩形内
|
||||
return (x1 >= sqX - 1e-6f) && (x1 <= sqX + sqWidth + 1e-6f) &&
|
||||
(y1 >= sqY - 1e-6f) && (y1 <= sqY + sqHeight + 1e-6f);
|
||||
}
|
||||
|
||||
static float getUniformVelocity(float sv, float ev, float currentRate, float maxRate)
|
||||
{
|
||||
// 避免除零错误
|
||||
if (maxRate <= 0.0f)
|
||||
{
|
||||
throw std::invalid_argument("maxRate must be greater than 0");
|
||||
}
|
||||
|
||||
// 计算当前进度比例(0.0到1.0之间)
|
||||
float rate = currentRate / maxRate;
|
||||
// 限制比例在[0, 1]范围内,避免超出边界
|
||||
rate = std::clamp(rate, 0.0f, 1.0f);
|
||||
|
||||
// 计算变化量并返回当前值
|
||||
float varyValue = ev - sv;
|
||||
return sv + varyValue * rate;
|
||||
}
|
||||
};
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include <cstdint>
|
||||
enum class Tag
|
||||
{
|
||||
NONE = 0, // 无标签
|
||||
NONE = 0, // 无标签
|
||||
UPDATE = 1 << 0, // 更新标签
|
||||
RENDER = 1 << 1, // 渲染标签
|
||||
};
|
||||
|
|
@ -31,13 +31,15 @@ public:
|
|||
// 添加标签
|
||||
void addTag(Tag tag)
|
||||
{
|
||||
m_tags |= static_cast<uint64_t>(tag);
|
||||
if (!hasTag(tag))
|
||||
m_tags |= static_cast<uint64_t>(tag);
|
||||
}
|
||||
|
||||
// 移除标签
|
||||
void removeTag(Tag tag)
|
||||
{
|
||||
m_tags &= ~static_cast<uint64_t>(tag);
|
||||
if (hasTag(tag))
|
||||
m_tags &= ~static_cast<uint64_t>(tag);
|
||||
}
|
||||
|
||||
// 判断是否包含指定标签
|
||||
|
|
@ -58,4 +60,3 @@ public:
|
|||
m_tags = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Tool/Tool_String.h"
|
||||
std::string Tool_toLowerCase(const std::string &str)
|
||||
{
|
||||
std::string result = str;
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
|
||||
std::string Tool_toLowerCase(const std::string &str);
|
||||
|
|
@ -46,6 +46,7 @@ void RunSetup()
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
socketInitializeDefault();
|
||||
nxlinkStdio(); // 启用nxlink调试输出
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT); // 初始化libcurl
|
||||
|
|
@ -67,7 +68,7 @@ int main(int argc, char *argv[])
|
|||
// 初始化Squirrel脚本系统
|
||||
SquirrelEx::GetInstance().Init();
|
||||
// 请求脚本
|
||||
SquirrelEx::GetInstance().RequestNetScript(PC_IP, PC_SCRIPT_PORT);
|
||||
// SquirrelEx::GetInstance().RequestNetScript(PC_IP, PC_SCRIPT_PORT);
|
||||
|
||||
// 初始化游戏引擎
|
||||
Game &game = Game::GetInstance();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,355 @@
|
|||
#include "Asset/AnimationStruct.h"
|
||||
|
||||
namespace AniScriptParser
|
||||
{
|
||||
|
||||
std::string Get_Ani_Flag(int data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
return "LOOP";
|
||||
case 1:
|
||||
return "SHADOW";
|
||||
case 3:
|
||||
return "COORD";
|
||||
case 7:
|
||||
return "IMAGE_RATE";
|
||||
case 8:
|
||||
return "IMAGE_ROTATE";
|
||||
case 9:
|
||||
return "RGBA";
|
||||
case 10:
|
||||
return "INTERPOLATION";
|
||||
case 11:
|
||||
return "GRAPHIC_EFFECT";
|
||||
case 12:
|
||||
return "DELAY";
|
||||
case 13:
|
||||
return "DAMAGE_TYPE";
|
||||
case 14:
|
||||
return "DAMAGE_BOX";
|
||||
case 15:
|
||||
return "ATTACK_BOX";
|
||||
case 16:
|
||||
return "PLAY_SOUND";
|
||||
case 17:
|
||||
return "PRELOAD";
|
||||
case 18:
|
||||
return "SPECTRUM";
|
||||
case 23:
|
||||
return "SET_FLAG";
|
||||
case 24:
|
||||
return "FLIP_TYPE";
|
||||
case 25:
|
||||
return "LOOP_START";
|
||||
case 26:
|
||||
return "LOOP_END";
|
||||
case 27:
|
||||
return "CLIP";
|
||||
case 28:
|
||||
return "OPERATION";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string Get_Ani_Effect_Type(int data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
return "NONE";
|
||||
case 1:
|
||||
return "DODGE";
|
||||
case 2:
|
||||
return "LINEARDODGE";
|
||||
case 3:
|
||||
return "DARK";
|
||||
case 4:
|
||||
return "XOR";
|
||||
case 5:
|
||||
return "MONOCHROME";
|
||||
case 6:
|
||||
return "SPACEDISTORT";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
std::string Get_Ani_Flip_Type(int data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 1:
|
||||
return "HORIZON";
|
||||
case 2:
|
||||
return "VERTICAL";
|
||||
case 3:
|
||||
return "ALL";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
std::string Get_Ani_Damage_Type(int data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
return "NORMAL";
|
||||
case 1:
|
||||
return "SUPERARMOR";
|
||||
case 2:
|
||||
return "UNBREAKABLE";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
/////////以下是读取逻辑
|
||||
AniInfo StructAniInfo(Blob blob)
|
||||
{
|
||||
AniInfo Info;
|
||||
int Frame_Max = blob.getUShort();
|
||||
int Img_Count = blob.getUShort();
|
||||
|
||||
// Img的路径读取 存入数组
|
||||
for (int i = 0; i < Img_Count; i++)
|
||||
{
|
||||
int Buf = blob.getInt();
|
||||
std::string ImgPath = "sprite/" + blob.getString(Buf);
|
||||
Info.Img_List.push_back(ImgPath);
|
||||
}
|
||||
|
||||
// Ani头部标签数量
|
||||
int Ani_H_Item_Count = blob.getUShort();
|
||||
// 处理标签
|
||||
for (int i = 0; i < Ani_H_Item_Count; i++)
|
||||
{
|
||||
int Type = blob.getUShort();
|
||||
switch (Type)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
std::string Key = AniScriptParser::Get_Ani_Flag(Type);
|
||||
int Value = blob.getByte();
|
||||
Info.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
case 28:
|
||||
{
|
||||
std::string Key = AniScriptParser::Get_Ani_Flag(Type);
|
||||
int Value = blob.getUShort();
|
||||
Info.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
{
|
||||
blob.getByte();
|
||||
blob.getInt();
|
||||
blob.getInt();
|
||||
blob.getInt();
|
||||
blob.get256();
|
||||
blob.get256();
|
||||
blob.get256();
|
||||
blob.get256();
|
||||
blob.getUShort();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 读取每一个Img
|
||||
for (int i = 0; i < Frame_Max; i++)
|
||||
{
|
||||
AniFrame FrameObject;
|
||||
|
||||
// 碰撞框项目数量
|
||||
int Ani_Box_Item_Count = blob.getUShort();
|
||||
for (int j = 0; j < Ani_Box_Item_Count; j++)
|
||||
{
|
||||
int Box_Type = blob.getUShort();
|
||||
std::vector<int> D_Box_b;
|
||||
for (int k = 0; k < 6; k++)
|
||||
{
|
||||
D_Box_b.push_back(blob.getInt());
|
||||
}
|
||||
if (Box_Type == 15)
|
||||
FrameObject.AttackBox.push_back(D_Box_b);
|
||||
else
|
||||
FrameObject.DamageBox.push_back(D_Box_b);
|
||||
}
|
||||
|
||||
// 调用的第几个Img
|
||||
int Index_Buf = blob.getShort();
|
||||
if (Index_Buf != -1)
|
||||
{
|
||||
FrameObject.Img_Path = Tool_toLowerCase(Info.Img_List[Index_Buf]);
|
||||
FrameObject.Img_Index = blob.getUShort();
|
||||
}
|
||||
else
|
||||
{
|
||||
FrameObject.Img_Path = "";
|
||||
FrameObject.Img_Index = 0;
|
||||
}
|
||||
|
||||
// 坐标
|
||||
FrameObject.Img_Pos = SDL_Point{blob.getInt(), blob.getInt()};
|
||||
|
||||
// Img中的项目数量
|
||||
int Img_Flag_Count = blob.getUShort();
|
||||
for (int j = 0; j < Img_Flag_Count; j++)
|
||||
{
|
||||
int Img_Flag_Type = blob.getUShort();
|
||||
std::string Key;
|
||||
int Value;
|
||||
switch (Img_Flag_Type)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 10:
|
||||
{
|
||||
Key = AniScriptParser::Get_Ani_Flag(Img_Flag_Type);
|
||||
Value = blob.getByte();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
Key = "COORD";
|
||||
Value = blob.getUShort();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 17:
|
||||
{
|
||||
Key = "PRELOAD";
|
||||
Value = 1;
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
Key = "IMAGE_RATE";
|
||||
SDL_FPoint pos{
|
||||
blob.getFloat(),
|
||||
blob.getFloat()};
|
||||
FrameObject.Flag.emplace(Key, pos);
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
Key = "IMAGE_ROTATE";
|
||||
Value = blob.getFloat();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
Key = "RGBA";
|
||||
std::vector<int> RGBA = {
|
||||
(int)blob.get256(),
|
||||
(int)blob.get256(),
|
||||
(int)blob.get256(),
|
||||
(int)blob.get256()};
|
||||
FrameObject.Flag.emplace(Key, RGBA);
|
||||
break;
|
||||
}
|
||||
case 11:
|
||||
{
|
||||
int Effect_Type = blob.getUShort();
|
||||
Key = "GRAPHIC_EFFECT_" + AniScriptParser::Get_Ani_Effect_Type(Effect_Type);
|
||||
std::vector<float> effect;
|
||||
switch (Effect_Type)
|
||||
{
|
||||
case 5:
|
||||
{
|
||||
effect.push_back(blob.get256());
|
||||
effect.push_back(blob.get256());
|
||||
effect.push_back(blob.get256());
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
effect.push_back(blob.get256());
|
||||
effect.push_back(blob.get256());
|
||||
break;
|
||||
}
|
||||
}
|
||||
FrameObject.Flag.emplace(Key, effect);
|
||||
break;
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
Value = blob.getInt();
|
||||
FrameObject.Delay = Value;
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
Key = "DAMAGE_TYPE";
|
||||
std::string DTYPE = AniScriptParser::Get_Ani_Damage_Type(blob.getUShort());
|
||||
FrameObject.Flag.emplace(Key, DTYPE);
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
int SoundTempSize = blob.getInt();
|
||||
Key = "PLAY_SOUND";
|
||||
std::string sound = blob.getString(SoundTempSize);
|
||||
FrameObject.Flag.emplace(Key, sound);
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
Key = "SET_FLAG";
|
||||
Value = blob.getInt();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 24:
|
||||
{
|
||||
Key = "FLIP_TYPE";
|
||||
std::string FTYPEValue = AniScriptParser::Get_Ani_Flip_Type(blob.getUShort());
|
||||
FrameObject.Flag.emplace(Key, FTYPEValue);
|
||||
break;
|
||||
}
|
||||
case 25:
|
||||
{
|
||||
Key = "LOOP_START";
|
||||
FrameObject.Flag.emplace(Key, 1);
|
||||
break;
|
||||
}
|
||||
case 26:
|
||||
{
|
||||
Key = "LOOP_END";
|
||||
Value = blob.getInt();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 27:
|
||||
{
|
||||
Key = "CLIP";
|
||||
std::vector<int> ClipArr{
|
||||
blob.getShort(),
|
||||
blob.getShort(),
|
||||
blob.getShort(),
|
||||
blob.getShort(),
|
||||
};
|
||||
FrameObject.Flag.emplace(Key, ClipArr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Info.Frame.push_back(FrameObject);
|
||||
}
|
||||
return Info;
|
||||
}
|
||||
};
|
||||
|
|
@ -4,134 +4,42 @@
|
|||
#include <variant>
|
||||
#include <unordered_map>
|
||||
#include <SDL.h>
|
||||
#include "Tool/Blob.hpp"
|
||||
#include "Tool/Tool_String.h"
|
||||
|
||||
using AniFlag = std::variant<
|
||||
int,
|
||||
float,
|
||||
SDL_Point,
|
||||
SDL_FPoint,
|
||||
std::string,
|
||||
std::vector<int>,
|
||||
std::vector<float>>;
|
||||
struct AniFrame
|
||||
{
|
||||
std::string Img_Path; // img路径
|
||||
int Img_Index; // img索引
|
||||
SDL_Point Img_Pos; // img位置
|
||||
std::vector<std::vector<int>> AttackBox; // 攻击框
|
||||
std::vector<std::vector<int>> DamageBox; // 受击框
|
||||
std::unordered_map<std::string, AniFlag> Flag; // Frame特效数据
|
||||
int Delay; // 延迟
|
||||
};
|
||||
struct AniInfo
|
||||
{
|
||||
std::vector<std::string> Img_List; // img列表
|
||||
std::vector<AniFrame> Frame; // ani列表
|
||||
std::unordered_map<std::string, AniFlag> Flag; // ani特效数据
|
||||
};
|
||||
namespace AniScriptParser
|
||||
{
|
||||
static std::string Get_Ani_Flag(int data)
|
||||
using AniFlag = std::variant<
|
||||
int,
|
||||
float,
|
||||
SDL_Point,
|
||||
SDL_FPoint,
|
||||
std::string,
|
||||
std::vector<int>,
|
||||
std::vector<float>>;
|
||||
struct AniFrame
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
return "LOOP";
|
||||
case 1:
|
||||
return "SHADOW";
|
||||
case 3:
|
||||
return "COORD";
|
||||
case 7:
|
||||
return "IMAGE_RATE";
|
||||
case 8:
|
||||
return "IMAGE_ROTATE";
|
||||
case 9:
|
||||
return "RGBA";
|
||||
case 10:
|
||||
return "INTERPOLATION";
|
||||
case 11:
|
||||
return "GRAPHIC_EFFECT";
|
||||
case 12:
|
||||
return "DELAY";
|
||||
case 13:
|
||||
return "DAMAGE_TYPE";
|
||||
case 14:
|
||||
return "DAMAGE_BOX";
|
||||
case 15:
|
||||
return "ATTACK_BOX";
|
||||
case 16:
|
||||
return "PLAY_SOUND";
|
||||
case 17:
|
||||
return "PRELOAD";
|
||||
case 18:
|
||||
return "SPECTRUM";
|
||||
case 23:
|
||||
return "SET_FLAG";
|
||||
case 24:
|
||||
return "FLIP_TYPE";
|
||||
case 25:
|
||||
return "LOOP_START";
|
||||
case 26:
|
||||
return "LOOP_END";
|
||||
case 27:
|
||||
return "CLIP";
|
||||
case 28:
|
||||
return "OPERATION";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string Get_Ani_Effect_Type(int data)
|
||||
std::string Img_Path; // img路径
|
||||
int Img_Index; // img索引
|
||||
SDL_Point Img_Pos; // img位置
|
||||
std::vector<std::vector<int>> AttackBox; // 攻击框
|
||||
std::vector<std::vector<int>> DamageBox; // 受击框
|
||||
std::unordered_map<std::string, AniFlag> Flag; // Frame特效数据
|
||||
int Delay; // 延迟
|
||||
};
|
||||
struct AniInfo
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
return "NONE";
|
||||
case 1:
|
||||
return "DODGE";
|
||||
case 2:
|
||||
return "LINEARDODGE";
|
||||
case 3:
|
||||
return "DARK";
|
||||
case 4:
|
||||
return "XOR";
|
||||
case 5:
|
||||
return "MONOCHROME";
|
||||
case 6:
|
||||
return "SPACEDISTORT";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
std::vector<std::string> Img_List; // img列表
|
||||
std::vector<AniFrame> Frame; // ani列表
|
||||
std::unordered_map<std::string, AniFlag> Flag; // ani特效数据
|
||||
};
|
||||
|
||||
static std::string Get_Ani_Flip_Type(int data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 1:
|
||||
return "HORIZON";
|
||||
case 2:
|
||||
return "VERTICAL";
|
||||
case 3:
|
||||
return "ALL";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
// 工具函数
|
||||
std::string Get_Ani_Flag(int data);
|
||||
std::string Get_Ani_Effect_Type(int data);
|
||||
std::string Get_Ani_Flip_Type(int data);
|
||||
std::string Get_Ani_Damage_Type(int data);
|
||||
|
||||
static std::string Get_Ani_Damage_Type(int data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
return "NORMAL";
|
||||
case 1:
|
||||
return "SUPERARMOR";
|
||||
case 2:
|
||||
return "UNBREAKABLE";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
// Ani脚本的读取逻辑
|
||||
AniInfo StructAniInfo(Blob blob);
|
||||
};
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#include "AssetManager.h"
|
||||
#include "EngineCore/Asset_Script.h"
|
||||
#include "Tool/Blob.hpp"
|
||||
#include "Tool/Tool_String.hpp"
|
||||
|
||||
AssetManager::AssetManager()
|
||||
{
|
||||
|
|
@ -10,255 +8,14 @@ AssetManager::~AssetManager()
|
|||
{
|
||||
}
|
||||
|
||||
AniInfo AssetManager::StructAniInfo(std::string path)
|
||||
AniScriptParser::AniInfo AssetManager::StructAniInfo(std::string path)
|
||||
{
|
||||
AniInfo Info;
|
||||
std::vector<BYTE> Data = Asset_Script::GetInstance().GetFileContentByte(path);
|
||||
Blob blob(Data);
|
||||
|
||||
int Frame_Max = blob.getUShort();
|
||||
int Img_Count = blob.getUShort();
|
||||
|
||||
printf("Frame_Max : %d\n", Frame_Max);
|
||||
printf("Img_Count : %d\n", Img_Count);
|
||||
|
||||
// Img的路径读取 存入数组
|
||||
for (int i = 0; i < Img_Count; i++)
|
||||
if (Data.size() > 0)
|
||||
{
|
||||
int Buf = blob.getInt();
|
||||
std::string ImgPath = blob.getString(Buf);
|
||||
printf("ImgPath : %s\n", ImgPath.c_str());
|
||||
Info.Img_List.push_back(ImgPath);
|
||||
Blob blob(Data);
|
||||
return AniScriptParser::StructAniInfo(blob);
|
||||
}
|
||||
|
||||
// Ani头部标签数量
|
||||
int Ani_H_Item_Count = blob.getUShort();
|
||||
// 处理标签
|
||||
for (int i = 0; i < Ani_H_Item_Count; i++)
|
||||
{
|
||||
int Type = blob.getUShort();
|
||||
switch (Type)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
std::string Key = AniScriptParser::Get_Ani_Flag(Type);
|
||||
int Value = blob.getByte();
|
||||
Info.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
case 28:
|
||||
{
|
||||
std::string Key = AniScriptParser::Get_Ani_Flag(Type);
|
||||
int Value = blob.getUShort();
|
||||
Info.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
{
|
||||
blob.getByte();
|
||||
blob.getInt();
|
||||
blob.getInt();
|
||||
blob.getInt();
|
||||
blob.get256();
|
||||
blob.get256();
|
||||
blob.get256();
|
||||
blob.get256();
|
||||
blob.getUShort();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 读取每一个Img
|
||||
for (int i = 0; i < Frame_Max; i++)
|
||||
{
|
||||
AniFrame FrameObject;
|
||||
|
||||
// 碰撞框项目数量
|
||||
int Ani_Box_Item_Count = blob.getUShort();
|
||||
for (int j = 0; j < Ani_Box_Item_Count; j++)
|
||||
{
|
||||
int Box_Type = blob.getUShort();
|
||||
std::vector<int> D_Box_b;
|
||||
for (int k = 0; k < 6; k++)
|
||||
{
|
||||
D_Box_b.push_back(blob.getInt());
|
||||
}
|
||||
if (Box_Type == 15)
|
||||
FrameObject.AttackBox.push_back(D_Box_b);
|
||||
else
|
||||
FrameObject.DamageBox.push_back(D_Box_b);
|
||||
}
|
||||
|
||||
// 调用的第几个Img
|
||||
int Index_Buf = blob.getShort();
|
||||
if (Index_Buf != -1)
|
||||
{
|
||||
FrameObject.Img_Path = Tool_toLowerCase(Info.Img_List[Index_Buf]);
|
||||
FrameObject.Img_Index = blob.getUShort();
|
||||
}
|
||||
else
|
||||
{
|
||||
FrameObject.Img_Path = "";
|
||||
FrameObject.Img_Index = 0;
|
||||
}
|
||||
|
||||
// 坐标
|
||||
FrameObject.Img_Pos = SDL_Point{blob.getInt(), blob.getInt()};
|
||||
|
||||
// Img中的项目数量
|
||||
int Img_Flag_Count = blob.getUShort();
|
||||
for (int j = 0; j < Img_Flag_Count; j++)
|
||||
{
|
||||
int Img_Flag_Type = blob.getUShort();
|
||||
std::string Key;
|
||||
int Value;
|
||||
switch (Img_Flag_Type)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 10:
|
||||
{
|
||||
Key = AniScriptParser::Get_Ani_Flag(Img_Flag_Type);
|
||||
Value = blob.getInt();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
Key = "COORD";
|
||||
Value = blob.getUShort();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 17:
|
||||
{
|
||||
Key = "PRELOAD";
|
||||
Value = 1;
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
Key = "IMAGE_RATE";
|
||||
SDL_FPoint pos{
|
||||
blob.getFloat(),
|
||||
blob.getFloat()};
|
||||
FrameObject.Flag.emplace(Key, pos);
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
Key = "IMAGE_ROTATE";
|
||||
Value = blob.getFloat();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
Key = "RGBA";
|
||||
std::vector<float> RGBA = {
|
||||
blob.get256(),
|
||||
blob.get256(),
|
||||
blob.get256(),
|
||||
blob.get256()};
|
||||
FrameObject.Flag.emplace(Key, RGBA);
|
||||
break;
|
||||
}
|
||||
case 11:
|
||||
{
|
||||
int Effect_Type = blob.getUShort();
|
||||
Key = "GRAPHIC_EFFECT_" + AniScriptParser::Get_Ani_Effect_Type(Effect_Type);
|
||||
std::vector<float> effect;
|
||||
switch (Effect_Type)
|
||||
{
|
||||
case 5:
|
||||
{
|
||||
effect.push_back(blob.get256());
|
||||
effect.push_back(blob.get256());
|
||||
effect.push_back(blob.get256());
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
effect.push_back(blob.get256());
|
||||
effect.push_back(blob.get256());
|
||||
break;
|
||||
}
|
||||
}
|
||||
FrameObject.Flag.emplace(Key, effect);
|
||||
break;
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
Value = blob.getInt();
|
||||
FrameObject.Delay = Value;
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
Key = "DAMAGE_TYPE";
|
||||
std::string DTYPE = AniScriptParser::Get_Ani_Damage_Type(blob.getUShort());
|
||||
FrameObject.Flag.emplace(Key, DTYPE);
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
int SoundTempSize = blob.getInt();
|
||||
Key = "PLAY_SOUND";
|
||||
std::string sound = blob.getString(SoundTempSize);
|
||||
FrameObject.Flag.emplace(Key, sound);
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
Key = "SET_FLAG";
|
||||
Value = blob.getInt();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 24:
|
||||
{
|
||||
Key = "FLIP_TYPE";
|
||||
std::string FTYPEValue = AniScriptParser::Get_Ani_Flip_Type(blob.getUShort());
|
||||
FrameObject.Flag.emplace(Key, FTYPEValue);
|
||||
break;
|
||||
}
|
||||
case 25:
|
||||
{
|
||||
Key = "LOOP_START";
|
||||
FrameObject.Flag.emplace(Key, 1);
|
||||
break;
|
||||
}
|
||||
case 26:
|
||||
{
|
||||
Key = "LOOP_END";
|
||||
Value = blob.getInt();
|
||||
FrameObject.Flag.emplace(Key, Value);
|
||||
break;
|
||||
}
|
||||
case 27:
|
||||
{
|
||||
Key = "CLIP";
|
||||
std::vector<int> ClipArr{
|
||||
blob.getShort(),
|
||||
blob.getShort(),
|
||||
blob.getShort(),
|
||||
blob.getShort(),
|
||||
};
|
||||
FrameObject.Flag.emplace(Key, ClipArr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Info.Frame.push_back(FrameObject);
|
||||
}
|
||||
|
||||
return Info;
|
||||
SDL_LogError(0, "Ani加载失败 Error : %s", path.c_str());
|
||||
return AniScriptParser::AniInfo();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,5 +22,5 @@ private:
|
|||
|
||||
public:
|
||||
// 构造Ani结构体
|
||||
AniInfo StructAniInfo(std::string path);
|
||||
AniScriptParser::AniInfo StructAniInfo(std::string path);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "EngineFrame/Scene/Scene.h"
|
||||
#include "Asset/AssetManager.h"
|
||||
#include "EngineFrame/Component/Animation.h"
|
||||
|
||||
class Scene_SelectCharacter_UI : public Scene
|
||||
{
|
||||
|
|
@ -17,7 +18,23 @@ public:
|
|||
public:
|
||||
void Enter() override
|
||||
{
|
||||
AssetManager::GetInstance().StructAniInfo("common/training/main/main.ani");
|
||||
RefPtr<Actor> actor = new Actor;
|
||||
AddChild(actor);
|
||||
|
||||
RefPtr<Animation> ani3 = new Animation("common/commoneffect/animation/priestslowheal1.ani");
|
||||
actor->AddComponent(ani3);
|
||||
ani3->SetRenderZOrder(1000);
|
||||
|
||||
RefPtr<Animation> ani = new Animation("common/anton/main.ani");
|
||||
actor->AddComponent(ani);
|
||||
ani->SetRenderZOrder(500);
|
||||
|
||||
RefPtr<Animation> ani2 = new Animation("common/anton/face/0/0.ani");
|
||||
actor->AddComponent(ani2);
|
||||
ani2->SetRenderZOrder(1000);
|
||||
|
||||
actor->SetPos(SDL_Point{500, 500});
|
||||
|
||||
SDL_Log("进入了选择角色场景!");
|
||||
};
|
||||
// void HandleEvents(SDL_Event *e) override;
|
||||
|
|
|
|||
Loading…
Reference in New Issue