Какой более эффективный способ установить переменные для неизвестного количества объектов в C++?

Вопрос или проблема

В настоящее время я создаю игру Asteroids на Arduino для школьного проекта. Скорее всего, мне нужно будет создать относительно большое количество астероидов во время игры, а также потребуется создать ещё больше пуль, которые игрок стреляет, чтобы уничтожить астероиды. Поскольку мы не будем знать точно, сколько пуль/астероидов будет на экране в один момент времени, это будет означать, что нам потребуется объявить достаточно возможных имен переменных, чтобы не превышать лимит (или, по крайней мере, избежать ситуации, когда игрок сталкивается с этим лимитом слишком часто).

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

Как я понимаю, использование класса или структуры было бы наилучшим способом настройки кода как для астероидов, так и для пуль, но поскольку оба требуют, чтобы вы назвали каждую новую инстанцию, это значительно усложняет задачу, так как C++ не позволяет динамически создавать имена переменных. Моя текущая рабочая идея заключается в создании булева массива (AsteroidBoolean0, AsteroidBoolean1 и так далее, вплоть до, скажем, 50), который будет сообщать коду, используется ли данное имя в настоящее время. Затем я буду использовать первое имя, которое код найдет как не назначенное живому астероиду, и создавать астероид на его основе. Например:

Если(AsteroidBoolean0 == false){

AsteroidBoolean0 = true;

asteroidExampleClass asteroid0;

(вставьте все связанные переменные для астероида)

}

Иначе если(asteroidboolean1 == false){

повторите примерный код, показанный выше, до последней булевой переменной

}

Есть ли лучший способ сделать это? На основе моего ограниченного опыта это кажется наилучшим вариантом, но он по-прежнему кажется очень скучным, и я хотел бы избежать необходимости писать около ста операторов if, по сути, делающих одно и то же. Кроме того; правильно ли я использую массивы в этом примере? Или было бы возможно полностью записать: Если(AsteroidBooleanArray[0] == false){

   asteroidExampleClass asteroidNameStringArray[0];

}

И, наконец, мой последний вопрос (извините, что задаю так много), могу ли я использовать метод, чтобы избежать необходимости переписывать всю математику, необходимую для каждого астероида, в каждом возможном экземпляре? Например, могу ли я использовать:

void asteroidMethod(){

asteroidXPos += asteroidXMovement

}

и затем вызывать этот метод позже, чтобы повлиять на все инстанции астероидов, так как каждая инстанция будет иметь как свою x-позицию, так и x-движение определенными. Или мне придется индивидуально записывать математику для каждого астероида вот так:

asteroid0.asteroidXPos += asteroid0.asteroidXMovement
asteroid1.asteroidXPos += asteroid0.asteroidXMovement
... (повторяется до последнего возможного астероида)

Я полностью осознаю, что это может показаться действительно безумным для ветерана C++, но я просто не могу найти никаких ресурсов в интернете, которые подсказывают мне лучший способ сделать это, поскольку очевидно, что C не предназначен для разработки игр. Если есть какая-либо часть этого вопроса, которая является неадекватной/путаной, пожалуйста, дайте мне знать, чтобы я мог уточнить!

Ответ или решение

Создание игры, подобной Asteroids, на платформе Arduino требует продуманного подхода к управлению объектами, такими как астероиды и пули. Ваша задача усложняется необходимостью динамически управлять количеством этих объектов во время игры. Рассмотрим более эффективные способы реализации вашего замысла, используя современные концепции программирования в C++.

Оптимизация структуры данных

Ваше текущее решение с использованием массива булевых переменных для отслеживания состояния каждого астероида является неэффективным и трудоемким. Вместо этого я рекомендую использовать динамические структуры данных, такие как std::vector, которая предоставляет гибкость в управлении массивом объектов.

Пример использования std::vector

C++ предоставляет контейнеры стандартной библиотеки, такие как std::vector, которые позволяют динамически добавлять и удалять элементы. Пример использования std::vector для управления астероидами может выглядеть следующим образом:

#include <vector>

class Asteroid {
public:
    float xPos;
    float yPos;
    float xMovement;

    void updatePosition() {
        xPos += xMovement; // Логика обновления позиции астероида
    }
};

std::vector<Asteroid> asteroids;

void spawnAsteroid() {
    Asteroid newAsteroid;
    newAsteroid.xPos = ...; // Задайте начальные параметры
    newAsteroid.yPos = ...;
    newAsteroid.xMovement = ...;
    asteroids.push_back(newAsteroid);
}

void updateAsteroids() {
    for (auto& asteroid : asteroids) {
        asteroid.updatePosition(); // Обновление позиции каждого астероида
    }
}

Динамическое управление объектами

С таким подходом вам не нужно заранее объявлять фиксированное количество переменных. Вместо этого вы можете просто добавлять новые объекты Asteroid по мере необходимости, используя метод push_back в векторе. Это существенно упрощает логику управления и делает код более читаемым.

Упрощение математических операций

Что касается вычислений, вы можете создать метод в классе Asteroid, который будет обрабатывать логику обновления положения:

class Asteroid {
    // ... [предыдущий код] ...
public:
    void updatePosition() {
        xPos += xMovement;
    }
    // ... [другие методы] ...
};

Таким образом, для обновления всех астероидов вы просто вызываете метод обновления для каждого объекта в векторе:

void updateAsteroids() {
    for (auto& asteroid : asteroids) {
        asteroid.updatePosition(); // Вызывайте общую функцию обновления
    }
}

Дополнительные соображения

Если количество объектов будет значительно увеличиваться, вы должны помнить о производительности и управлении памятью. Убедитесь, что ваши объекты освобождают память при удалении, если это необходимо. При использованию std::vector и его встроенной функциональности, управление памятью значительно упрощается.

Заключение

С учетом вышесказанного, использование динамических контейнеров, таких как std::vector, значительно упрощает задачу создания и управления объектами в вашей игре. Это решение не только оптимизирует код, но и делает его более гибким и масштабируемым, что является важным аспектом разработки игр. Если возникнут дополнительные вопросы или потребуется помощь с конкретными аспектами реализации, не стесняйтесь обращаться за помощью.

Оцените материал
Добавить комментарий

Капча загружается...