93 lines
3.1 KiB
C++
93 lines
3.1 KiB
C++
#include "components/SpawnComponent.hpp"
|
|
|
|
#include "Entities.hpp"
|
|
#include "Entity.hpp"
|
|
#include "components/CollectibleComponent.hpp"
|
|
#include "components/HazardComponent.hpp"
|
|
#include "components/NullZoneComponent.hpp"
|
|
#include "components/ScrollComponent.hpp"
|
|
#include "components/ScrollableComponent.hpp"
|
|
#include "components/TransformComponent.hpp"
|
|
|
|
#include "raylib.h"
|
|
|
|
#include <algorithm>
|
|
|
|
void SpawnComponent::Setup() {
|
|
// Start a bit beyond the initial handcrafted segment.
|
|
cursorWX = 1500.0f;
|
|
}
|
|
|
|
void SpawnComponent::Update(float) {
|
|
if (!context || !context->entities) {
|
|
return;
|
|
}
|
|
|
|
auto scroll = entity->GetComponent<ScrollComponent>();
|
|
if (!scroll) {
|
|
return;
|
|
}
|
|
|
|
const float cameraX = scroll->get().scrollX;
|
|
const float spawnLimit = cameraX + spawnAheadDistance;
|
|
|
|
while (cursorWX < spawnLimit) {
|
|
const float r = static_cast<float>(GetRandomValue(0, 99));
|
|
if (r < 70.0f) {
|
|
const float y = static_cast<float>(GetRandomValue(48, GetScreenHeight() - 48));
|
|
auto star = CreateStar(cursorWX, y);
|
|
star->SetContext(context);
|
|
context->entities->push_back(star);
|
|
} else if (r < 90.0f) {
|
|
const float y = static_cast<float>(GetRandomValue(42, GetScreenHeight() - 42));
|
|
auto asteroid = CreateAsteroid(cursorWX, y);
|
|
asteroid->SetContext(context);
|
|
context->entities->push_back(asteroid);
|
|
} else if (r < 95.0f) {
|
|
const float width = static_cast<float>(GetRandomValue(70, 140));
|
|
auto zone = CreateNullZone(cursorWX, width);
|
|
zone->SetContext(context);
|
|
context->entities->push_back(zone);
|
|
} else {
|
|
const float y = static_cast<float>(GetRandomValue(42, GetScreenHeight() - 42));
|
|
auto blackHole = CreateBlackHole(cursorWX, y);
|
|
blackHole->SetContext(context);
|
|
context->entities->push_back(blackHole);
|
|
}
|
|
|
|
const float gap =
|
|
static_cast<float>(GetRandomValue(static_cast<int>(minGap), static_cast<int>(maxGap)));
|
|
cursorWX += gap;
|
|
}
|
|
|
|
const float cullX = cameraX - despawnBehindDistance;
|
|
for (auto &candidate : *context->entities) {
|
|
if (!candidate || candidate.get() == entity || candidate->queuedForFree) {
|
|
continue;
|
|
}
|
|
|
|
const bool isSpawnedGameplayObject =
|
|
candidate->GetComponent<CollectibleComponent>().has_value() ||
|
|
candidate->GetComponent<HazardComponent>().has_value() ||
|
|
candidate->GetComponent<NullZoneComponent>().has_value();
|
|
if (!isSpawnedGameplayObject) {
|
|
continue;
|
|
}
|
|
|
|
auto scrollable = candidate->GetComponent<ScrollableComponent>();
|
|
if (scrollable) {
|
|
if (scrollable->get().worldX < cullX) {
|
|
candidate->QueueFree();
|
|
}
|
|
continue;
|
|
}
|
|
|
|
auto transform = candidate->GetComponent<TransformComponent>();
|
|
if (transform && transform->get().x < cullX) {
|
|
candidate->QueueFree();
|
|
}
|
|
}
|
|
}
|
|
|
|
void SpawnComponent::Cleanup() {}
|