#c #2d #game-development #glm-math
Вопрос:
У меня есть проект под названием Survival Shooter, в котором я должен создать спавнера для врагов. Я не знаю, как заставить нескольких врагов появляться из случайных позиций или, например, из одной позиции, но, например, через 5 секунд.
void Tema1::SpawnEnemy(glm::mat3 visMatrix, float deltaTime, float* posX, float* posY, float speed) { enemyAngle = atan2(translateX - *posX, translateY - *posY); *posX = speed * sin(enemyAngle) * deltaTime; *posY = speed * cos(enemyAngle) * deltaTime; //Body modelMatrix = visMatrix; modelMatrix *= transform2D::Translate(*posX, *posY); modelMatrix *= transform2D::Scale(1, 1); modelMatrix *= transform2D::Rotate(enemyAngle); modelMatrix *= transform2D::Translate(-50, -50); RenderMesh2D(meshes["border"], shaders["VertexColor"], modelMatrix); //Eye1 modelMatrix = visMatrix; modelMatrix *= transform2D::Translate(*posX, *posY); modelMatrix *= transform2D::Scale(0.25f, 0.25f); modelMatrix *= transform2D::Rotate(enemyAngle); modelMatrix *= transform2D::Translate(150, 200); modelMatrix *= transform2D::Rotate(0); modelMatrix *= transform2D::Translate(-50, -50); RenderMesh2D(meshes["square2"], shaders["VertexColor"], modelMatrix); //Eye2 modelMatrix = visMatrix; modelMatrix *= transform2D::Translate(*posX, *posY); modelMatrix *= transform2D::Scale(0.25f, 0.25f); modelMatrix *= transform2D::Rotate(enemyAngle); modelMatrix *= transform2D::Translate(-150, 200); modelMatrix *= transform2D::Rotate(0); modelMatrix *= transform2D::Translate(-50, -50); RenderMesh2D(meshes["square2"], shaders["VertexColor"], modelMatrix); }
Это метод, который я вызываю, когда хочу нарисовать нового врага, и я вызываю его в методе обновления.
Вопрос в том, как мне нарисовать нового врага через некоторое время, не уничтожая текущих врагов, которые у меня есть на сцене?
Ответ №1:
Вам нужно явно представлять врагов в своем игровом состоянии:
struct Enemy { glm::vec2 pos; glm::vec2 speed; ... void update(float deltaTime); // Update position and/or speed void draw(); // Actually draw }; std::vectorlt;Enemygt; enemies;
Затем создание врага-это просто вопрос создания нового Enemy
объекта и добавления его в вектор. Уничтожение врага — это вопрос удаления Enemy
объекта из вектора. Однако остерегайтесь обычных проблем с удалением элементов из вектора, который вы повторяете.
Ваш игровой цикл должен сначала вызывать update(deltaTime)
все объекты, а затем draw()
их.
Ответ №2:
Во-первых, вам нужно выбрать способ хранения ваших врагов. Поскольку вы работаете C
, я бы рекомендовал вам определить базовый класс entity
для игроков, предметов, сущностей и всего остального, что будет отображаться. Он определит одну функцию: update(float delta)
, где дельта-это время, затраченное нами на визуализацию предыдущего кадра. После этого вы можете создать movableEntity
наследующий класс entity
, который может перемещаться (управляется либо игроком , либо ИИ). Класс определит несколько функций: jump
, moveBack
, moveForward
, attack
, и т.д… Он также определит два поля: float x
и float y
это действительно зависит от того, что смогут сделать ваши враги. Теперь мы определяем класс для нашего врага, который следует назвать enemyEntity
, и он унаследует movableEntity
.
Теперь вам нужно иметь список всех сущностей, присутствующих в мире. Вы пройдете через него и вызовете render(delta)
каждого из них. Для врагов вы должны реализовать искусственный интеллект, который использует контроллер для управления врагом (рекомендуется, чтобы controllableEntity
класс определял функции перемещения, чтобы у них была какая-то перезарядка). Это должно быть включено в функцию обновления противника. Предпочтительно, вы могли бы написать вражеский ИИ так, чтобы вы просто указали цель.
Вот пример вражеского ИИ для 2D-игры, которая просматривается со стороны (как и большинство платформеров):
void update(float delta) { float distanceX = x - target-gt;x; if (distanceX gt; 1) { moveLeft(); } else if (distanceX lt; -1) { moveRight(); } else { attack(); } }
Конечно, это очень простой ИИ, который не учитывает никаких препятствий на своем пути, но movableEntity
класс гарантирует, что игрок может сделать столько, сколько может сущность. Если вам нужна какая-либо помощь, напишите в комментариях