0

我有一个功能可以检查其他玩家在地图上的移动并相应地调整他们的位置,它还会检查玩家是否刚刚进入。

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;
            }


        }
    }





}

因此,基本上当新玩家连接到服务器并且游戏需要将其添加到向量中时,就会发生崩溃。奇怪的是它并没有在 Visual Studio 2010 上崩溃,但是当我更改为 vs 2012 时崩溃了,所以我一定做错了什么。

编辑:这是玩家矢量的创建方式

地图管理器.h

std::vector<player> * players;

地图管理器.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 和 player.cpp

4

1 回答 1

1

您提供的代码似乎没有任何问题。

虽然try-catch您使用的构造可能不是我会做的事情,但据我所知,它没有任何问题。atC++03 和 C++11 标准都保证throwstd::out_of_range元素不存在。

您需要在其他地方寻找错误。引起我兴趣的一件事是您正在动态分配vector. vector 没有提出任何理由,但是由于假设它存在,您使用的方式似乎没有任何问题,因此可能的情况是vector已损坏,已被删除,或者您的动态内存有其他问题管理。如果您可以在不使用动态分配的情况下度过难关,我强烈推荐它。如果没有动态分配就无法度过难关,那么至少使用智能指针而不是原始指针。

另一个值得关注的地方是 的构造函数player,尤其是复制构造函数。由于push_back要创建要添加的元素的副本,因此如果vector本身没有问题,则问题可能出在复制构造函数中。

为 编写一个复制构造函数player,如下所示:

player (const player& rhs)
:
  posX (rhs.posX),
  mapId (rhs.mapId),
  plyId (rhs.plyId),
  playerModel (rhs.playerModel)
{
}

在初始化列表的第一行设置断点。它打吗?进入每个成员的构造函数。他们会崩溃吗?

于 2013-07-05T13:12:43.613 回答