Added GameOver Scene

This commit is contained in:
2025-12-14 10:33:06 +08:00
parent 27ff62df14
commit ad3b8d7732
12 changed files with 264 additions and 30 deletions

View File

@@ -9,6 +9,35 @@ Button::Button()
Button::Button(TextRenderer* textRenderer) : m_textRenderer(textRenderer) {
}
Button::Button(
const std::string& text,
TextStyle style,
int x,
int y,
TextRenderer* textRenderer,
SDL_Color backgroundColor,
int borderThickness,
SDL_Color borderColor
) : m_textRenderer(textRenderer)
{
m_rect.x = static_cast<float>(x);
m_rect.y = static_cast<float>(y);
m_buttonData.text = text;
m_buttonData.textstytle = style;
m_buttonData.backgroundColor = backgroundColor;
m_buttonData.borderThickness = borderThickness;
m_buttonData.borderColor = borderColor;
// 如果提供了 TextRenderer则立即测量文本并更新控件尺寸
if (m_textRenderer) {
auto [w, h] = m_textRenderer->getTextSize(text, style);
m_rect.w = static_cast<float>(w);
m_rect.h = static_cast<float>(h);
m_buttonData.rect = m_rect;
}
}
void Button::setText(const std::string& text, TextStyle style) {
m_buttonData.text = text;
m_buttonData.textstytle = style;
@@ -51,15 +80,17 @@ void Button::setCallback(std::function<void()> callback) {
void Button::update(float deltaTime) {
}
void Button::handleCilck(int x, int y) {
bool Button::handleCilck(int x, int y) {
if (m_callback && m_isEnabled && m_isVisible) {
//SDL_Log("rect x: %f, y: %f, w: %f, h: %f", m_rect.x, m_rect.y, m_rect.w, m_rect.h);
if (x >= m_rect.x && x <= m_rect.x + m_rect.w &&
y >= m_rect.y && y <= m_rect.y + m_rect.h) {
m_callback();
return true;
}
}
return false;
}

View File

@@ -12,6 +12,18 @@ public:
Button();
// 可以传入 TextRenderer 指针以便在 setText 时立即计算文字尺寸并更新 rect
explicit Button(TextRenderer* textRenderer);
explicit Button(
const std::string& text,
TextStyle style = {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}},
int x = 0,
int y = 0,
TextRenderer* textRenderer = nullptr,
SDL_Color backgroundColor = {200, 200, 200, 255},
int borderThickness = 0,
SDL_Color borderColor = {0, 0, 0, 255}
);
~Button() override = default;
// 实现UIComponent接口
@@ -57,7 +69,7 @@ public:
* @param x 点击位置的X坐标
* @param y 点击位置的Y坐标
*/
void handleCilck(int x, int y);
bool handleCilck(int x, int y);
private:

View File

@@ -11,21 +11,12 @@ GameUIManager::~GameUIManager() {
}
void GameUIManager::init() {
auto button = std::make_unique<Button>(m_textRenderer);
button->setBackgroundColor({255, 100, 0, 255});
button->setBorder(2, {0, 0, 0, 255});
button->setPosition(20, 20);
button->setEnabled(true);
button->setVisible(true);
button->setText("Please Choose", {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}});
button->setName("ActionButton");
m_buttons.emplace(button->getNameHash(), std::move(button));
//m_restartCallback = restartCallback;
setupUIComponents();
}
auto label = std::make_unique<Label>();
label->setPosition(1200, 20);
label->setText("0 0", {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}});
label->setName("MousePositionLabel");
m_labels.emplace(label->getNameHash(), std::move(label));
void GameUIManager::setCallback(std::function<void()> restartCallback) {
m_restartCallback = restartCallback;
}
@@ -92,4 +83,100 @@ void GameUIManager::updateActionType(ActionType type) {
break;
}
}
}
}
void GameUIManager::updateGameState(GameState state) {
if (m_currentGameState == state) {
SDL_Log("State unchanged, returning early\n");
return;
}
// 根据传入的 GameState 更新 UI 组件状态
{
auto buttonIt = m_buttons.find(makeHash("RestartButton"));
if (buttonIt != m_buttons.end()) {
auto& button = buttonIt->second;
if (state != GameState::GAME_RUNING) {
//button->setBackgroundColor({255, 215, 0, 255}); // 金色
//button->setText("GAME OVER");
button->setVisible(true);
button->setEnabled(true);
} else {
button->setVisible(false);
button->setEnabled(false);
}
}
}
{
auto actionButtonIt = m_buttons.find(makeHash("ActionButton"));
if (actionButtonIt != m_buttons.end()) {
auto& actionButton = actionButtonIt->second;
if (state != GameState::GAME_RUNING) {
actionButton->setEnabled(false);
actionButton->setVisible(false);
} else {
actionButton->setEnabled(true);
actionButton->setVisible(true);
}
}
}
// 保存当前游戏状态,避免后续相同状态更新被误判为无变化
m_currentGameState = state;
}
void GameUIManager::setupUIComponents() {
// 这里可以添加更多的UI组件初始化逻辑
auto button = std::make_unique<Button>(m_textRenderer);
button->setBackgroundColor({255, 100, 0, 255});
button->setBorder(2, {0, 0, 0, 255});
button->setPosition(20, 20);
button->setEnabled(true);
button->setVisible(true);
button->setText("Please Choose", {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}});
button->setName("ActionButton");
m_buttons.emplace(button->getNameHash(), std::move(button));
auto label = std::make_unique<Label>();
label->setPosition(1200, 20);
label->setText("0 0", {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}});
label->setName("MousePositionLabel");
m_labels.emplace(label->getNameHash(), std::move(label));
auto restartButton = std::make_unique<Button>(
"Restart",
(TextStyle){"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}},
700,
500,
m_textRenderer,
(SDL_Color){100, 255, 100, 255}
);
restartButton->setCallback([this](){
if (m_restartCallback) {
m_restartCallback();
}
});
restartButton->setName("RestartButton");
restartButton->setVisible(false); // 初始时隐藏
restartButton->setEnabled(false);
m_buttons.emplace(restartButton->getNameHash(), std::move(restartButton));
}
bool GameUIManager::handleClick(float x, float y) {
auto logicalPos = physicalToLogical(static_cast<float>(x), static_cast<float>(y), m_renderer);
int lx = logicalPos.first;
int ly = logicalPos.second;
// 遍历所有按钮,检查点击位置是否在按钮范围内
for (auto& [id, button] : m_buttons) {
if (button->isEnabled() && button->isVisible()) {
if(button->handleCilck(lx, ly)) {
return true;
}
}
}
return false;
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "ui/base/IUIManager.h"
#include "game/GameTypes.h"
#include <functional>
class GameUIManager : public IUIManager {
public:
GameUIManager(SDL_Renderer* renderer, TextRenderer* textRenderer);
@@ -9,6 +10,8 @@ public:
void init();
void setCallback(std::function<void()> restartCallback);
const UIRenderData& getUIRenderData();
// 收集渲染数据
void CollectRenderData();
@@ -16,7 +19,14 @@ public:
void UpdateMousePositon(float x, float y);
void updateActionType(ActionType type);
private:
};
void updateGameState(GameState state);
bool handleClick(float x, float y);
private:
std::function<void()> m_restartCallback;
void setupUIComponents();
GameState m_currentGameState = GameState::GAME_RUNING;
};

View File

@@ -72,6 +72,8 @@ void MainMenuUIManager::handleClick(float x, float y) {
auto logicPos = physicalToLogical(x, y, m_renderer);
for (auto& buttonPair : m_buttons) {
SDL_Log("Handling click at logical position (%d, %d)\n", logicPos.first, logicPos.second);
buttonPair.second->handleCilck(logicPos.first, logicPos.second);
if (buttonPair.second->handleCilck(logicPos.first, logicPos.second)) {
return;
}
}
}