C++ 实现状态
C++ Implementing states
我的问题是:
我正在尝试在我的项目中实施基本状态管理,但我坚持改变状态。
我的所有状态都在 std::stack<State*>
容器中,并且 push/pop 它们直接来自应用程序 class 或来自状态 class。
问题是当我从 State class 更改当前状态时,它可以在调用 render 方法之前被销毁,这会导致异常。那么我该如何避免呢?
PS 对不起我的英语,如果我的 problem/code 中的内容不清楚,请告诉我
申请class:
void Application::pushState(State* state)
{
this->m_states.push(state);
this->m_states.top()->open();//enter state
}
void Application::popState()
{
if (!this->m_states.empty())
{
this->m_states.top()->close();//leave state
delete this->m_states.top();
}
if (!this->m_states.empty())
this->m_states.pop();
}
void Application::changeState(State* state)
{
if (!this->m_states.empty())
popState();
pushState(state);
}
State* Application::peekState()
{
if (this->m_states.empty()) return nullptr;
return this->m_states.top();
}
void Application::mainLoop()
{
sf::Clock clock;
while (this->m_window.isOpen())
{
sf::Time elapsed = clock.restart();
float delta = elapsed.asSeconds();
if (this->peekState() == nullptr)
this->m_window.close();
this->peekState()->update(delta)//if i change state in State.update(), it may be that code below will now point to not existing state
if (this->peekState() == nullptr)
this->m_window.close();
this->peekState()->render(delta);
}
}
状态class:
void EditorState::update(const float delta)
{
sf::Event event;
while (this->m_application->m_window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
this->m_application->popState();
return;
}
}
}
好吧,也许这不是真正的问题,而是类似 "how to" 的问题。正如您在我的代码中看到的,我在 mainLoop() 方法中更新和呈现状态。我想弄清楚的是如何管理这些更新,假设状态可以从状态本身改变,而不仅仅是从 stateManager(在我的例子中是 Application class)
好的,所以我猜这是为了游戏(但不一定是)。我没有做你正在做的在状态之间切换的事情,而是使用枚举。
enum class GameState {
MENU, PLAY, PAUSE
}
然后,在你的主 header
GameState m_gameState = GameState::MENU;
在您的主循环中,您可以通过简单地执行以下操作来检查当前状态
if (m_gameState == GameState::MENU)
{
...
}
或者您可以使用 switch 语句
switch (m_gameState)
{
case GameState::MENU:
...
break;
case GameState::PLAY:
...
break;
case GameState::PAUSE:
...
break;
}
而且,如果你想切换状态,你可以这样做
m_gameState = GameState::PAUSE;
希望这能回答您的问题 :D
如果不是,那一定是我误会了(抱歉)
我的问题是:
我正在尝试在我的项目中实施基本状态管理,但我坚持改变状态。
我的所有状态都在 std::stack<State*>
容器中,并且 push/pop 它们直接来自应用程序 class 或来自状态 class。
问题是当我从 State class 更改当前状态时,它可以在调用 render 方法之前被销毁,这会导致异常。那么我该如何避免呢?
PS 对不起我的英语,如果我的 problem/code 中的内容不清楚,请告诉我
申请class:
void Application::pushState(State* state)
{
this->m_states.push(state);
this->m_states.top()->open();//enter state
}
void Application::popState()
{
if (!this->m_states.empty())
{
this->m_states.top()->close();//leave state
delete this->m_states.top();
}
if (!this->m_states.empty())
this->m_states.pop();
}
void Application::changeState(State* state)
{
if (!this->m_states.empty())
popState();
pushState(state);
}
State* Application::peekState()
{
if (this->m_states.empty()) return nullptr;
return this->m_states.top();
}
void Application::mainLoop()
{
sf::Clock clock;
while (this->m_window.isOpen())
{
sf::Time elapsed = clock.restart();
float delta = elapsed.asSeconds();
if (this->peekState() == nullptr)
this->m_window.close();
this->peekState()->update(delta)//if i change state in State.update(), it may be that code below will now point to not existing state
if (this->peekState() == nullptr)
this->m_window.close();
this->peekState()->render(delta);
}
}
状态class:
void EditorState::update(const float delta)
{
sf::Event event;
while (this->m_application->m_window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
this->m_application->popState();
return;
}
}
}
好吧,也许这不是真正的问题,而是类似 "how to" 的问题。正如您在我的代码中看到的,我在 mainLoop() 方法中更新和呈现状态。我想弄清楚的是如何管理这些更新,假设状态可以从状态本身改变,而不仅仅是从 stateManager(在我的例子中是 Application class)
好的,所以我猜这是为了游戏(但不一定是)。我没有做你正在做的在状态之间切换的事情,而是使用枚举。
enum class GameState {
MENU, PLAY, PAUSE
}
然后,在你的主 header
GameState m_gameState = GameState::MENU;
在您的主循环中,您可以通过简单地执行以下操作来检查当前状态
if (m_gameState == GameState::MENU)
{
...
}
或者您可以使用 switch 语句
switch (m_gameState)
{
case GameState::MENU:
...
break;
case GameState::PLAY:
...
break;
case GameState::PAUSE:
...
break;
}
而且,如果你想切换状态,你可以这样做
m_gameState = GameState::PAUSE;
希望这能回答您的问题 :D
如果不是,那一定是我误会了(抱歉)