修改OpenGl渲染底层之前

This commit is contained in:
2025-10-20 20:50:12 +08:00
parent 1b011b9b68
commit 2b888aae5b
61 changed files with 1609 additions and 680 deletions

View File

@@ -4,6 +4,7 @@
#include "EngineFrame/Component/Animation.h"
#include "Actor/Map/GameMapCamera.h"
#include "Actor/Object/CharacterObject.h"
#include "EngineCore/Game.h"
GameMap::GameMap()
{
@@ -45,12 +46,23 @@ void GameMap::InitConfiguration(std::string mapName)
std::string Segment = Data.Get();
if (Segment == "[background pos]")
{
_MapInfo["background_pos"] = std::stoi(Data.Get());
int Offset = std::stoi(Data.Get());
MapOffsetY = Offset;
_MapInfo["background_pos"] = Offset;
}
else if (Segment == "[map name]")
{
_MapInfo["name"] = Data.Get();
}
else if (Segment == "[limit map camera move]")
{
std::vector<int> limit;
limit.push_back(std::stoi(Data.Get()));
limit.push_back(std::stoi(Data.Get()));
limit.push_back(std::stoi(Data.Get()));
limit.push_back(std::stoi(Data.Get()));
_MapInfo["limit_map_camera_move"] = limit;
}
else if (Segment == "[wide mode camera vertical correction]")
{
_MapInfo["wide_mode_camer_vertical_correction"] = std::stoi(Data.Get());
@@ -196,7 +208,10 @@ void GameMap::InitTile()
{
if (!_MapInfo.count("tile"))
return;
// 普通地板数量
int NormalTileCount = 0;
// 普通地板高度
int NormalTileHeight = 560;
std::vector<std::string> tileArr = std::get<std::vector<std::string>>(_MapInfo["tile"]);
if (tileArr.size() > 0)
{
@@ -224,7 +239,7 @@ void GameMap::InitTile()
std::string path = extileArr[i];
RefPtr<Tile> tile = new Tile(path);
int xbuf = i % NormalTileCount * 224;
int ybuf = 560 - 200 - std::get<int>(_MapInfo["background_pos"]) + 40 * (i / NormalTileCount);
int ybuf = -200 - std::get<int>(_MapInfo["background_pos"]) + NormalTileHeight + 120 * (i / NormalTileCount);
tile->SetPos(VecFPos{xbuf, ybuf});
_LayerMap["bottom"]->AddComponent(tile);
}
@@ -325,6 +340,7 @@ void GameMap::LoadMap(std::string mapName)
void GameMap::Enter(Scene *scene)
{
_Scene = scene;
scene->AddChild(_LayerMap["contact"]);
scene->AddChild(_LayerMap["distantback"]);
scene->AddChild(_LayerMap["middleback"]);
@@ -334,18 +350,6 @@ void GameMap::Enter(Scene *scene)
scene->AddChild(_LayerMap["close"]);
scene->AddChild(_LayerMap["cover"]);
scene->AddChild(_LayerMap["max"]);
// TODO
int HSU = 0;
_LayerMap["contact"]->SetPos(VecFPos{0, HSU});
_LayerMap["distantback"]->SetPos(VecFPos{0, HSU});
_LayerMap["middleback"]->SetPos(VecFPos{0, HSU});
_LayerMap["bottom"]->SetPos(VecFPos{0, HSU});
_LayerMap["closeback"]->SetPos(VecFPos{0, HSU});
_LayerMap["normal"]->SetPos(VecFPos{0, HSU});
_LayerMap["close"]->SetPos(VecFPos{0, HSU});
_LayerMap["cover"]->SetPos(VecFPos{0, HSU});
_LayerMap["max"]->SetPos(VecFPos{0, HSU});
}
void GameMap::HandleEvents(SDL_Event *e)
@@ -354,45 +358,68 @@ void GameMap::HandleEvents(SDL_Event *e)
void GameMap::Update(float deltaTime)
{
// this->_Camera->Update(deltaTime);
if (_Scene->GetCamera() == nullptr)
return;
GameMapCamera *Cam = (GameMapCamera *)(_Scene->GetCamera().Get());
int targetX = Cam->_currentPosition.x;
int targetY = Cam->_currentPosition.y;
// 屏幕中心
int width_Separate = Game::GetInstance().Screen_W / 2;
int height_Separate = Game::GetInstance().Screen_H / 2;
// if (this->_Camera)
// {
// int CamearXpos = this->_Camera->X;
// int CamearYpos = this->_Camera->Y;
// int CamearZpos = this->_Camera->Z;
// 获取摄像机可行区域限制
auto limitIt = _MapInfo.find("limit_map_camera_move");
if (limitIt != _MapInfo.end())
{
std::vector<int> limit = std::get<std::vector<int>>(_MapInfo["limit_map_camera_move"]);
int X_Limit_Min = limit[0];
int X_Limit_Max = limit[1];
int Y_Limit_Min = limit[2];
int Y_Limit_Max = limit[3];
// 应用地图边界限制
targetX = std::clamp(targetX, width_Separate, _MapLength - width_Separate);
targetY = std::clamp(targetY, height_Separate, _MapHeight - height_Separate);
// 应用自定义摄像机移动限制
if (X_Limit_Min != -1)
targetX = std::max(targetX, X_Limit_Min);
if (X_Limit_Max != -1)
targetX = std::min(targetX, X_Limit_Max);
if (Y_Limit_Min != -1)
targetY = std::max(targetY, Y_Limit_Min);
if (Y_Limit_Max != -1)
targetY = std::min(targetY, Y_Limit_Max);
}
// SDL_Log("Camera Pos: %d, %d", CamearXpos, CamearYpos);
// // 遍历
// for (auto &pair : _LayerMap)
// {
// // pair.first 是 keystd::string
// std::string key = pair.first;
// // pair.second 是 valueRefPtr<GameMapLayer>
// RefPtr<GameMapLayer> &value = pair.second;
// if (key == "distantback")
// {
// value->SetPos(VecPos{(-CamearXpos + 553), (-CamearYpos + CamearZpos + 300 + 120 + 80)});
// }
// else
// {
// value->SetPos(VecPos{(-CamearXpos + 553), (-CamearYpos + CamearZpos + 300 + 120 + 80)});
// }
// }
// }
// 更新图层位置
for (auto &Layer : _LayerMap)
{
int posX = -targetX + width_Separate;
int posY = -targetY + height_Separate + MapOffsetY;
if (Layer.first == "distantback")
{
posX *= BackgroundMoveSpeed;
posX /= 100;
}
Layer.second->SetPos(VecFPos(posX, posY));
}
}
void GameMap::AddObject(RefPtr<BaseObject> object)
{
object->_AffMap = this;
_LayerMap["normal"]->AddObject(object);
// 如果是角色对象
if (object->m_objecttype == ObjectType::CHARACTER)
{
CharacterObject *chr = (CharacterObject *)(object.Get());
_LayerMap["bottom"]->AddComponent(chr->_Shadow);
}
}
VecFPos3 GameMap::CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset)
VecPos3 GameMap::CheckIsItMovable(VecPos3 CurPos, VecPos3 PosOffset)
{
// 初始化结果为原坐标(默认不移动)
VecFPos3 result = CurPos;
VecPos3 result = CurPos;
// 如果没有可移动区域限制,直接全量位移
if (_MovableArea.empty())

View File

@@ -65,15 +65,18 @@ public:
// 可行区域
std::vector<SDL_FRect> _MovableArea;
// 调试模式
bool _DebugMode = true;
bool _DebugMode = false;
public:
// 图层Map 图层类型 显示对象
std::unordered_map<std::string, RefPtr<GameMapLayer>> _LayerMap;
// 摄像机对象
GameMapCamera *_Camera;
// 所属场景
Scene *_Scene = nullptr;
// 背景层移动速率
int BackgroundMoveSpeed = 103;
// 地图Y轴偏移量
int MapOffsetY = 0;
public:
GameMap(/* args */);
~GameMap();
@@ -91,5 +94,5 @@ public:
public:
// 检查是否可移动
VecFPos3 CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset);
VecPos3 CheckIsItMovable(VecPos3 CurPos, VecPos3 PosOffset);
};

View File

@@ -12,15 +12,10 @@ GameMapCamera::~GameMapCamera()
{
}
void GameMapCamera::SetParentMap(GameMap *map)
{
this->_ParentMap = map;
_ParentMap->_Camera = this;
}
void GameMapCamera::SetFromActor(BaseObject *actor)
{
this->_FromActor = actor;
_FromActor->_AffCamera = this;
}
void GameMapCamera::Update(float deltaTime)
@@ -28,41 +23,105 @@ void GameMapCamera::Update(float deltaTime)
SyncPosByFromParent(deltaTime);
}
void GameMapCamera::SyncPos(float deltaTime)
{
}
void GameMapCamera::SetPos(int x, int y, int z)
{
this->X = x;
this->Y = y;
this->Z = z;
// this->X = x;
// this->Y = y;
// this->Z = z;
}
void GameMapCamera::AddPos(int x, int y, int z)
{
this->X += x;
this->Y += y;
this->Z += z;
// this->X += x;
// this->Y += y;
// this->Z += z;
}
void GameMapCamera::SyncPosByFromParent(float deltaTime)
{
if (this->_FromActor != nullptr)
if (this->_FromActor == nullptr)
{
float width_Separate = Game::GetInstance().Screen_W / 2;
float height_Separate = Game::GetInstance().Screen_H / 2;
int R_X, R_Y, R_Z;
R_X = std::fmin(std::fmax(this->_FromActor->Position.x, width_Separate), _ParentMap->_MapLength - width_Separate);
R_Y = std::fmin(std::fmax(this->_FromActor->Position.y, height_Separate), _ParentMap->_MapHeight - height_Separate);
R_Z = 0;
// SDL_Log("R_X: %d, R_Y: %d, R_Z: %d", R_X, R_Y, R_Z);
// SetPos(R_X, R_Y, R_Z);
return;
}
int targetX = _FromActor->Position.x;
int targetY = _FromActor->Position.y;
for (auto Layer : _ParentMap->_LayerMap)
{
if (Layer.first == "distantback")
{
Layer.second->SetPos(VecFPos((-R_X + width_Separate) * BackgroundMoveSpeed, -R_Y + R_Z + height_Separate + 120 + BackgroundOffset));
}
else
Layer.second->SetPos(VecFPos((-R_X + width_Separate), -R_Y + R_Z + height_Separate + 120 + BackgroundOffset));
}
if (_isSmoothMoving)
{
// 平滑移动计算
VecPos targetPosition(targetX, targetY);
_currentPosition = SmoothDamp(_currentPosition, targetPosition, _velocity, _smoothTime, _maxSpeed, deltaTime);
}
else
{
_currentPosition.x = targetX;
_currentPosition.y = targetY;
}
}
VecPos GameMapCamera::SmoothDamp(const VecPos &current, const VecPos &target, VecPos &currentVelocity, float smoothTime, int maxSpeed, float deltaTime)
{
// 平滑时间为0时直接返回目标位置并重置速度
if (smoothTime <= 0.f)
{
currentVelocity = VecPos(0, 0);
return target;
}
// 临界阻尼系数计算(避免过冲的核心参数)
const float omega = 2.0f / smoothTime;
const float x = omega * deltaTime;
const float expTerm = 1.0f / (1.0f + x + 0.48f * x * x + 0.235f * x * x * x);
// 计算当前位置与目标的差值
VecPos delta = target - current;
// 计算目标速度(基于阻尼公式和当前差值)
// 注意:这里先通过浮点计算保持精度,最后转换为整数
const float tx = delta.x * (omega * omega * deltaTime) - currentVelocity.x * (1.0f + 0.48f * x) * x;
const float ty = delta.y * (omega * omega * deltaTime) - currentVelocity.y * (1.0f + 0.48f * x) * x;
VecPos targetVelocity(static_cast<int>(tx), static_cast<int>(ty));
// 应用速度衰减(指数平滑)
currentVelocity += targetVelocity;
currentVelocity = VecPos(
static_cast<int>(currentVelocity.x * expTerm),
static_cast<int>(currentVelocity.y * expTerm));
// 限制最大速度如果设置了maxSpeed
if (maxSpeed > 0)
{
// 计算当前速度的模长(浮点精度)
const float speedSq = static_cast<float>(currentVelocity.x * currentVelocity.x + currentVelocity.y * currentVelocity.y);
const float maxSpeedSq = static_cast<float>(maxSpeed * maxSpeed);
if (speedSq > maxSpeedSq)
{
// 速度超限,按比例缩放至最大速度
const float scale = maxSpeed / sqrtf(speedSq);
currentVelocity = VecPos(
static_cast<int>(currentVelocity.x * scale),
static_cast<int>(currentVelocity.y * scale));
}
}
// 计算新位置(当前位置 + 速度 * 时间)
VecPos newPos = current + VecPos(
static_cast<int>(currentVelocity.x * deltaTime),
static_cast<int>(currentVelocity.y * deltaTime));
// 检测过冲:如果新位置已越过目标,直接锁定目标并重置速度
// 点积 > 0 表示方向相反(已超过目标)
const int dot = delta.x * (newPos.x - target.x) + delta.y * (newPos.y - target.y);
if (dot > 0)
{
newPos = target;
currentVelocity = VecPos(0, 0);
}
return newPos;
}

View File

@@ -5,41 +5,37 @@ class BaseObject;
class GameMapCamera : public Actor
{
private:
GameMap *_ParentMap = nullptr;
// 跟随对象
BaseObject *_FromActor = nullptr;
public:
// 摄像机坐标
int X = 0;
int Y = 0;
int Z = 0;
// 镜头可行坐标
int MovableAreaX = 0;
int MovableAreaY = 0;
// 背景偏移量
int BackgroundOffset = 0;
// 背景层移动速率
int BackgroundMoveSpeed = 1.03;
// 人物中线长度
int CharacterLineLength = 0;
// 摄像机朝向
int Direction = 1;
// 摄像机朝向时间
float DirectionTime = 0.f;
// 摄像机记录的跟随对象坐标
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 SetParentMap(GameMap *map);
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 &current, const VecPos &target, VecPos &currentVelocity, float smoothTime, int maxSpeed, float deltaTime);
};

View File

@@ -28,6 +28,7 @@ void GameMapLayer::Render()
// 绘制填充矩形
SDL_RenderFillRect(renderer, &buf);
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 250);
}
void GameMapLayer::AddDebugFeasibleAreaInfo(VecFPos pos, VecSize size)

View File

@@ -7,8 +7,6 @@ class BaseObject;
class GameMapLayer : public Actor
{
private:
// 地图对象
std::vector<RefPtr<Component>> ObjectManager;
// 可行区域信息
std::vector<SDL_Rect> FeasibleAreaInfoList;

View File

@@ -1,5 +1,6 @@
#include "Tile.h"
#include "Tool/Tool_String.h"
#include "EngineCore/Game.h"
Tile::Tile()
{
}
@@ -12,6 +13,7 @@ Tile::Tile(std::string Path) : Sprite()
m_texture = new Texture(std::get<std::string>(m_data["path"]), std::get<int>(m_data["idx"]));
Sprite::Init();
this->imgPath = Path;
}
Tile::~Tile()
@@ -42,4 +44,4 @@ void Tile::InitInfo(std::string Path)
m_data["pos"] = std::stoi(Data.Get());
}
}
}
}

View File

@@ -1,15 +1,12 @@
#include "ActiveObject.h"
void ActiveObject::SetPosition(VecFPos3 pos)
void ActiveObject::SetPosition(VecPos3 pos)
{
BaseObject::SetPosition(pos);
BaseObject::SetRenderZOrder(this->Position.y);
}
void ActiveObject::SetYpos(float y)
void ActiveObject::SetYpos(int y)
{
BaseObject::SetYpos(y);
BaseObject::SetRenderZOrder(this->Position.y);
}
void ActiveObject::SetSpeed(VecSpeed3 speed)
@@ -24,27 +21,49 @@ VecSpeed3 ActiveObject::GetSpeed()
void ActiveObject::Update(float deltaTime)
{
// X Y 轴方向的加速度计算
if (Speed.x != 0 || Speed.y != 0)
int IntegerDelta = static_cast<int>(deltaTime * 1000);
const int Gravity = 1020;
// X轴移动含余数补偿
if (Speed.x != 0)
{
MoveBy(Speed.x * deltaTime, Speed.y * deltaTime, 0);
int totalX = Speed.x * IntegerDelta + Remainder.x; // 加上上次余数
int moveX = totalX / 1000; // 整数部分为实际移动
Remainder.x = totalX % 1000; // 保留余数(-999~999
MoveBy(moveX, 0, 0);
}
// Z轴只在Z轴大于0时 或者 Z轴速度向上时才会有重力
// Y轴移动同上
if (Speed.y != 0)
{
int totalY = Speed.y * IntegerDelta + Remainder.y;
int moveY = totalY / 1000;
Remainder.y = totalY % 1000;
MoveBy(0, moveY, 0);
}
// Z轴重力与移动含余数补偿
if (Position.z > 0 || Speed.z > 0)
{
// TODO 还没有写角色属性 要读了角色属性以后才是正确的
float Gravity = 68000.0 / 1000.0 * 15.0;
Speed.z -= Gravity * deltaTime;
MoveBy(0, 0, Speed.z * deltaTime);
// 重力对速度的影响先更新Speed.z含余数
int speedZTotal = -Gravity * IntegerDelta + Remainder.z; // 注意负号(减速)
Speed.z += speedZTotal / 1000; // 速度的整数部分
Remainder.z = speedZTotal % 1000; // 速度的余数
// 基于更新后的Speed.z计算移动量同样含余数
int moveZTotal = Speed.z * IntegerDelta + _zRemainderMove; // 新增_zRemainderMove记录移动余数
int moveZ = moveZTotal / 1000;
_zRemainderMove = moveZTotal % 1000;
MoveBy(0, 0, moveZ);
}
// Z轴小于0时要修正
else if (Position.z < 0)
{
Position.z = 0;
Speed.z = 0;
Remainder.z = 0; // 重置余数
_zRemainderMove = 0;
SetPosition(Position);
SDL_LogError(0, "修正Z轴");
}
// 执行父类的更新
BaseObject::Update(deltaTime);
}

View File

@@ -5,11 +5,16 @@ class ActiveObject : public BaseObject
{
public:
// 三轴速度
VecSpeed3 Speed;
// 三轴移动余数
VecPos3 Remainder;
int _zRemainderMove = 0;
public:
void SetPosition(VecFPos3 pos) override;
void SetYpos(float y) override;
void
SetPosition(VecPos3 pos) override;
void SetYpos(int y) override;
void SetSpeed(VecSpeed3 speed);
VecSpeed3 GetSpeed();

View File

@@ -1,5 +1,7 @@
#include "BaseObject.h"
#include "Actor/Map/GameMap.h"
#include "Actor/Map/GameMapCamera.h"
BaseObject::BaseObject()
{
Init(); // 调用了RenderBase的Init函数 对象才会被执行回调
@@ -10,41 +12,50 @@ BaseObject::~BaseObject()
{
}
void BaseObject::SetPosition(VecFPos3 pos)
void BaseObject::Update(float deltaTime)
{
if (_AffCamera != nullptr)
{
_AffCamera->SyncPos(deltaTime);
}
Actor::Update(deltaTime);
}
void BaseObject::SetPosition(VecPos3 pos)
{
if (pos.y != this->Position.y)
{
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
SetRenderZOrder(pos.y); // 设置渲染顺序
}
this->Position = pos;
Actor::SetPos(VecFPos{this->Position.x, this->Position.y - this->Position.z});
SetPos(VecFPos{this->Position.x, this->Position.y - this->Position.z});
}
VecFPos3 BaseObject::GetPosition()
VecPos3 BaseObject::GetPosition()
{
return this->Position;
}
void BaseObject::SetXpos(float x)
void BaseObject::SetXpos(int x)
{
this->Position.x = x;
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
SetPos({this->Position.x, this->Position.y - this->Position.z});
}
void BaseObject::SetYpos(float y)
void BaseObject::SetYpos(int y)
{
if (y != this->Position.y)
{
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
SetRenderZOrder(y); // 设置渲染顺序
}
this->Position.y = y;
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
SetPos({this->Position.x, this->Position.y - this->Position.z});
}
void BaseObject::SetZpos(float z)
void BaseObject::SetZpos(int z)
{
this->Position.z = z;
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
SetPos({this->Position.x, this->Position.y - this->Position.z});
}
int BaseObject::GetXpos()
@@ -62,28 +73,33 @@ int BaseObject::GetZpos()
return this->Position.z;
}
void BaseObject::MoveBy(VecFPos3 pos)
void BaseObject::MoveBy(VecPos3 pos)
{
// 只有moveby移动时判断所在地图中是否能够这样移动
VecFPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), pos);
if (pos.y != 0)
VecPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), pos);
if (RealPos.y != this->Position.y)
{
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
SetRenderZOrder(RealPos.y); // 设置渲染顺序
}
if (RealPos != this->Position){
this->Position = RealPos;
SetPos({this->Position.x, this->Position.y - this->Position.z});
}
this->Position = RealPos;
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
}
void BaseObject::MoveBy(float x, float y, float z)
void BaseObject::MoveBy(int x, int y, int z)
{
// 只有moveby移动时判断所在地图中是否能够这样移动
VecFPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), VecFPos3({x, y, z}));
if (y != 0)
VecPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), VecPos3({x, y, z}));
if (RealPos.y != this->Position.y)
{
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
SetRenderZOrder(RealPos.y); // 设置渲染顺序
}
if (RealPos != this->Position)
{
this->Position = RealPos;
SetPos({this->Position.x, this->Position.y - this->Position.z});
}
this->Position = RealPos;
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
}
void BaseObject::SetDirection(int dir)

View File

@@ -1,38 +1,43 @@
#pragma once
#include "EngineFrame/Actor/Actor.h"
#include "Asset/Common/ObjectVars.h"
#include "Global/Global_Enum.h"
class GameMap;
class GameMapCamera;
class BaseObject : public Actor
{
private:
/* data */
public:
VecFPos3 Position; // 位置
public:
ObjectType m_objecttype; // 对象类型
VecPos3 Position; // 位置
int Direction = 0; // 方向
GameMap *_AffMap = nullptr; // 所在地图
GameMapCamera *_AffCamera = nullptr; // 跟随相机
public:
BaseObject(/* args */);
~BaseObject();
void Update(float deltaTime) override;
// 数据储存器
ObjectVars _ObjectVars;
public:
virtual void SetPosition(VecFPos3 pos);
virtual void SetXpos(float x);
virtual void SetYpos(float y);
virtual void SetZpos(float z);
virtual void SetPosition(VecPos3 pos);
virtual void SetXpos(int x);
virtual void SetYpos(int y);
virtual void SetZpos(int z);
VecFPos3 GetPosition();
VecPos3 GetPosition();
int GetXpos();
int GetYpos();
int GetZpos();
void MoveBy(VecFPos3 pos);
void MoveBy(float x, float y, float z);
void SetDirection(int dir);
virtual void MoveBy(VecPos3 pos);
virtual void MoveBy(int x, int y, int z);
virtual void SetDirection(int dir);
int GetDirection();
ObjectVars &GetObjectVars();

View File

@@ -5,21 +5,16 @@ CharacterObject::~CharacterObject()
{
}
void CharacterObject::Update(float deltaTime)
{
ActiveObject::Update(deltaTime);
}
void CharacterObject::Render()
{
ActiveObject::Render();
}
void CharacterObject::Construction(int job)
{
m_objecttype = ObjectType::CHARACTER;
this->Job = job;
// 创建装备管理器
_EquipmentManager = new Chr_Equipment();
_EquipmentManager->Init(this);
// 创建阴影对象
_Shadow = new Chr_Shadow();
_Shadow->Init(this);
// 创建动画管理器(一定要先创建装备管理器再创建动画管理器 因为需要读取身上的装备)
_AnimationManager = new Chr_Animation();
_AnimationManager->Init(this);
@@ -55,3 +50,20 @@ void CharacterObject::ControllerMsg(CONTROLLER_MSG_TYPE msgType, void *msgData)
this->_StateMachine->ChangeState(BASE_STATE::MOVE);
}
}
void CharacterObject::Update(float deltaTime)
{
ActiveObject::Update(deltaTime);
}
void CharacterObject::SetPos(VecFPos pos)
{
BaseObject::SetPos(pos);
if(_Shadow)_Shadow->SetPos(this->GetPos());
}
void CharacterObject::SetDirection(int dir)
{
BaseObject::SetDirection(dir);
if(_Shadow)_Shadow->SetDirection(this->GetDirection());
}

View File

@@ -4,6 +4,7 @@
#include "Asset/Character/Chr_Equipment.h"
#include "Asset/Character/Chr_Controller.h"
#include "Asset/Character/Chr_StateMachine.h"
#include "Asset/Character/Chr_Shadow.h"
#include "Global/Global_Enum.h"
class CharacterObject : public ActiveObject
{
@@ -16,6 +17,9 @@ public:
RefPtr<Chr_Controller> _Controller = nullptr;
// 角色状态机
RefPtr<Chr_StateMachine> _StateMachine = nullptr;
// 角色阴影对象
RefPtr<Chr_Shadow> _Shadow = nullptr;
// 职业
int Job = 0;
// 转职职业 如果是-1则没有转职
@@ -25,8 +29,6 @@ public:
~CharacterObject();
public:
void Update(float deltaTime) override;
void Render() override;
// 通过职业创建角色
void Construction(int job);
@@ -36,4 +38,8 @@ public:
void DisableController();
// 控制器信息
void ControllerMsg(CONTROLLER_MSG_TYPE msgType, void* msgData);
void Update(float deltaTime) override;
void SetPos(VecFPos pos) override;
void SetDirection(int dir) override;
};

View File

@@ -0,0 +1,10 @@
#include "MonsterObject.h"
#include "Global/Global_Game.h"
void MonsterObject::Construction(int MonsterID)
{
this->Id = MonsterID;
// 创建动画管理器(一定要先创建装备管理器再创建动画管理器 因为需要读取身上的装备)
_AnimationManager = new Mon_Animation();
_AnimationManager->Init(this);
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "Actor/Object/ActiveObject.h"
#include "Global/Global_Enum.h"
#include "Asset/Monster/Mon_Animation.h"
class MonsterObject : public ActiveObject
{
public:
// 怪物动画管理器
RefPtr<Mon_Animation> _AnimationManager = nullptr;
// 怪物ID
int Id = 0;
public:
// 通过ID创建怪物
void Construction(int MonsterID);
};

View File

@@ -36,6 +36,14 @@ void Chr_Animation::CreateSkinmationBySlot(std::string actionName, std::string s
Ani->SetRenderZOrder(Variation.Layer);
this->AddChild(Ani);
ActionAnis[actionName].push_back(Ani);
// 构造一下阴影对象
RefPtr<Animation> ShadowAni = new Animation(path, FormatImgPath, Data);
ShadowAni->SetVisible(false);
// 皮肤统一设置阴影
ShadowAni->SetShadow();
chr_parent->_Shadow->AddChild(ShadowAni);
chr_parent->_Shadow->ActionAnis[actionName].push_back(ShadowAni);
}
}
}
@@ -106,11 +114,7 @@ void Chr_Animation::SetAction(std::string actionName)
Ani->SetVisible(true);
}
CurrentActionTag = actionName;
}
void Chr_Animation::Update(float deltaTime)
{
RenderBase::Update(deltaTime);
// SDL_Log("Position %d %d", this->GetTransform().position.x, this->GetTransform().position.y);
// SDL_Log("IterPosition %d %d", this->GetIterationTransform().position.x, this->GetIterationTransform().position.y);
// 设置阴影的动作
chr_parent->_Shadow->SetAction(actionName);
}

View File

@@ -45,6 +45,4 @@ public:
void Init(CharacterObject *parent);
// 设置动作
void SetAction(std::string actionName);
void Update(float deltaTime) override;
};

View File

@@ -0,0 +1,44 @@
#include "Chr_Shadow.h"
#include "Global/Global_Game.h"
#include "Actor/Object/CharacterObject.h"
#include "Asset/Character/Chr_Equipment.h"
void Chr_Shadow::Init(CharacterObject *parent)
{
// 调用RenderBase类的初始化 才能挂上标签
RenderBase::Init();
chr_parent = parent;
SetRenderZOrder(1000000);
SetPos(parent->GetPos());
}
void Chr_Shadow::SetAction(std::string actionName)
{
// 先将原动作的Ani设置为不可见
for (auto Ani : ActionAnis[CurrentActionTag])
{
Ani->Reset();
Ani->SetVisible(false);
}
// 再将新动作的Ani设置为可见
for (auto Ani : ActionAnis[actionName])
{
Ani->SetVisible(true);
}
CurrentActionTag = actionName;
}
void Chr_Shadow::SetDirection(int dir)
{
VecFPos sc = GetScale();
// 朝右
if (dir == 0)
{
SetScale(VecFPos({SDL_fabsf(sc.x), sc.y}));
}
// 朝左
else if (dir == 1)
{
SetScale(VecFPos({-SDL_fabsf(sc.x), sc.y}));
}
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include "EngineFrame/Component/Animation.h"
#include <string>
#include <vector>
#include <unordered_map>
class CharacterObject;
class Chr_Shadow : public RenderBase
{
// 动作动画集合
using ActionAniList = std::map<std::string, std::vector<RefPtr<Animation>>>;
private:
/* data */
public:
// 父对象
CharacterObject *chr_parent;
// 时装部位对应的动作动画集合
ActionAniList ActionAnis;
// 当前动作Tag
std::string CurrentActionTag = "waiting";
// 初始化时
void Init(CharacterObject *parent);
// 设置动作
void SetAction(std::string actionName);
// 设置方向
void SetDirection(int dir);
};

View File

@@ -0,0 +1,39 @@
#include "Mon_Animation.h"
#include "Actor/Object/MonsterObject.h"
#include "Global/Global_Game.h"
void Mon_Animation::Init(MonsterObject *parent)
{
// 调用RenderBase类的初始化 才能挂上标签
RenderBase::Init();
parent->AddChild(this);
mon_parent = parent;
GlobalMonsterScript::MonsterConfig Config = Global_Game::GetInstance().GetMonsterInfo(mon_parent->Id);
// 遍历所有动作Ani路径
for (const auto &pair : Config.animationPath)
{
std::string ActionName = pair.first;
std::string Path = std::string(Config.folder + Tool_toLowerCase(pair.second));
RefPtr<Animation> Ani = new Animation(Path);
this->ActionAnis[ActionName] = Ani;
Ani->SetVisible(false);
this->AddChild(Ani);
}
// 默认动作
this->SetAction("waiting");
}
void Mon_Animation::SetAction(std::string actionName)
{
// 先将原动作的Ani设置为不可见
ActionAnis[CurrentActionTag]->Reset();
ActionAnis[CurrentActionTag]->SetVisible(false);
// 再将新动作的Ani设置为可见
ActionAnis[actionName]->SetVisible(true);
CurrentActionTag = actionName;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "EngineFrame/Component/Animation.h"
#include <string>
#include <vector>
#include <unordered_map>
class MonsterObject;
class Mon_Animation : public RenderBase
{
// 动作动画集合
using ActionAniList = std::map<std::string, RefPtr<Animation>>;
private:
// 父对象
MonsterObject *mon_parent;
// 动作动画集合
ActionAniList ActionAnis;
// 当前动作Tag
std::string CurrentActionTag = "waiting";
public:
// 初始化时 只完成基础的职业皮肤设置
void Init(MonsterObject *parent);
// 设置动作
void SetAction(std::string actionName);
};

View File

@@ -15,7 +15,7 @@ static SQInteger SQR_GetPosition(HSQUIRRELVM v)
SQUserPointer ptr;
sq_getuserpointer(v, 2, &ptr);
BaseObject *obj = (BaseObject *)ptr;
VecFPos3 Pos = obj->GetPosition();
VecPos3 Pos = obj->GetPosition();
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
@@ -40,7 +40,7 @@ static SQInteger SQR_SetPosition(HSQUIRRELVM v)
sq_getfloat(v, 3, &PosX);
sq_getfloat(v, 4, &PosY);
sq_getfloat(v, 5, &PosZ);
obj->SetPosition(VecFPos3(PosX, PosY, PosZ));
obj->SetPosition(VecPos3(PosX, PosY, PosZ));
return 0;
}

View File

@@ -0,0 +1,336 @@
#pragma once
#include "squirrel/SquirrelEx.h"
#include "EngineFrame/Actor/Actor.h"
#include "EngineFrame/Component/Sprite.h"
static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size))
{
Actor *Abli = (Actor *)p;
Abli->Release();
return 0;
}
static SQInteger SQR_RegisterDestruction(HSQUIRRELVM v)
{
// 析构函数测试
SQUserPointer P;
sq_getuserpointer(v, 2, &P);
sq_setinstanceup(v, 3, P);
sq_setreleasehook(v, 3, _file_releasehook);
return 0;
}
static SQInteger SQR_CreateActor(HSQUIRRELVM v)
{
RefPtr<Actor> act = new Actor();
act->Retain();
sq_pushuserpointer(v, act.Get());
return 1;
}
static SQInteger SQR_AddChild(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQUserPointer B_obj;
sq_getuserpointer(v, 3, &B_obj);
Actor *Aobj = (Actor *)A_obj;
Actor *Bobj = (Actor *)B_obj;
Aobj->AddChild(Bobj);
return 0;
}
static SQInteger SQR_RemoveChild(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQUserPointer B_obj;
sq_getuserpointer(v, 3, &B_obj);
Actor *Aobj = (Actor *)A_obj;
Actor *Bobj = (Actor *)B_obj;
Aobj->RemoveChild(Bobj);
return 0;
}
static SQInteger SQR_GetZOrder(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor *Aobj = (Actor *)A_obj;
sq_pushinteger(v, Aobj->GetRenderZOrder());
return 1;
}
static SQInteger SQR_SetZOrder(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQInteger Value;
sq_getinteger(v, 3, &Value);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetRenderZOrder(Value);
return 0;
}
static SQInteger SQR_GetPos(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor *Aobj = (Actor *)A_obj;
VecFPos Pos = Aobj->GetPos();
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
static SQInteger SQR_SetPos(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3)
{
VecFPos Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar *key;
sq_getstring(v, -2, &key);
if (strcmp(key, _SC("x")) == 0)
{
Pos.x = value;
}
else if (strcmp(key, _SC("y")) == 0)
{
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetPos(Pos);
}
else if (sq_gettop(v) == 4)
{
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetPos(VecFPos(X, Y));
}
return 0;
}
static SQInteger SQR_GetAlpha(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor *Aobj = (Actor *)A_obj;
sq_pushfloat(v, Aobj->GetAlpha());
return 1;
}
static SQInteger SQR_SetAlpha(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQFloat Value;
sq_getfloat(v, 3, &Value);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetAlpha(Value);
return 0;
}
static SQInteger SQR_GetScale(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor *Aobj = (Actor *)A_obj;
VecFPos Pos = Aobj->GetScale();
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
static SQInteger SQR_SetScale(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3)
{
VecFPos Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar *key;
sq_getstring(v, -2, &key);
if (strcmp(key, _SC("x")) == 0)
{
Pos.x = value;
}
else if (strcmp(key, _SC("y")) == 0)
{
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetScale(Pos);
}
else if (sq_gettop(v) == 4)
{
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetScale(VecFPos(X, Y));
}
return 0;
}
static SQInteger SQR_GetRotation(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor *Aobj = (Actor *)A_obj;
sq_pushfloat(v, Aobj->GetRotation());
}
static SQInteger SQR_SetRotation(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQFloat Value;
sq_getfloat(v, 3, &Value);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetRotation(Value);
return 0;
}
static SQInteger SQR_GetSize(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor *Aobj = (Actor *)A_obj;
VecSize Pos = Aobj->GetSize();
sq_newtable(v);
sq_pushstring(v, _SC("w"), -1);
sq_pushfloat(v, Pos.width);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("h"), -1);
sq_pushfloat(v, Pos.height);
sq_newslot(v, 3, SQFalse);
return 1;
}
static SQInteger SQR_SetSize(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3)
{
VecSize Size;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar *key;
sq_getstring(v, -2, &key);
if (strcmp(key, _SC("w")) == 0)
{
Size.width = value;
}
else if (strcmp(key, _SC("h")) == 0)
{
Size.height = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetSize(Size);
}
else if (sq_gettop(v) == 4)
{
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor *Aobj = (Actor *)A_obj;
Aobj->SetSize(VecSize(X, Y));
}
return 0;
}
static SQInteger SQR_CreateSprite(HSQUIRRELVM v)
{
const SQChar *ImgPath;
SQInteger Idx;
sq_getstring(v, 2, &ImgPath);
sq_getinteger(v, 3, &Idx);
RefPtr<Sprite> act = new Sprite(ImgPath, Idx);
act->Retain();
sq_pushuserpointer(v, act.Get());
return 1;
}
static void RegisterUINutApi(const SQChar *funcName, SQFUNCTION funcAddr, HSQUIRRELVM v)
{
sq_pushroottable(v);
sq_pushstring(v, funcName, -1);
sq_newclosure(v, funcAddr, 0);
sq_newslot(v, -3, false);
sq_poptop(v);
}
static void RegisterUI()
{
SDL_Log("初始化 UI函数-松鼠脚本!");
HSQUIRRELVM v = SquirrelEx::GetInstance().GetSquirrelVM();
// 析构函数
RegisterUINutApi(_SC("sq_RegisterDestruction"), SQR_RegisterDestruction, v);
RegisterUINutApi(_SC("sq_CreateActor"), SQR_CreateActor, v);
RegisterUINutApi(_SC("sq_AddChild"), SQR_AddChild, v);
RegisterUINutApi(_SC("sq_RemoveChild"), SQR_RemoveChild, v);
RegisterUINutApi(_SC("sq_GetZOrder"), SQR_GetZOrder, v);
RegisterUINutApi(_SC("sq_SetZOrder"), SQR_SetZOrder, v);
RegisterUINutApi(_SC("sq_GetPos"), SQR_GetPos, v);
RegisterUINutApi(_SC("sq_SetPos"), SQR_SetPos, v);
RegisterUINutApi(_SC("sq_GetAlpha"), SQR_GetAlpha, v);
RegisterUINutApi(_SC("sq_SetAlpha"), SQR_SetAlpha, v);
RegisterUINutApi(_SC("sq_GetScale"), SQR_GetScale, v);
RegisterUINutApi(_SC("sq_SetScale"), SQR_SetScale, v);
RegisterUINutApi(_SC("sq_GetRotation"), SQR_GetRotation, v);
RegisterUINutApi(_SC("sq_SetRotation"), SQR_SetRotation, v);
RegisterUINutApi(_SC("sq_GetSize"), SQR_GetSize, v);
RegisterUINutApi(_SC("sq_SetSize"), SQR_SetSize, v);
RegisterUINutApi(_SC("sq_CreateSprite"), SQR_CreateSprite, v);
}

View File

@@ -3,6 +3,8 @@
void SquirrelManager::Init()
{
SDL_Log("开始初始化sqr管理器!");
// UI函数
RegisterUI();
// 基础对象
RegisterBaseObject();
// 动态对象

View File

@@ -1,4 +1,5 @@
#pragma once
#include "Asset/Squirrel/Sqr_UI.hpp"
#include "Asset/Squirrel/Sqr_BaseObject.hpp"
#include "Asset/Squirrel/Sqr_ActiveObject.hpp"
#include "Asset/Squirrel/Sqr_CharacterObject.hpp"

View File

@@ -29,8 +29,11 @@ enum BASE_STATE
JUMP, // 跳跃
};
// 对象类型
enum ObjectType
{
BASE = 0, // 基础对象
ACTIVE = 1 << 0, // 动态对象
CHARACTER = 1 << 1, // 角色对象
MONSTER = 1 << 2 // 怪物对象
};

View File

@@ -27,6 +27,8 @@ void Global_Game::InitGame()
CharacterConfigs = GlobalCharacterScript::InitCharacterLst();
// 读取装备配置文件
EquipmentPathMap = GlobalEquipmentScript::InitEquipmentLst();
// 读取怪物配置文件
MonsterPathMap = GlobalMonsterScript::InitMonsterLst();
// 初始化松鼠脚本管理器
SquirrelManager::GetInstance().Init();
@@ -36,3 +38,24 @@ void Global_Game::InitGame()
// 游戏初始化完成标志
InitFlag = true;
}
GlobalMonsterScript::MonsterConfig Global_Game::GetMonsterInfo(int id)
{
if (!InitFlag)
{
SDL_LogError(0, "游戏未初始化");
return GlobalMonsterScript::MonsterConfig();
}
if (MonsterInfoMap.count(id))
return MonsterInfoMap[id];
if (!MonsterPathMap.count(id))
{
SDL_LogError(0, "怪物ID不存在");
return GlobalMonsterScript::MonsterConfig();
}
std::string path = MonsterPathMap[id];
GlobalMonsterScript::MonsterConfig MonsterConfig = GlobalMonsterScript::ReadMonsterConfig(path);
MonsterConfig.id = id;
MonsterInfoMap[id] = MonsterConfig;
return MonsterConfig;
}

View File

@@ -2,6 +2,7 @@
#include "EngineCore/Game.h"
#include "Global/Script/CharacterConfig.h"
#include "Global/Script/EquipmentConfig.h"
#include "Global/Script/MonsterConfig.h"
#include "Global/Save/SavaManager.h"
#include "Asset/Squirrel/SquirrelManager.h"
class Global_Game
@@ -36,6 +37,11 @@ public:
// 装备路径Map
std::map<int, std::string> EquipmentPathMap;
// 怪物相关
std::map<int, std::string> MonsterPathMap; // 路径
std::map<int, GlobalMonsterScript::MonsterConfig> MonsterInfoMap; // 信息
GlobalMonsterScript::MonsterConfig GetMonsterInfo(int id); // 获取怪物信息
// 游戏资源初始化标志
bool InitFlag = false;

View File

@@ -0,0 +1,46 @@
#include "MonsterConfig.h"
#include "Asset/AssetManager.h"
#include "Tool/Tool_String.h"
namespace GlobalMonsterScript
{
std::map<int, std::string> InitMonsterLst()
{
std::map<int, std::string> EquipList;
ScriptData Data = AssetManager::GetInstance().GetScriptInfo("monster/monster.lst");
while (!Data.IsEnd())
{
std::string Index = Data.Get();
std::string MonsterPath = std::string("monster/") + Data.Get();
EquipList[std::stoi(Index)] = MonsterPath;
}
return EquipList;
}
MonsterConfig ReadMonsterConfig(std::string path)
{
MonsterConfig Config;
Config.folder = path.substr(0, path.find_last_of('/') + 1);
ScriptData Data = AssetManager::GetInstance().GetScriptInfo(path);
while (!Data.IsEnd())
{
std::string Segment = Data.Get();
if (Segment == "name")
{
Config.name = Data.Get();
}
else if (Segment == "[动作动画]")
{
while (true)
{
std::string Ret = Data.Get();
if (Ret == "[/动作动画]")
break;
std::string path = Data.Get();
Config.animationPath[Ret] = path;
}
}
}
return Config;
}
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <string>
#include <vector>
#include <map>
namespace GlobalMonsterScript
{
// 怪物配置
struct MonsterConfig
{
//编号
int id = -1;
//名称
std::string name = "none";
//动作动画
std::map<std::string, std::string> animationPath;
//所在文件夹
std::string folder = "none";
};
// 读取怪物列表
std::map<int, std::string> InitMonsterLst();
// 读取怪物数据
MonsterConfig ReadMonsterConfig(std::string path);
}

View File

@@ -1,5 +1,5 @@
#include "Scene/Scene_Loading_UI.h"
#include "Scene/Scene_SelectCharacter_UI.hpp"
#include "Scene/Scene_MainUi.h"
#include "Scene/Scene_Test.h"
#include "Scene_Loading_UI.h"
#include "EngineFrame/Component/Sprite.h"
@@ -50,7 +50,7 @@ void Scene_Loading_UI::Update(float deltaTime)
RefPtr<Scene_Test> scene = new Scene_Test;
Game::GetInstance().ChangeScene(scene);
// 设定UI层场景
RefPtr<Scene_SelectCharacter_UI> sceneUI = new Scene_SelectCharacter_UI;
RefPtr<Scene_MainUi> sceneUI = new Scene_MainUi;
Game::GetInstance().ChangeUIScene(sceneUI);
}
}

View File

@@ -0,0 +1,72 @@
#include "Scene_MainUi.h"
#include "Asset/Squirrel/SquirrelManager.h"
void Scene_MainUi::Enter()
{
Scene::Enter();
HSQUIRRELVM v = SquirrelEx::GetInstance().GetSquirrelVM();
SQInteger top = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC("_MainUI_Enter_"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2)))
{
sq_pushroottable(v);
sq_pushuserpointer(v, this);
sq_call(v, 2, SQFalse, SQTrue);
}
sq_settop(v, top);
}
void Scene_MainUi::HandleEvents(SDL_Event *e)
{
Scene::HandleEvents(e);
HSQUIRRELVM v = SquirrelEx::GetInstance().GetSquirrelVM();
SQInteger top = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC("_MainUI_HandleEvents_"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2)))
{
sq_pushroottable(v);
sq_pushinteger(v, 1);
sq_call(v, 2, SQFalse, SQTrue);
}
sq_settop(v, top);
}
void Scene_MainUi::Update(float deltaTime)
{
Scene::Update(deltaTime);
HSQUIRRELVM v = SquirrelEx::GetInstance().GetSquirrelVM();
SQInteger top = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC("_MainUI_Update_"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2)))
{
sq_pushroottable(v);
sq_pushfloat(v, deltaTime);
sq_call(v, 2, SQFalse, SQTrue);
}
sq_settop(v, top);
}
void Scene_MainUi::Exit()
{
Scene::Exit();
HSQUIRRELVM v = SquirrelEx::GetInstance().GetSquirrelVM();
SQInteger top = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC("_MainUI_Exit_"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2)))
{
sq_pushroottable(v);
sq_call(v, 1, SQFalse, SQTrue);
}
sq_settop(v, top);
}
void Scene_MainUi::Render()
{
Scene::Render();
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "EngineFrame/Scene/Scene.h"
class Scene_MainUi : public Scene
{
private:
/* data */
public:
void Enter() override;
void HandleEvents(SDL_Event *e) override;
void Update(float deltaTime) override;
void Exit() override;
void Render() override;
};

View File

@@ -1,98 +0,0 @@
#pragma once
#include "EngineFrame/Scene/Scene.h"
#include "Asset/AssetManager.h"
#include "EngineFrame/Component/Animation.h"
#include "Actor/Map/GameMap.h"
#include "Actor/Map/GameMapCamera.h"
#include "Actor/Object/CharacterObject.h"
class Scene_SelectCharacter_UI : public Scene
{
private:
/* data */
GameMap *map;
RefPtr<GameMapCamera> camera = nullptr;
public:
Scene_SelectCharacter_UI(/* args */) {
};
~Scene_SelectCharacter_UI() {
};
public:
void Enter() override
{
map = new GameMap;
map->LoadMap("map/cataclysm/town/elvengard/new_elvengard.map");
map->Enter(this);
RefPtr<CharacterObject> obj = new CharacterObject();
obj->SetPosition({620, 200, 0});
// 构造为鬼剑士
obj->Construction(0);
map->AddObject(obj);
camera = new GameMapCamera;
camera->SetParentMap(map);
camera->SetFromActor(obj.Get());
AddChild(camera);
// RefPtr<Actor> actor = new Actor;
// actor->SetPos(VecFPos{450, 350});
// // actor->SetAnchor(VecFPos{0.5, 0.5});
// actor->SetScale(VecFPos{-1.f, 1.f});
// AddChild(actor);
// RefPtr<Actor> actor2 = new Actor;
// actor->AddChild(actor2);
// RefPtr<Animation> ani4 = new Animation("map/cataclysm/town/hendonmyre/animation/object/gateall_02.ani");
// // ani4->SetScale(VecFPos{-1.0, 1.0});
// actor2->AddChild(ani4);
// RefPtr<Animation> ani3 = new Animation("map/cataclysm/town/elvengard/animation/obj/serialight01_right.ani");
// ani3->SetPos(VecPos{300, 300});
// actor->AddChild(ani3);
// RefPtr<Animation> ani4 = new Animation("map/cataclysm/town/hendonmyre/animation/object/gateall_02.ani");
// ani4->SetPos(VecPos{300, 500});
// actor->AddChild(ani4);
// for (size_t i = 0; i < 400; i++)
// {
// 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<Sprite> sprite = new Sprite("sprite/item/avatar/swordman/0sm_acap.img", 0);
// actor->AddComponent(sprite);
// // RefPtr<Animation> ani2 = new Animation("common/anton/face/0/0.ani");
// // actor->AddComponent(ani2);
// // ani2->SetRenderZOrder(1000);
// }
// SDL_Log("进入了选择角色场景!");
};
void HandleEvents(SDL_Event *e) override
{
Scene::HandleEvents(e);
map->HandleEvents(e);
};
void Update(float deltaTime) override
{
Scene::Update(deltaTime);
map->Update(deltaTime);
};
// void Render() override;
// void Exit() override;
};

View File

@@ -1,6 +1,7 @@
#include "Scene_Test.h"
#include <memory>
#include <EngineCore/Game.h>
#include <EngineFrame/Component/AnimationManager.h>
Scene_Test::Scene_Test()
{
}
@@ -12,22 +13,108 @@ Scene_Test::~Scene_Test()
void Scene_Test::Enter()
{
SDL_Log("进入测试场景!");
map = new GameMap;
map->LoadMap("map/cataclysm/town/elvengard/new_elvengard.map");
map->Enter(this);
RefPtr<CharacterObject> obj = new CharacterObject();
obj->SetPosition({1000, 300, 0});
obj->Construction(0);
RefPtr<MonsterObject> monster = new MonsterObject();
monster->SetPosition({1200, 301, 0});
monster->Construction(1);
monster->SetDirection(1);
map->AddObject(obj);
map->AddObject(monster);
_camera = new GameMapCamera;
_camera->SetFromActor(obj.Get());
return;
// SDL_Log("Scene_Test::进入测试场景!");
RefPtr<Actor> actor = new Actor;
AddChild(actor);
// RefPtr<Sprite> sprite = new Sprite("ImagePacks2/test_white_background.png");
// actor->AddComponent(sprite);
// RefPtr<Sprite> chr = new Sprite("sprite/character/swordman/equipment/avatar/skin/sm_body0000.img", 90);
// chr->SetPos(VecFPos{200, 100});
// chr->SetAlpha(0.5);
// chr->SetShadow();
// actor->AddComponent(chr);
RefPtr<AnimationManager> Am = new AnimationManager;
RefPtr<Animation> ani4 = new Animation("map/cataclysm/town/hendonmyre/animation/object/gateall_02.ani");
Am->AddAnimation(ani4);
// Am->SetPos(VecFPos{200, 100});
actor->AddChild(Am);
// // sprite2->UnsetClipRect();
// RefPtr<Actor> actor2 = new Actor;
// actor->AddChild(actor2);
// RefPtr<Animation> ani4 = new Animation("map/cataclysm/town/hendonmyre/animation/object/gateall_02.ani");
// // ani4->SetScale(VecFPos{-1.0, 1.0});
// actor->AddChild(ani4);
// RefPtr<Animation> ani3 = new Animation("map/cataclysm/town/elvengard/animation/obj/serialight01_right.ani");
// actor->AddChild(ani3);
// RefPtr<Animation> ani4 = new Animation("map/cataclysm/town/hendonmyre/animation/object/gateall_02.ani");
// ani4->SetPos(VecPos{300, 500});
// actor->AddChild(ani4);
// for (size_t i = 0; i < 400; i++)
// {
// 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<Sprite> sprite = new Sprite("sprite/item/avatar/swordman/0sm_acap.img", 0);
// actor->AddComponent(sprite);
// // RefPtr<Animation> ani2 = new Animation("common/anton/face/0/0.ani");
// // actor->AddComponent(ani2);
// // ani2->SetRenderZOrder(1000);
// }
}
void Scene_Test::HandleEvents(SDL_Event *e)
{
Scene::HandleEvents(e);
}
void Scene_Test::Update(float deltaTime)
{
Scene::Update(deltaTime);
// 摄像机中有检测宿主坐标 所以要在场景的update后调用以便读取到本帧最新的坐标
if (_camera)
_camera->Update(deltaTime);
if (map)
map->Update(deltaTime);
}
void Scene_Test::Render()
{
Scene::Render();
}
void Scene_Test::Exit()
{
SDL_Log("Scene_Test::退出测试场景!当前引用计数%d", this->GetRefCount());
}
RefPtr<BaseNode> Scene_Test::GetCamera()
{
return this->_camera;
}

View File

@@ -1,10 +1,18 @@
#pragma once
#include "EngineFrame/Scene/Scene.h"
#include "Asset/AssetManager.h"
#include "EngineFrame/Component/Animation.h"
#include "Actor/Map/GameMap.h"
#include "Actor/Map/GameMapCamera.h"
#include "Actor/Object/CharacterObject.h"
#include "Actor/Object/MonsterObject.h"
class Scene_Test : public Scene
{
private:
/* data */
GameMap *map = nullptr;
RefPtr<GameMapCamera> _camera = nullptr;
public:
Scene_Test(/* args */);
~Scene_Test();
@@ -15,7 +23,8 @@ public:
void Update(float deltaTime) override;
void Render() override;
void Exit() override;
RefPtr<BaseNode> GetCamera() override;
public:
int MyId = 0;
};