Вопрос или проблема
В настоящее время я создаю игру 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
, значительно упрощает задачу создания и управления объектами в вашей игре. Это решение не только оптимизирует код, но и делает его более гибким и масштабируемым, что является важным аспектом разработки игр. Если возникнут дополнительные вопросы или потребуется помощь с конкретными аспектами реализации, не стесняйтесь обращаться за помощью.