feat(地图系统): 增强移动区域调试功能
- 添加移动区域边界结构体MoveAreaBounds并集成到地图配置中 - 实现移动区域索引查找和高亮显示功能 - 增加可移动区域检查开关movableAreaCheckEnabled - 优化调试信息显示,包括坐标和当前所在移动区域 - 重构移动区域相关代码,提高可维护性
This commit is contained in:
@@ -41,6 +41,11 @@ struct MoveAreaTarget {
|
|||||||
int area = -2;
|
int area = -2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MoveAreaBounds {
|
||||||
|
Vec2 leftTop = Vec2::Zero();
|
||||||
|
Vec2 rightBottom = Vec2::Zero();
|
||||||
|
};
|
||||||
|
|
||||||
struct TileInfo {
|
struct TileInfo {
|
||||||
std::string spritePath;
|
std::string spritePath;
|
||||||
int spriteIndex = 0;
|
int spriteIndex = 0;
|
||||||
@@ -65,6 +70,7 @@ struct MapConfig {
|
|||||||
std::vector<std::string> soundIds;
|
std::vector<std::string> soundIds;
|
||||||
std::vector<Vec2> virtualMovablePolygon;
|
std::vector<Vec2> virtualMovablePolygon;
|
||||||
std::vector<Rect> townMovableAreas;
|
std::vector<Rect> townMovableAreas;
|
||||||
|
std::vector<MoveAreaBounds> townMovableAreaBounds;
|
||||||
std::vector<MoveAreaTarget> townMovableAreaTargets;
|
std::vector<MoveAreaTarget> townMovableAreaTargets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace frostbite2D {
|
|||||||
*/
|
*/
|
||||||
class GameMap : public Actor {
|
class GameMap : public Actor {
|
||||||
public:
|
public:
|
||||||
|
static constexpr size_t kInvalidMoveAreaIndex = static_cast<size_t>(-1);
|
||||||
using MapMoveArea = game::MoveAreaTarget;
|
using MapMoveArea = game::MoveAreaTarget;
|
||||||
|
|
||||||
GameMap();
|
GameMap();
|
||||||
@@ -45,11 +46,16 @@ public:
|
|||||||
/// 检查当前位置是否进入 town move area,用于切图/传送判定。
|
/// 检查当前位置是否进入 town move area,用于切图/传送判定。
|
||||||
MapMoveArea CheckIsItMoveArea(const Vec3& curPos) const;
|
MapMoveArea CheckIsItMoveArea(const Vec3& curPos) const;
|
||||||
bool TryGetMoveAreaTarget(const Vec3& curPos, MapMoveArea& outTarget) const;
|
bool TryGetMoveAreaTarget(const Vec3& curPos, MapMoveArea& outTarget) const;
|
||||||
|
size_t FindMoveAreaIndex(const Vec3& curPos) const;
|
||||||
const std::vector<MapMoveArea>& GetMoveAreaInfo() const;
|
const std::vector<MapMoveArea>& GetMoveAreaInfo() const;
|
||||||
|
size_t GetMoveAreaCount() const { return moveArea_.size(); }
|
||||||
Rect GetMovablePositionArea(size_t index) const;
|
Rect GetMovablePositionArea(size_t index) const;
|
||||||
|
const std::string& GetMapPath() const { return mapConfig_.mapPath; }
|
||||||
|
void SetDebugHighlightedMoveAreaIndex(size_t index);
|
||||||
|
|
||||||
int GetBackgroundRepeatWidth() const { return backgroundRepeatWidth_; }
|
int GetBackgroundRepeatWidth() const { return backgroundRepeatWidth_; }
|
||||||
bool IsDebugModeEnabled() const { return debugMode_; }
|
bool IsDebugModeEnabled() const { return debugMode_; }
|
||||||
|
bool IsMovableAreaCheckEnabled() const { return movableAreaCheckEnabled_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// 初始化固定图层。图层名字与 DNF 地图层概念保持一致。
|
/// 初始化固定图层。图层名字与 DNF 地图层概念保持一致。
|
||||||
@@ -84,6 +90,8 @@ private:
|
|||||||
/// 地图配置里的整体 Y 偏移;既影响层位置,也影响地板校准。
|
/// 地图配置里的整体 Y 偏移;既影响层位置,也影响地板校准。
|
||||||
int mapOffsetY_ = 0;
|
int mapOffsetY_ = 0;
|
||||||
bool debugMode_ = true;
|
bool debugMode_ = true;
|
||||||
|
/// 硬编码调试开关:关闭后忽略可行走区域检测,允许角色自由移动。
|
||||||
|
bool movableAreaCheckEnabled_ = false;
|
||||||
/// 当前地图正在播放的背景音乐。
|
/// 当前地图正在播放的背景音乐。
|
||||||
Ptr<Music> currentMusic_;
|
Ptr<Music> currentMusic_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,17 +7,26 @@ namespace frostbite2D {
|
|||||||
|
|
||||||
class GameMapLayer : public Actor {
|
class GameMapLayer : public Actor {
|
||||||
public:
|
public:
|
||||||
|
static constexpr size_t kInvalidMoveAreaIndex = static_cast<size_t>(-1);
|
||||||
|
|
||||||
void Render() override;
|
void Render() override;
|
||||||
|
|
||||||
void SetDebugFeasibleAreaPolygon(const std::vector<Vec2>& polygon);
|
void SetDebugFeasibleAreaPolygon(const std::vector<Vec2>& polygon);
|
||||||
void AddDebugMoveAreaInfo(const Rect& rect);
|
void AddDebugMoveAreaInfo(const Rect& rect, size_t index);
|
||||||
|
void SetDebugHighlightedMoveAreaIndex(size_t index);
|
||||||
void ClearDebugAreaInfo();
|
void ClearDebugAreaInfo();
|
||||||
void AddObject(RefPtr<Actor> obj);
|
void AddObject(RefPtr<Actor> obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct DebugMoveAreaInfo {
|
||||||
|
Rect rect;
|
||||||
|
size_t index = kInvalidMoveAreaIndex;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<Vec2> feasibleAreaPolygon_;
|
std::vector<Vec2> feasibleAreaPolygon_;
|
||||||
std::vector<Rect> feasibleAreaFillRects_;
|
std::vector<Rect> feasibleAreaFillRects_;
|
||||||
std::vector<Rect> moveAreaInfoList_;
|
std::vector<DebugMoveAreaInfo> moveAreaInfoList_;
|
||||||
|
size_t highlightedMoveAreaIndex_ = kInvalidMoveAreaIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace frostbite2D
|
} // namespace frostbite2D
|
||||||
|
|||||||
@@ -17,6 +17,17 @@ constexpr float kDebugHudPaddingX = 8.0f;
|
|||||||
constexpr float kDebugHudPaddingY = 6.0f;
|
constexpr float kDebugHudPaddingY = 6.0f;
|
||||||
constexpr char kDebugHudPopupImg[] = "sprite/interface/newstyle/windows/popup/popup.img";
|
constexpr char kDebugHudPopupImg[] = "sprite/interface/newstyle/windows/popup/popup.img";
|
||||||
|
|
||||||
|
void ConfigureTextLine(RefPtr<TextSprite> textSprite, const char* name,
|
||||||
|
int zOrder) {
|
||||||
|
if (!textSprite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
textSprite->SetName(name);
|
||||||
|
textSprite->SetFont("default");
|
||||||
|
textSprite->SetTextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
textSprite->SetZOrder(zOrder);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
GameDebugActor::GameDebugActor() {
|
GameDebugActor::GameDebugActor() {
|
||||||
@@ -64,6 +75,9 @@ void GameDebugActor::DetachFromParent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameDebugActor::SetDebugMap(GameMap* map) {
|
void GameDebugActor::SetDebugMap(GameMap* map) {
|
||||||
|
if (debugMap_ && debugMap_ != map) {
|
||||||
|
debugMap_->SetDebugHighlightedMoveAreaIndex(GameMap::kInvalidMoveAreaIndex);
|
||||||
|
}
|
||||||
debugMap_ = map;
|
debugMap_ = map;
|
||||||
updateOverlay();
|
updateOverlay();
|
||||||
}
|
}
|
||||||
@@ -74,6 +88,9 @@ void GameDebugActor::SetTrackedCharacter(CharacterObject* character) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameDebugActor::ClearDebugContext() {
|
void GameDebugActor::ClearDebugContext() {
|
||||||
|
if (debugMap_) {
|
||||||
|
debugMap_->SetDebugHighlightedMoveAreaIndex(GameMap::kInvalidMoveAreaIndex);
|
||||||
|
}
|
||||||
debugMap_ = nullptr;
|
debugMap_ = nullptr;
|
||||||
trackedCharacter_ = nullptr;
|
trackedCharacter_ = nullptr;
|
||||||
setOverlayVisible(false);
|
setOverlayVisible(false);
|
||||||
@@ -100,10 +117,7 @@ void GameDebugActor::initOverlay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
coordText_ = TextSprite::create();
|
coordText_ = TextSprite::create();
|
||||||
coordText_->SetName("debugCoordText");
|
ConfigureTextLine(coordText_, "debugCoordText", 1);
|
||||||
coordText_->SetFont("default");
|
|
||||||
coordText_->SetTextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
coordText_->SetZOrder(1);
|
|
||||||
AddChild(coordText_);
|
AddChild(coordText_);
|
||||||
|
|
||||||
setOverlayVisible(false);
|
setOverlayVisible(false);
|
||||||
@@ -112,19 +126,29 @@ void GameDebugActor::initOverlay() {
|
|||||||
void GameDebugActor::updateOverlay() {
|
void GameDebugActor::updateOverlay() {
|
||||||
if (!coordText_ || !debugMap_ || !trackedCharacter_ ||
|
if (!coordText_ || !debugMap_ || !trackedCharacter_ ||
|
||||||
!debugMap_->IsDebugModeEnabled()) {
|
!debugMap_->IsDebugModeEnabled()) {
|
||||||
|
if (debugMap_) {
|
||||||
|
debugMap_->SetDebugHighlightedMoveAreaIndex(GameMap::kInvalidMoveAreaIndex);
|
||||||
|
}
|
||||||
setOverlayVisible(false);
|
setOverlayVisible(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CharacterWorldPosition& worldPosition = trackedCharacter_->GetWorldPosition();
|
const CharacterWorldPosition& worldPosition = trackedCharacter_->GetWorldPosition();
|
||||||
char textBuffer[64];
|
Vec3 currentWorldPos(static_cast<float>(worldPosition.x),
|
||||||
SDL_snprintf(textBuffer, sizeof(textBuffer), "角色坐标: (%d, %d, %d)",
|
static_cast<float>(worldPosition.y),
|
||||||
worldPosition.x, worldPosition.y, worldPosition.z);
|
static_cast<float>(worldPosition.z));
|
||||||
coordText_->SetText(textBuffer);
|
size_t moveAreaIndex = debugMap_->FindMoveAreaIndex(currentWorldPos);
|
||||||
|
debugMap_->SetDebugHighlightedMoveAreaIndex(moveAreaIndex);
|
||||||
|
|
||||||
Vec2 textSize = coordText_->GetTextSize();
|
char coordTextBuffer[96];
|
||||||
Vec2 panelSize(textSize.x + kDebugHudPaddingX * 2.0f,
|
SDL_snprintf(coordTextBuffer, sizeof(coordTextBuffer), "角色坐标: (%d, %d, %d)",
|
||||||
textSize.y + kDebugHudPaddingY * 2.0f);
|
worldPosition.x, worldPosition.y, worldPosition.z);
|
||||||
|
coordText_->SetText(coordTextBuffer);
|
||||||
|
|
||||||
|
Vec2 coordTextSize = coordText_->GetTextSize();
|
||||||
|
float panelWidth = coordTextSize.x + kDebugHudPaddingX * 2.0f;
|
||||||
|
float panelHeight = coordTextSize.y + kDebugHudPaddingY * 2.0f;
|
||||||
|
Vec2 panelSize(panelWidth, panelHeight);
|
||||||
if (background_) {
|
if (background_) {
|
||||||
background_->SetSize(panelSize);
|
background_->SetSize(panelSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,21 @@ int toInt(const std::string& value, int fallback = 0) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoveAreaBounds normalizeMoveAreaBounds(int x1, int y1, int x2, int y2) {
|
||||||
|
MoveAreaBounds bounds;
|
||||||
|
bounds.leftTop.x = static_cast<float>(std::min(x1, x2));
|
||||||
|
bounds.leftTop.y = static_cast<float>(std::min(y1, y2));
|
||||||
|
bounds.rightBottom.x = static_cast<float>(std::max(x1, x2));
|
||||||
|
bounds.rightBottom.y = static_cast<float>(std::max(y1, y2));
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect makeMoveAreaRect(const MoveAreaBounds& bounds) {
|
||||||
|
return Rect(bounds.leftTop.x, bounds.leftTop.y,
|
||||||
|
bounds.rightBottom.x - bounds.leftTop.x,
|
||||||
|
bounds.rightBottom.y - bounds.leftTop.y);
|
||||||
|
}
|
||||||
|
|
||||||
bool readScript(const std::string& path, ScriptTokenStream& outStream) {
|
bool readScript(const std::string& path, ScriptTokenStream& outStream) {
|
||||||
(void)path;
|
(void)path;
|
||||||
return outStream.isValid();
|
return outStream.isValid();
|
||||||
@@ -257,14 +272,18 @@ bool loadMapConfig(const std::string& mapPath, MapConfig& outConfig) {
|
|||||||
if (token == "[/town movable area]") {
|
if (token == "[/town movable area]") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Rect rect(static_cast<float>(toInt(token)),
|
int leftTopX = toInt(token);
|
||||||
static_cast<float>(toInt(stream.get())),
|
int leftTopY = toInt(stream.get());
|
||||||
static_cast<float>(toInt(stream.get())),
|
int rightBottomX = toInt(stream.get());
|
||||||
static_cast<float>(toInt(stream.get())));
|
int rightBottomY = toInt(stream.get());
|
||||||
|
MoveAreaBounds bounds = normalizeMoveAreaBounds(
|
||||||
|
leftTopX, leftTopY, rightBottomX, rightBottomY);
|
||||||
|
Rect rect = makeMoveAreaRect(bounds);
|
||||||
MoveAreaTarget target;
|
MoveAreaTarget target;
|
||||||
target.town = toInt(stream.get(), -2);
|
target.town = toInt(stream.get(), -2);
|
||||||
target.area = toInt(stream.get(), -2);
|
target.area = toInt(stream.get(), -2);
|
||||||
outConfig.townMovableAreas.push_back(rect);
|
outConfig.townMovableAreas.push_back(rect);
|
||||||
|
outConfig.townMovableAreaBounds.push_back(bounds);
|
||||||
outConfig.townMovableAreaTargets.push_back(target);
|
outConfig.townMovableAreaTargets.push_back(target);
|
||||||
}
|
}
|
||||||
} else if (segment == "[virtual movable area]") {
|
} else if (segment == "[virtual movable area]") {
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ void GameMap::clearLayerChildren() {
|
|||||||
moveArea_.clear();
|
moveArea_.clear();
|
||||||
currentMusic_.Reset();
|
currentMusic_.Reset();
|
||||||
backgroundRepeatWidth_ = 0;
|
backgroundRepeatWidth_ = 0;
|
||||||
|
SetDebugHighlightedMoveAreaIndex(kInvalidMoveAreaIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameMap::LoadMap(const std::string &mapName) {
|
bool GameMap::LoadMap(const std::string &mapName) {
|
||||||
@@ -321,19 +322,10 @@ void GameMap::InitVirtualMovableArea() {
|
|||||||
if (movablePolygon_.empty()) {
|
if (movablePolygon_.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!movableAreaCheckEnabled_) {
|
||||||
float minX = movablePolygon_.front().x;
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
float minY = movablePolygon_.front().y;
|
"GameMap: movable area check disabled, allowing free movement");
|
||||||
float maxX = movablePolygon_.front().x;
|
|
||||||
float maxY = movablePolygon_.front().y;
|
|
||||||
for (const auto& point : movablePolygon_) {
|
|
||||||
minX = std::min(minX, point.x);
|
|
||||||
minY = std::min(minY, point.y);
|
|
||||||
maxX = std::max(maxX, point.x);
|
|
||||||
maxY = std::max(maxY, point.y);
|
|
||||||
}
|
}
|
||||||
SDL_Log("GameMap: movable polygon vertices=%zu bounds=(%.0f, %.0f)-(%.0f, %.0f)",
|
|
||||||
movablePolygon_.size(), minX, minY, maxX, maxY);
|
|
||||||
|
|
||||||
if (!debugMode_) {
|
if (!debugMode_) {
|
||||||
return;
|
return;
|
||||||
@@ -357,8 +349,10 @@ void GameMap::InitMoveArea() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& rect : moveArea_) {
|
for (size_t i = 0;
|
||||||
layerIt->second->AddDebugMoveAreaInfo(rect);
|
i < moveArea_.size() && i < mapConfig_.townMovableAreaTargets.size();
|
||||||
|
++i) {
|
||||||
|
layerIt->second->AddDebugMoveAreaInfo(moveArea_[i], i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,6 +454,9 @@ Vec3 GameMap::CheckIsItMovable(const Vec3& curPos, const Vec3& posOffset) const
|
|||||||
int targetY = RoundWorldCoordinate(curPos.y + posOffset.y);
|
int targetY = RoundWorldCoordinate(curPos.y + posOffset.y);
|
||||||
int targetZ = RoundWorldCoordinate(curPos.z + posOffset.z);
|
int targetZ = RoundWorldCoordinate(curPos.z + posOffset.z);
|
||||||
Vec3 result = MakeIntegerWorldPosition(currentX, currentY, targetZ);
|
Vec3 result = MakeIntegerWorldPosition(currentX, currentY, targetZ);
|
||||||
|
if (!movableAreaCheckEnabled_) {
|
||||||
|
return MakeIntegerWorldPosition(targetX, targetY, targetZ);
|
||||||
|
}
|
||||||
if (movablePolygon_.size() < 3) {
|
if (movablePolygon_.size() < 3) {
|
||||||
return MakeIntegerWorldPosition(targetX, targetY, targetZ);
|
return MakeIntegerWorldPosition(targetX, targetY, targetZ);
|
||||||
}
|
}
|
||||||
@@ -502,19 +499,37 @@ GameMap::MapMoveArea GameMap::CheckIsItMoveArea(const Vec3& curPos) const {
|
|||||||
return MapMoveArea();
|
return MapMoveArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameMap::TryGetMoveAreaTarget(const Vec3& curPos, MapMoveArea& outTarget) const {
|
size_t GameMap::FindMoveAreaIndex(const Vec3& curPos) const {
|
||||||
// moveArea_ and townMovableAreaTargets share the same index mapping.
|
|
||||||
int currentX = RoundWorldCoordinate(curPos.x);
|
int currentX = RoundWorldCoordinate(curPos.x);
|
||||||
int currentY = RoundWorldCoordinate(curPos.y);
|
int currentY = RoundWorldCoordinate(curPos.y);
|
||||||
for (size_t i = 0; i < moveArea_.size() && i < mapConfig_.townMovableAreaTargets.size(); ++i) {
|
for (size_t i = 0;
|
||||||
|
i < moveArea_.size() && i < mapConfig_.townMovableAreaTargets.size();
|
||||||
|
++i) {
|
||||||
if (moveArea_[i].containsPoint(MakeIntegerWorldPoint(currentX, currentY))) {
|
if (moveArea_[i].containsPoint(MakeIntegerWorldPoint(currentX, currentY))) {
|
||||||
outTarget = mapConfig_.townMovableAreaTargets[i];
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kInvalidMoveAreaIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameMap::TryGetMoveAreaTarget(const Vec3& curPos, MapMoveArea& outTarget) const {
|
||||||
|
size_t index = FindMoveAreaIndex(curPos);
|
||||||
|
if (index != kInvalidMoveAreaIndex &&
|
||||||
|
index < mapConfig_.townMovableAreaTargets.size()) {
|
||||||
|
outTarget = mapConfig_.townMovableAreaTargets[index];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameMap::SetDebugHighlightedMoveAreaIndex(size_t index) {
|
||||||
|
auto layerIt = layerMap_.find("max");
|
||||||
|
if (layerIt == layerMap_.end() || !layerIt->second) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layerIt->second->SetDebugHighlightedMoveAreaIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<GameMap::MapMoveArea>& GameMap::GetMoveAreaInfo() const {
|
const std::vector<GameMap::MapMoveArea>& GameMap::GetMoveAreaInfo() const {
|
||||||
return mapConfig_.townMovableAreaTargets;
|
return mapConfig_.townMovableAreaTargets;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,19 @@ constexpr float kDebugEdgePointSize = 5.0f;
|
|||||||
constexpr float kDebugVertexSize = 9.0f;
|
constexpr float kDebugVertexSize = 9.0f;
|
||||||
constexpr float kDebugEdgeStep = 4.0f;
|
constexpr float kDebugEdgeStep = 4.0f;
|
||||||
|
|
||||||
|
std::vector<Vec2> BuildRectPolygon(const Rect& rect) {
|
||||||
|
if (rect.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
Vec2(rect.left(), rect.top()),
|
||||||
|
Vec2(rect.right(), rect.top()),
|
||||||
|
Vec2(rect.right(), rect.bottom()),
|
||||||
|
Vec2(rect.left(), rect.bottom()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Rect> BuildPolygonFillRects(const std::vector<Vec2>& polygon) {
|
std::vector<Rect> BuildPolygonFillRects(const std::vector<Vec2>& polygon) {
|
||||||
std::vector<Rect> fillRects;
|
std::vector<Rect> fillRects;
|
||||||
if (polygon.size() < 3) {
|
if (polygon.size() < 3) {
|
||||||
@@ -124,10 +137,15 @@ void GameMapLayer::Render() {
|
|||||||
Renderer::get().drawQuad(drawRect, Color(0.0f, 1.0f, 0.0f, kDebugAreaAlpha));
|
Renderer::get().drawQuad(drawRect, Color(0.0f, 1.0f, 0.0f, kDebugAreaAlpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& rect : moveAreaInfoList_) {
|
for (const auto& moveArea : moveAreaInfoList_) {
|
||||||
Rect drawRect(worldOrigin.x + rect.origin.x, worldOrigin.y + rect.origin.y,
|
bool isHighlighted = moveArea.index == highlightedMoveAreaIndex_;
|
||||||
rect.width(), rect.height());
|
Color fillColor =
|
||||||
Renderer::get().drawQuad(drawRect, Color(0.0f, 0.0f, 1.0f, kDebugAreaAlpha));
|
isHighlighted ? Color(0.0f, 1.0f, 1.0f, 0.60f)
|
||||||
|
: Color(0.0f, 0.0f, 1.0f, kDebugAreaAlpha);
|
||||||
|
Rect drawRect(worldOrigin.x + moveArea.rect.origin.x,
|
||||||
|
worldOrigin.y + moveArea.rect.origin.y,
|
||||||
|
moveArea.rect.width(), moveArea.rect.height());
|
||||||
|
Renderer::get().drawQuad(drawRect, fillColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!feasibleAreaPolygon_.empty()) {
|
if (!feasibleAreaPolygon_.empty()) {
|
||||||
@@ -135,6 +153,19 @@ void GameMapLayer::Render() {
|
|||||||
DrawPolygonOutline(feasibleAreaPolygon_, worldOrigin, outlineColor);
|
DrawPolygonOutline(feasibleAreaPolygon_, worldOrigin, outlineColor);
|
||||||
DrawPolygonVertices(feasibleAreaPolygon_, worldOrigin, outlineColor);
|
DrawPolygonVertices(feasibleAreaPolygon_, worldOrigin, outlineColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& moveArea : moveAreaInfoList_) {
|
||||||
|
std::vector<Vec2> polygon = BuildRectPolygon(moveArea.rect);
|
||||||
|
if (polygon.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool isHighlighted = moveArea.index == highlightedMoveAreaIndex_;
|
||||||
|
Color moveAreaOutlineColor =
|
||||||
|
isHighlighted ? Color(0.0f, 1.0f, 1.0f, 1.0f)
|
||||||
|
: Color(0.0f, 0.0f, 1.0f, kDebugOutlineAlpha);
|
||||||
|
DrawPolygonOutline(polygon, worldOrigin, moveAreaOutlineColor);
|
||||||
|
DrawPolygonVertices(polygon, worldOrigin, moveAreaOutlineColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMapLayer::SetDebugFeasibleAreaPolygon(const std::vector<Vec2>& polygon) {
|
void GameMapLayer::SetDebugFeasibleAreaPolygon(const std::vector<Vec2>& polygon) {
|
||||||
@@ -142,14 +173,23 @@ void GameMapLayer::SetDebugFeasibleAreaPolygon(const std::vector<Vec2>& polygon)
|
|||||||
feasibleAreaFillRects_ = BuildPolygonFillRects(feasibleAreaPolygon_);
|
feasibleAreaFillRects_ = BuildPolygonFillRects(feasibleAreaPolygon_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMapLayer::AddDebugMoveAreaInfo(const Rect& rect) {
|
void GameMapLayer::AddDebugMoveAreaInfo(const Rect& rect, size_t index) {
|
||||||
moveAreaInfoList_.push_back(rect);
|
DebugMoveAreaInfo debugArea;
|
||||||
|
debugArea.rect = rect;
|
||||||
|
debugArea.index = index;
|
||||||
|
|
||||||
|
moveAreaInfoList_.push_back(std::move(debugArea));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameMapLayer::SetDebugHighlightedMoveAreaIndex(size_t index) {
|
||||||
|
highlightedMoveAreaIndex_ = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMapLayer::ClearDebugAreaInfo() {
|
void GameMapLayer::ClearDebugAreaInfo() {
|
||||||
feasibleAreaPolygon_.clear();
|
feasibleAreaPolygon_.clear();
|
||||||
feasibleAreaFillRects_.clear();
|
feasibleAreaFillRects_.clear();
|
||||||
moveAreaInfoList_.clear();
|
moveAreaInfoList_.clear();
|
||||||
|
highlightedMoveAreaIndex_ = kInvalidMoveAreaIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMapLayer::AddObject(RefPtr<Actor> obj) {
|
void GameMapLayer::AddObject(RefPtr<Actor> obj) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "scene/GameMapTestScene.h"
|
#include "scene/GameMapTestScene.h"
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <frostbite2D/scene/scene_manager.h>
|
#include <frostbite2D/scene/scene_manager.h>
|
||||||
#include <frostbite2D/utils/startup_trace.h>
|
#include <frostbite2D/utils/startup_trace.h>
|
||||||
@@ -7,7 +7,7 @@ namespace frostbite2D {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr char kTestMapPath[] = "map/elvengard/elvengard.map";
|
constexpr char kTestMapPath[] = "map/elvengard/d_elvengard.map";
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user