我有一个功能,可以检查地图上其他玩家的移动并相应地调整他们的位置,并且还会检查玩家是否刚进入。
void mapManager::checkForOtherPlayerMovement(int plyId)
{
sf::Packet receivedPacket;
std::vector<player>::iterator it;
player pl(0,0,1);
if(socket->Receive(receivedPacket) == sf::Socket::Done)
{
int header;
receivedPacket >> header;
switch(header)
{
case PACKET_PLAYER_DISPATCHNEWPOSITION:
{
receivedPacket >> pl;
std::cout << pl.plyId << std::endl;
if(plyId != pl.plyId)
{
try
{
if(pl.plyId != 0)
{
std::cout << "DEBUG1" << std::endl;
players->at(pl.plyId-1).posX = pl.posX;
players->at(pl.plyId-1).posY = pl.posY;
}
else
{
std::cout << "DEBUG2" << std::endl;
players->at(pl.plyId).posX = pl.posX;
players->at(pl.plyId).posY = pl.posY;
}
}
catch(const std::out_of_range& oor)
{
std::cout << "Added new player!" << std::endl;
players->push_back(pl); // This crashes
}
}
break;
}
case PACKET_PLAYER_DISPATCHENTEREDMAP:
{
break;
}
}
}
}
所以基本上当新玩家连接到服务器并且游戏需要将其添加到向量内时发生崩溃。奇怪的是它在视觉工作室2010上没有崩溃,但是当我改为vs 2012时崩溃,所以我一定做错了。
编辑:以下是玩家矢量的创建方式
mapManager.h
std::vector<player> * players;
mapManager.cpp
players = new std::vector<player>();
这里我使用了球员矢量
void mapManager::drawOtherPlayers(int plyId, player *ownPlayer)
{
ownPlayerSprite->SetPosition(ownPlayer->getX(), ownPlayer->getY());
window.Draw(*ownPlayerSprite);
for(std::vector<player>::iterator it = players->begin(); it != players->end(); ++it)
{
spriteToDraw->SetPosition(it->posX,it->posY);
window.Draw(*spriteToDraw);
}
}
我的播放器课程:Player.h and player.cpp
答案 0 :(得分:1)
您提供的代码似乎没有任何问题。
虽然您使用的try-catch
构造可能不是我会做的事情,但据我所知,它没有任何问题。如果元素不存在,C ++ 03和C ++ 11标准都保证at
将throw
std::out_of_range
。
你需要到别处寻找bug。引起我兴趣的一件事是你正在动态分配vector
。没有提出任何理由,但由于您使用vector
假设它存在的方式似乎没有任何问题,可能的情况是{{1您的动态内存管理已损坏,已删除或其他错误。如果你可以不使用动态分配,我强烈推荐它。如果没有动态分配就无法通过,那么至少使用智能指针代替原始指针。
另一个要查看的地方是vector
的构造函数,特别是复制构造函数。由于player
将创建要添加的元素的副本,如果push_back
本身没有任何问题,则问题可能出在复制构造函数中。
为vector
编写一个复制构造函数,如下所示:
player
在初始化列表的第一行设置断点。它命中了吗?介入每个成员的构造函数。他们崩溃了吗?