我在半小时前问了这个问题,但是代码有错字,而且我不是很清楚,所以我已经删除了,我正在尝试用更好的格式。
我的代码中出现了分段错误,问题似乎出现在if( (*trans).test((*this), *(*itr)) )
内的函数调用World::update()
中:
void World::update(sf::Time dt)
{
mPlayer->setVelocity(0.f, 0.f);
while (!mCommandQueue.isEmpty()){
Command cmd = mCommandQueue.pop();
cmd.action(cmd.node, dt);
}
mSceneGraph.update(dt);
adaptPlayerPosition();
//Enemy Spawn engine
if (mSpawnTimer.getElapsedTime().asSeconds() >= SPAWN_INTERVAL && mEnemies.size() < MAX_NUM_ENEMIES){
float winX = mWindow.getDefaultView().getSize().x;
float winY = mWindow.getDefaultView().getSize().y;
float x = rand() % (int)winX;
float y = rand() % (int)winY;
spawnEnemy(x, y, EnemyType::Loner, IState::ILWander);
mSpawnTimer.restart();
}
// FSM update
IState::ID curEnemyStateID;
FState curEnemyState;
bool trigger = false;
ICondition triggeredtrans;
FState triggeredState;
for(auto itr = mEnemies.begin(); itr != mEnemies.end(); ++itr){
curEnemyStateID = (*itr)->getState();
// set curState to whatever the enemy's curState is
switch(curEnemyStateID){
case 0:
curEnemyState = LWander;
break;
default:
break;
}
auto tState = curEnemyState.getTransitionStates().begin();
for(auto trans = curEnemyState.getConditions().begin(); trans != curEnemyState.getConditions().end(); ++trans){
if( (*trans).test((*this), *(*itr)) ){
trigger = true;
triggeredState = (*tState);
break;
}
++tState;
}
if(trigger){
(*itr)->setState(IState::ILRushPlayer);
curEnemyState = LRushPlayer;
}
curEnemyState.getAction()->doAction((*this), *(*itr));
}
}
上下文:
trans
是std::vector<ICondition> conditions
的迭代器,其中每个ICondition
都有test(World& world, Enemy& enemy)
。 itr
是由std::vector<Enemy*>
持有的World
的迭代器。
conditions
向量填充在此函数中:
void World::initializeStates()
{
Wander LWanderAction;
LWander.setAction(LWanderAction);
DistFromPlayer LWanderCond1(30);
LWander.pushCondition(LWanderCond1);
LWander.pushTransitionState(LRushPlayer);
}
LWander是我的有限状态机中的状态(FState
)。 Wander
是继承IAction
的类,setAction
接受IAction
参数:FState::setAction(IAction iact)
DistFromPlayer
是一个继承ICondition
的类。
FState::pushCondition(ICondition icond)
和FState::pushTransitionState(Fstate state)
应该接受他们的论点并将其推送到Fstate
的{{1}}和conditions
向量。 (转换条件和匹配目标状态应该在两者中的相同索引处)
states
和LWander
都是LRushPlayer
的成员。
这应该涵盖一切。我不知道为什么我会收到SegFault,但我认为问题在于World
中LWander
的内容如何被推送到World::initializeStates()
。我还应该注意到SegFault是在我的游戏中产生第一个敌人之后发生的,这也是第一次运行(*trans).test(*this, **itr)
的更新帧。所有Enemy
都以LWander
州开头。
ICondition的virtual bool test(World& world, Enemy& enemy);
定义为:
bool ICondition::test(World& world, Enemy& enemy){
return false;
//returns false by default, overwritten later
}
和DistFromPlayer的bool test(World& world, Enemy& enemy);
定义为:
bool DistFromPlayer::test(World& world, Enemy& enemy)
{
std::cout << "DistFromPlayer (LWander's Transition) was reached\n";
return false;
}
并且仅包含用于调试目的的print语句。
GDB的回溯
#0 World::update (this=0x6464408, dt=...) at C:\...\World.cpp:97
#1 0x0040416b in GameState::update (this=0x64643f0, dt=...) at C:\...\GameState.cpp:22
#2 0x00402435 in StateStack::update (this=0x28fde0, dt=...) at C:\...\StateStack.cpp:19
#3 0x00403782 in Game::update (this=0x28fbc0, elapsedTime=...) at C:\...\Game.cpp:58
#4 0x004036a2 in Game::run (this=0x28fbc0) at C:\...\Game.cpp:48
#5 0x0040888b in main () at C:\...\main.cpp:7
答案 0 :(得分:0)
我怀疑是tState迭代器。您只能使用begin()初始化它并递增它。我找不到针对相应容器的end()的任何测试。或者是否因为curEnemyState.getTransitionStates()和curEnemyState.getConditions()之间存在一些关系而无法实现?