Призрачные экземпляры появляются в векторах - PullRequest
0 голосов
/ 01 декабря 2011

Это меня поставило в тупик. У меня есть три класса - большой класс с именем Level, который содержит, помимо прочего, многомерный вектор указателей на Plant экземпляров и многомерный вектор указателей на Mob экземпляров; оба вектора предназначены для классификации мобов и растений в соответствии с их положением, так что я могу искать каждый в меньшем векторе на основе их приблизительного местоположения, а не циклически перебирать все существующие растения / мобы, чтобы найти ближайший к заданная точка.

Векторы следующие, с наименьшими std :: векторами, представляющими квадратную область 128 пикселей на каждой стороне. Мобы и растения классифицируются путем деления их координат X и Y на 128 и добавления их к соответствующему сектору (я осторожен, что полученные значения на самом деле являются целыми числами).

std::vector< std::vector< std::vector<Plant*> > >* m_PlantSectors

std::vector< std::vector< std::vector<Mob*> > >* m_AnimalSectors

Мобам иногда нужно найти растения. Вот где возникает проблема: когда мобы запрашивают многомерный вектор, ища растения в их приблизительной области (если координаты моба / 128, скажем, [1,2], он ищет m_PlantSectors [2] [1]), они иногда найти растения, которые не существуют.

Мало того, но эти растения имеют невозможные позиции, например, 1.9777e + 33 или 3.75853e-39 (например). Когда я пытаюсь изменить цвет выбранного растения на красный, чтобы найти его визуально, я обнаруживаю, что ни одно из растений на экране (только растения, которые я поместил вручную) не изменило цвет.

Я пометил все растения целочисленным ID; Есть 36 растений, с идентификаторами от 1 до 36, но растения, которые мои мобы находят, имеют идентификаторы, такие как 63 или 429 - те, которые не могут существовать, так как не было создано такое количество растений (есть одна функция создания растений, которая последовательно сообщает, сколько растений существует, поэтому случайно не создаются растения). Все мобы убегают в верхнюю левую часть экрана за воображаемыми растениями и умирают от голода.

Так что я как-то создаю растения-призраки. До сих пор я пробовал два отдельных подхода, позволяющих Mob экземплярам искать Plant экземпляры. Первый выглядит так:

    float TargetDist = 256 * 256;
    Plant* Candidate = 0;
    Plant* ForageTarget = 0;
    int xSect = m_X / 128;
    int ySect = m_Y / 128;
    std::vector<Plant*> ThisSect = pLevel->CheckPSector(xSect, ySect);
    for (int i = 0; i < ThisSect.size(); ++i)
    {
        cout << "Searching in Sector (" << ySect << ", " << xSect << ")\n";
        Candidate = ThisSect[i];
        cout << "Candidate at: " << Candidate->GetX() << ", " << Candidate->GetY() << "\n";
        Candidate->Mark();
        //Calculate distance
        float xDist = Candidate->GetX() - m_X;
        float yDist = Candidate->GetY() - m_Y;
        float tDist = sqrt(xDist * xDist + yDist * yDist);
        if (tDist <= TargetDist)
        {
            ForageTarget = Candidate;
            TargetDist = tDist;
        }
    }

Где CheckPSector () выглядит так:

std::vector<Plant*> Level::CheckPSector(int x, int y)
{
    return m_PlantSectors[y][x];
}

Второе, что я попробовал, было следующее:

        float TargetDist = 256 * 256;
        Plant* Candidate = 0;
        Plant* ForageTarget = 0;
        int xSect = m_X / 128;
        int ySect = m_Y / 128;
        std::vector< std::vector< std::vector<Plant*> > >* Sectors = pLevel->AccessPlantSectors();
        for (int i = 0; i < (*Sectors)[ySect][xSect].size(); ++i)
        {
            cout << "Searching in Sector (" << ySect << ", " << xSect << ")\n";
            Candidate = (*Sectors)[ySect][xSect][i];
            cout << "Candidate at: " << Candidate->GetX() << ", " << Candidate->GetY() << "\n";
            Candidate->Mark();
            //Calculate distance
            float xDist = Candidate->GetX() - m_X;
            float yDist = Candidate->GetY() - m_Y;
            float tDist = sqrt(xDist * xDist + yDist * yDist);
            if (tDist <= TargetDist)
            {
                ForageTarget = Candidate;
                TargetDist = tDist;
            }
        }

Используя это:

std::vector< std::vector< std::vector<Plant*> > >* Level::AccessPlantSectors()
{
    return &m_PlantSectors;
}

Однако оба эти фактора приводят к тому, что животные находят воображаемые растения и убегают в пустоту.

Я не хочу регулярно копировать потенциально большие многомерные векторы в Mob экземпляров, потому что в каждый момент времени будет много таких экземпляров, и я бы хотел, чтобы программа работала несколько плавно. Несмотря на это, я просто попытался сделать все это, скопировав весь вектор вместо только соответствующего, и я получил тот же результат: воображаемые растения.

У меня никогда раньше не было такой проблемы; что здесь может происходить?

РЕДАКТИРОВАТЬ: Возможно, я должен упомянуть, что заставить выбранные заводы самостоятельно сообщать о своей позиции и идентификаторе в равной степени не удается, что приводит к абсурдным результатам, так что это не просто функции в Plant, которые я использую для доступа к частным пользователям. Между тем, при опросе всех существующих растений информация о призрачных растениях не раскрывается.

1 Ответ

2 голосов
/ 01 декабря 2011

Если m_PlantSectors определяется как:

std::vector< std::vector< std::vector<Plant*> > >* m_PlantSectors

Тогда Level::AccessPlantSectors() должен вернуть m_PlantSectors, а не &m_PlantSectors, потому что у вас уже есть указатель.

Аналогично, Level::CheckPSector(int x, int y) должен возвращать (*m_PlantSectors)[y][x], потому что вам нужно задержать указатель перед вызовом оператора [].

Как вы их написали, Level::CheckPSector(int x, int y) возвращает случайную память, и я удивлен, что Level::AccessPlantSectors() компилируется.

...