修改渲染底层,新增场景摄像机逻辑,地图可行区域逻辑
This commit is contained in:
@@ -291,6 +291,24 @@ void GameMap::InitMapAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
void GameMap::InitVirtualMovableArea()
|
||||
{
|
||||
std::vector<int> Info = std::get<std::vector<int>>(_MapInfo["virtual_movable_area"]);
|
||||
if (Info.size() > 0)
|
||||
{
|
||||
for (int i = 0; i < Info.size(); i += 4)
|
||||
{
|
||||
float x = Info[i];
|
||||
float y = Info[i + 1];
|
||||
float w = Info[i + 2];
|
||||
float h = Info[i + 3];
|
||||
if (_DebugMode)
|
||||
_LayerMap["max"]->AddDebugFeasibleAreaInfo(VecFPos(x, y), VecSize(w, h));
|
||||
_MovableArea.push_back(SDL_FRect{x, y, w, h});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameMap::LoadMap(std::string mapName)
|
||||
{
|
||||
// 读取脚本配置
|
||||
@@ -301,11 +319,8 @@ void GameMap::LoadMap(std::string mapName)
|
||||
InitBackgroundAnimation();
|
||||
// 初始化场景Ani
|
||||
InitMapAnimation();
|
||||
|
||||
RefPtr<CharacterObject> obj = new CharacterObject();
|
||||
obj->SetPosition({620, 200, 0});
|
||||
obj->Construction(0);
|
||||
_LayerMap["normal"]->AddObject(obj);
|
||||
// 初始化可行区域
|
||||
InitVirtualMovableArea();
|
||||
}
|
||||
|
||||
void GameMap::Enter(Scene *scene)
|
||||
@@ -321,7 +336,7 @@ void GameMap::Enter(Scene *scene)
|
||||
scene->AddChild(_LayerMap["max"]);
|
||||
|
||||
// TODO
|
||||
int HSU = 230;
|
||||
int HSU = 0;
|
||||
_LayerMap["contact"]->SetPos(VecFPos{0, HSU});
|
||||
_LayerMap["distantback"]->SetPos(VecFPos{0, HSU});
|
||||
_LayerMap["middleback"]->SetPos(VecFPos{0, HSU});
|
||||
@@ -367,3 +382,67 @@ void GameMap::Update(float deltaTime)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void GameMap::AddObject(RefPtr<BaseObject> object)
|
||||
{
|
||||
object->_AffMap = this;
|
||||
_LayerMap["normal"]->AddObject(object);
|
||||
}
|
||||
|
||||
VecFPos3 GameMap::CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset)
|
||||
{
|
||||
// 初始化结果为原坐标(默认不移动)
|
||||
VecFPos3 result = CurPos;
|
||||
|
||||
// 如果没有可移动区域限制,直接全量位移
|
||||
if (_MovableArea.empty())
|
||||
{
|
||||
result.x += PosOffset.x;
|
||||
result.y += PosOffset.y;
|
||||
result.z += PosOffset.z; // Z轴不受限
|
||||
return result;
|
||||
}
|
||||
|
||||
// 计算X轴单独位移后的目标位置
|
||||
float targetX = CurPos.x + PosOffset.x;
|
||||
// 计算Y轴单独位移后的目标位置
|
||||
float targetY = CurPos.y + PosOffset.y;
|
||||
|
||||
// 检查X轴位移是否合法(固定Y为当前值,仅移动X)
|
||||
SDL_FPoint xTestPoint{targetX, CurPos.y};
|
||||
bool isXValid = false;
|
||||
for (auto &area : _MovableArea)
|
||||
{
|
||||
if (SDL_PointInFRect(&xTestPoint, &area))
|
||||
{
|
||||
isXValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查Y轴位移是否合法(固定X为当前值,仅移动Y)
|
||||
SDL_FPoint yTestPoint{CurPos.x, targetY};
|
||||
bool isYValid = false;
|
||||
for (auto &area : _MovableArea)
|
||||
{
|
||||
if (SDL_PointInFRect(&yTestPoint, &area))
|
||||
{
|
||||
isYValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 应用合法的位移
|
||||
if (isXValid)
|
||||
{
|
||||
result.x = targetX; // X轴允许移动
|
||||
}
|
||||
if (isYValid)
|
||||
{
|
||||
result.y = targetY; // Y轴允许移动
|
||||
}
|
||||
// Z轴不受限制,直接应用位移
|
||||
result.z += PosOffset.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -62,6 +62,10 @@ public:
|
||||
int _MapLength = 0;
|
||||
// 地图高度
|
||||
int _MapHeight = 0;
|
||||
// 可行区域
|
||||
std::vector<SDL_FRect> _MovableArea;
|
||||
// 调试模式
|
||||
bool _DebugMode = true;
|
||||
|
||||
public:
|
||||
// 图层Map 图层类型 显示对象
|
||||
@@ -79,9 +83,13 @@ public:
|
||||
void InitTile();
|
||||
void InitBackgroundAnimation();
|
||||
void InitMapAnimation();
|
||||
void InitVirtualMovableArea();
|
||||
void Enter(Scene *scene);
|
||||
void HandleEvents(SDL_Event *e);
|
||||
void Update(float deltaTime);
|
||||
void AddObject(RefPtr<BaseObject> object);
|
||||
|
||||
public:
|
||||
// 检查是否可移动
|
||||
VecFPos3 CheckIsItMovable(VecFPos3 CurPos, VecFPos3 PosOffset);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "GameMapCamera.h"
|
||||
#include "EngineCore/Game.h"
|
||||
#include "Actor/Map/GameMap.h"
|
||||
#include "Actor/Object/BaseObject.h"
|
||||
#include <algorithm>
|
||||
@@ -45,10 +46,23 @@ void GameMapCamera::SyncPosByFromParent(float deltaTime)
|
||||
{
|
||||
if (this->_FromActor != nullptr)
|
||||
{
|
||||
// int R_X, R_Y, R_Z;
|
||||
// R_X = std::min(std::max(this->_FromActor->X, 533), MovableAreaX - 533);
|
||||
// R_Y = std::min(std::max(this->_FromActor->Y, 300), MovableAreaY - 300);
|
||||
// R_Z = 0;
|
||||
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);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
// 背景偏移量
|
||||
int BackgroundOffset = 0;
|
||||
// 背景层移动速率
|
||||
int BackgroundMoveSpeed = 1.0;
|
||||
int BackgroundMoveSpeed = 1.03;
|
||||
// 人物中线长度
|
||||
int CharacterLineLength = 0;
|
||||
// 摄像机朝向
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "GameMapLayer.h"
|
||||
#include "EngineCore/Game.h"
|
||||
|
||||
GameMapLayer::GameMapLayer()
|
||||
{
|
||||
@@ -8,6 +9,37 @@ GameMapLayer::~GameMapLayer()
|
||||
{
|
||||
}
|
||||
|
||||
void GameMapLayer::Render()
|
||||
{
|
||||
Actor::Render();
|
||||
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
|
||||
// 设置绘制颜色
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 128);
|
||||
// 自身坐标
|
||||
float Xpos = GetIterationPos().x + GetPos().x;
|
||||
float Ypos = GetIterationPos().y + GetPos().y;
|
||||
for (auto &info : this->FeasibleAreaInfoList)
|
||||
{
|
||||
SDL_Rect buf;
|
||||
buf.x = info.x + Xpos;
|
||||
buf.y = info.y + Ypos;
|
||||
buf.w = info.w;
|
||||
buf.h = info.h;
|
||||
// 绘制填充矩形
|
||||
SDL_RenderFillRect(renderer, &buf);
|
||||
}
|
||||
}
|
||||
|
||||
void GameMapLayer::AddDebugFeasibleAreaInfo(VecFPos pos, VecSize size)
|
||||
{
|
||||
SDL_Rect info;
|
||||
info.x = pos.x;
|
||||
info.y = pos.y;
|
||||
info.w = size.width;
|
||||
info.h = size.height;
|
||||
this->FeasibleAreaInfoList.push_back(info);
|
||||
}
|
||||
|
||||
void GameMapLayer::AddObject(RefPtr<Actor> obj)
|
||||
{
|
||||
this->AddChild(obj);
|
||||
|
||||
@@ -9,11 +9,18 @@ class GameMapLayer : public Actor
|
||||
private:
|
||||
// 地图对象
|
||||
std::vector<RefPtr<Component>> ObjectManager;
|
||||
// 可行区域信息
|
||||
std::vector<SDL_Rect> FeasibleAreaInfoList;
|
||||
|
||||
public:
|
||||
GameMapLayer(/* args */);
|
||||
~GameMapLayer();
|
||||
|
||||
// 重载Render以实现绘制可行区域
|
||||
void Render() override;
|
||||
// 添加调试可行区域信息
|
||||
void AddDebugFeasibleAreaInfo(VecFPos pos, VecSize size);
|
||||
|
||||
public:
|
||||
void AddObject(RefPtr<Actor> obj); // 添加对象
|
||||
};
|
||||
|
||||
@@ -45,6 +45,6 @@ void ActiveObject::Update(float deltaTime)
|
||||
SetPosition(Position);
|
||||
SDL_LogError(0, "修正Z轴");
|
||||
}
|
||||
// 执行父对象的更新
|
||||
// 执行父类的更新
|
||||
BaseObject::Update(deltaTime);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "BaseObject.h"
|
||||
|
||||
#include "Actor/Map/GameMap.h"
|
||||
BaseObject::BaseObject()
|
||||
{
|
||||
Init(); // 调用了RenderBase的Init函数 对象才会被执行回调
|
||||
@@ -12,6 +12,10 @@ BaseObject::~BaseObject()
|
||||
|
||||
void BaseObject::SetPosition(VecFPos3 pos)
|
||||
{
|
||||
if (pos.y != this->Position.y)
|
||||
{
|
||||
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
|
||||
}
|
||||
this->Position = pos;
|
||||
Actor::SetPos(VecFPos{this->Position.x, this->Position.y - this->Position.z});
|
||||
}
|
||||
@@ -29,6 +33,10 @@ void BaseObject::SetXpos(float x)
|
||||
|
||||
void BaseObject::SetYpos(float y)
|
||||
{
|
||||
if (y != this->Position.y)
|
||||
{
|
||||
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
|
||||
}
|
||||
this->Position.y = y;
|
||||
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
|
||||
}
|
||||
@@ -56,17 +64,25 @@ int BaseObject::GetZpos()
|
||||
|
||||
void BaseObject::MoveBy(VecFPos3 pos)
|
||||
{
|
||||
this->Position.x += pos.x;
|
||||
this->Position.y += pos.y;
|
||||
this->Position.z += pos.z;
|
||||
// 只有moveby移动时判断所在地图中是否能够这样移动
|
||||
VecFPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), pos);
|
||||
if (pos.y != 0)
|
||||
{
|
||||
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
|
||||
}
|
||||
this->Position = RealPos;
|
||||
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
|
||||
}
|
||||
|
||||
void BaseObject::MoveBy(float x, float y, float z)
|
||||
{
|
||||
this->Position.x += x;
|
||||
this->Position.y += y;
|
||||
this->Position.z += z;
|
||||
// 只有moveby移动时判断所在地图中是否能够这样移动
|
||||
VecFPos3 RealPos = this->_AffMap->CheckIsItMovable(GetPosition(), VecFPos3({x, y, z}));
|
||||
if (y != 0)
|
||||
{
|
||||
SetRenderZOrder((int)(this->Position.y)); // 设置渲染顺序
|
||||
}
|
||||
this->Position = RealPos;
|
||||
Actor::SetPos({this->Position.x, this->Position.y - this->Position.z});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
#include "Asset/Common/ObjectVars.h"
|
||||
class GameMap;
|
||||
class BaseObject : public Actor
|
||||
{
|
||||
private:
|
||||
@@ -8,6 +9,7 @@ private:
|
||||
public:
|
||||
VecFPos3 Position; // 位置
|
||||
int Direction = 0; // 方向
|
||||
GameMap *_AffMap = nullptr; // 所在地图
|
||||
|
||||
public:
|
||||
BaseObject(/* args */);
|
||||
|
||||
@@ -115,6 +115,71 @@ void Chr_Controller::HandleEvents(SDL_Event *e)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
switch (e->key.keysym.sym)
|
||||
{
|
||||
case SDLK_UP: // 上方向键
|
||||
LeftStick.y = -1.0f;
|
||||
break;
|
||||
case SDLK_DOWN: // 下方向键
|
||||
LeftStick.y = 1.0f;
|
||||
break;
|
||||
case SDLK_LEFT: // 左方向键
|
||||
LeftStick.x = -1.0f;
|
||||
break;
|
||||
case SDLK_RIGHT: // 右方向键
|
||||
LeftStick.x = 1.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// 如果父对象存在 调用父对象的消息处理
|
||||
if (m_pCharacter)
|
||||
{
|
||||
m_pCharacter->ControllerMsg(CONTROLLER_MSG_TYPE::CONTROLLER_MSG_TYPE_LEFT_JOYSTICK_MOVE, &LeftStick);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
switch (e->key.keysym.sym)
|
||||
{
|
||||
case SDLK_UP: // 上方向键
|
||||
{
|
||||
if (LeftStick.y < 0.f)
|
||||
LeftStick.y = 0.f;
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN: // 下方向键
|
||||
{
|
||||
if (LeftStick.y > 0.f)
|
||||
LeftStick.y = 0.f;
|
||||
break;
|
||||
}
|
||||
case SDLK_LEFT: // 左方向键
|
||||
{
|
||||
if (LeftStick.x < 0.f)
|
||||
LeftStick.x = 0.f;
|
||||
break;
|
||||
}
|
||||
case SDLK_RIGHT: // 右方向键
|
||||
{
|
||||
if (LeftStick.x > 0.f)
|
||||
LeftStick.x = 0.f;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// 如果父对象存在 调用父对象的消息处理
|
||||
if (m_pCharacter)
|
||||
{
|
||||
m_pCharacter->ControllerMsg(CONTROLLER_MSG_TYPE::CONTROLLER_MSG_TYPE_LEFT_JOYSTICK_MOVE, &LeftStick);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// 可以处理其他类型的事件或忽略
|
||||
break;
|
||||
|
||||
@@ -10,7 +10,8 @@ Global_Game::~Global_Game()
|
||||
void Global_Game::Init()
|
||||
{
|
||||
// 初始化ttf字体资源
|
||||
TTF_Font *FontBuf = TTF_OpenFont("Fonts/LXGWWenKai-Regular.ttf", 24);
|
||||
// TTF_Font *FontBuf = TTF_OpenFont("Fonts/LXGWWenKai-Regular.ttf", 24);
|
||||
TTF_Font *FontBuf = TTF_OpenFont("Fonts/VonwaonBitmap-12px.ttf", 24);
|
||||
// TTF_Font *FontBuf = TTF_OpenFont("Fonts/Gothica-Book.ttf", 24);
|
||||
// TTF_Font *FontBuf = TTF_OpenFont("Fonts/Gasinamu.ttf", 24);
|
||||
if (!FontBuf)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#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:
|
||||
@@ -26,21 +27,30 @@ public:
|
||||
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);
|
||||
return;
|
||||
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<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<Animation> ani4 = new Animation("map/cataclysm/town/hendonmyre/animation/object/gateall_02.ani");
|
||||
// ani4->SetScale(VecFPos{-1.0, 1.0});
|
||||
actor2->AddChild(ani4);
|
||||
// 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});
|
||||
|
||||
Reference in New Issue
Block a user