C ++: как вы обновляете высоту игрока в зависимости от высоты местности? - PullRequest
0 голосов
/ 03 февраля 2020

Раньше у меня был проект, в котором использовалось изображение в оттенках серого, чтобы установить высоту вершин в простой плоской области me sh, что привело к хорошему виду ландшафта, отображаемого по высоте. Однако с тех пор я преобразовал свой проект в C ++ и больше не могу использовать помощь BufferedImage и т. Д., Чтобы использовать старый подход с использованием серой шкалы для создания рельефной местности из плоского me sh.

Из-за этот мой проект C ++ теперь использует файл .obj для ландшафта, но мне очень трудно обновлять высоту проигрывателя / камеры, когда пользователь ходит по местности, вместо этого я просто перемещаюсь по всему, поскольку высота игрока никогда не меняется или только делает это очень часто (поэтому я знаю, что высота, по крайней мере, обновляется, но не правильно).

Ниже приведен небольшой пример кода, который выполняет фактическое обновление высоты проигрывателя на основе файла terrain.obj. , он делает это, сохраняя все вершины файла .obj и сравнивая каждый из их компонентов x и z с компонентами x и z проигрывателя, и, если есть совпадение, тогда устанавливает значение y проигрывателя в текущие вершины. позиция y:

Vector3f *playerPos = freeMoveObjects[0]->GetParent()->GetTransform()->GetPos();
    float playerXPos = playerPos->GetX();
    float playerZPos = playerPos->GetZ();
    int playerXPosInt = (int)playerXPos;
    int playerZPosInt = (int)playerZPos;
    for (Vector3f currentVector : meshObjects[0]->getMeshVertices()) {
        int meshHeightXInt = (int)currentVector.GetX();
        int meshHeightZInt = (int)currentVector.GetZ();
        if (meshHeightXInt == playerXPosInt & meshHeightZInt == playerZPosInt){//currentVector.GetX() <= playerXPos & currentVector.GetZ() <= playerZPos) {
            freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->SetY(currentVector.GetY());
        }

    }

1 Ответ

0 голосов
/ 03 февраля 2020

То, что вы делаете, сейчас очень неэффективно; вам не нужно выполнять l oop через все вершины, если у вас уже есть карта высот, которую вы можете использовать для обновления позиции игрока.

Почему бы вам не сохранить карту высот в псевдо-2d-массиве вот так:

class HeightMap {
private:
int width;
int height;
std::unique_ptr<int[]> data = std::make_unique<int[]>(width * height);

public:
HeightMap(int width, int height) : width{width}, height{height} {}
// you can default copy, move constructors and assignments

int heightAt(int x, int y) {
    return heightmap[x + y * width];
}
}

Используя heightAt, вы получаете эффективный произвольный доступ к данным на карте. Благодаря unique_ptr вам не нужно управлять какой-либо памятью вручную, а другие конструкторы можно использовать по умолчанию.

Обратите внимание, что вам нужно обрабатывать ошибки, такие как x или y, находящиеся вне диапазона вручную.

...