Add main loop
parent
a97770a8eb
commit
50066db8ef
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "Entity.hpp"
|
#include "Entity.hpp"
|
||||||
#include "components/GravityWellComponent.hpp"
|
#include "components/GravityWellComponent.hpp"
|
||||||
|
#include "components/MeterComponent.hpp"
|
||||||
#include "components/NullZoneComponent.hpp"
|
#include "components/NullZoneComponent.hpp"
|
||||||
#include "components/TransformComponent.hpp"
|
#include "components/TransformComponent.hpp"
|
||||||
|
|
||||||
|
|
@ -85,6 +86,14 @@ bool PhysicsComponent::ComputeWellDeltaVelocity(double px, double py, double dt,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Probe cannot receive well acceleration when meter is depleted.
|
||||||
|
if (context && entity == context->probeEntity && context->hudEntity) {
|
||||||
|
auto meter = context->hudEntity->GetComponent<MeterComponent>();
|
||||||
|
if (meter && meter->get().value <= 0.0f) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IsInsideNullZone(px)) {
|
if (IsInsideNullZone(px)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,87 @@
|
||||||
#include "components/SpawnComponent.hpp"
|
#include "components/SpawnComponent.hpp"
|
||||||
|
|
||||||
void SpawnComponent::Setup() {}
|
#include "Entities.hpp"
|
||||||
void SpawnComponent::Update(float) {}
|
#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 < 55.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 < 88.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 {
|
||||||
|
const float width = static_cast<float>(GetRandomValue(70, 140));
|
||||||
|
auto zone = CreateNullZone(cursorWX, width);
|
||||||
|
zone->SetContext(context);
|
||||||
|
context->entities->push_back(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {}
|
void SpawnComponent::Cleanup() {}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,29 @@
|
||||||
#include "Component.hpp"
|
#include "Component.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Placeholder for spawn cursor/state while spawning system evolves.
|
* Spawns and despawns gameplay objects to keep the run effectively infinite.
|
||||||
*/
|
*/
|
||||||
struct SpawnComponent : public Component {
|
struct SpawnComponent : public Component {
|
||||||
|
/**
|
||||||
|
* Next world-space X coordinate where a spawn roll will happen.
|
||||||
|
*/
|
||||||
float cursorWX = 0.0f;
|
float cursorWX = 0.0f;
|
||||||
|
/**
|
||||||
|
* How far ahead of current scroll we keep content generated.
|
||||||
|
*/
|
||||||
|
float spawnAheadDistance = 1200.0f;
|
||||||
|
/**
|
||||||
|
* How far behind the camera entities are culled.
|
||||||
|
*/
|
||||||
|
float despawnBehindDistance = 180.0f;
|
||||||
|
/**
|
||||||
|
* Minimum spacing between spawn rolls.
|
||||||
|
*/
|
||||||
|
float minGap = 160.0f;
|
||||||
|
/**
|
||||||
|
* Maximum spacing between spawn rolls.
|
||||||
|
*/
|
||||||
|
float maxGap = 320.0f;
|
||||||
|
|
||||||
void Setup() override;
|
void Setup() override;
|
||||||
void Update(float dt) override;
|
void Update(float dt) override;
|
||||||
|
|
|
||||||
|
|
@ -20,30 +20,32 @@ void GameplayScene::Enter() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.entities->push_back(
|
context.entities->emplace_back(
|
||||||
CreateDebris(transform->get().x - 4.0f, transform->get().y, -22.0f, -36.0f));
|
CreateDebris(transform->get().x - 4.0f, transform->get().y, -22.0f, -36.0f));
|
||||||
context.entities->push_back(
|
context.entities->emplace_back(
|
||||||
CreateDebris(transform->get().x + 4.0f, transform->get().y, 24.0f, -28.0f));
|
CreateDebris(transform->get().x + 4.0f, transform->get().y, 24.0f, -28.0f));
|
||||||
});
|
});
|
||||||
context.AddMeterChangedListener([this](float, float newValue) { meterValue = newValue; });
|
context.AddMeterChangedListener([this](float, float newValue) { meterValue = newValue; });
|
||||||
|
|
||||||
entities.push_back(CreateWorld());
|
context.worldEntity = entities.emplace_back(CreateWorld()).get();
|
||||||
entities.push_back(CreateGravityWell());
|
|
||||||
entities.push_back(CreateProbe());
|
|
||||||
entities.push_back(CreateStar(900.0f, 120.0f));
|
|
||||||
entities.push_back(CreateAsteroid(1100.0f, 330.0f));
|
|
||||||
entities.push_back(CreateNullZone(1280.0f, 120.0f));
|
|
||||||
entities.push_back(CreateHUD());
|
|
||||||
|
|
||||||
if (auto meter = entities.back()->GetComponent<MeterComponent>()) {
|
context.wellEntity = entities.emplace_back(CreateGravityWell()).get();
|
||||||
meterValue = meter->get().value;
|
|
||||||
|
context.probeEntity = entities.emplace_back(CreateProbe()).get();
|
||||||
|
|
||||||
|
entities.emplace_back(CreateStar(900.0f, 230.0f));
|
||||||
|
entities.emplace_back(CreateNullZone(1280.0f, 120.0f));
|
||||||
|
|
||||||
|
context.hudEntity = entities.emplace_back(CreateHUD()).get();
|
||||||
|
|
||||||
|
if (context.hudEntity) {
|
||||||
|
auto meter = context.hudEntity->GetComponent<MeterComponent>();
|
||||||
|
if (meter) {
|
||||||
|
meterValue = meter->get().value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.entities = &entities;
|
context.entities = &entities;
|
||||||
context.worldEntity = (entities.size() > 0 && entities[0]) ? entities[0].get() : nullptr;
|
|
||||||
context.wellEntity = (entities.size() > 1 && entities[1]) ? entities[1].get() : nullptr;
|
|
||||||
context.probeEntity = (entities.size() > 2 && entities[2]) ? entities[2].get() : nullptr;
|
|
||||||
context.hudEntity = (!entities.empty() && entities.back()) ? entities.back().get() : nullptr;
|
|
||||||
|
|
||||||
for (auto &entity : entities) {
|
for (auto &entity : entities) {
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
|
|
@ -56,11 +58,6 @@ void GameplayScene::Enter() {
|
||||||
void GameplayScene::Update(float dt) {
|
void GameplayScene::Update(float dt) {
|
||||||
UpdateAllSystems(entities, dt);
|
UpdateAllSystems(entities, dt);
|
||||||
|
|
||||||
context.worldEntity = (entities.size() > 0 && entities[0]) ? entities[0].get() : nullptr;
|
|
||||||
context.wellEntity = (entities.size() > 1 && entities[1]) ? entities[1].get() : nullptr;
|
|
||||||
context.probeEntity = (entities.size() > 2 && entities[2]) ? entities[2].get() : nullptr;
|
|
||||||
context.hudEntity = (!entities.empty() && entities.back()) ? entities.back().get() : nullptr;
|
|
||||||
|
|
||||||
if (wantsDeathScene) {
|
if (wantsDeathScene) {
|
||||||
manager.QueueSceneChange<DeathScene>();
|
manager.QueueSceneChange<DeathScene>();
|
||||||
}
|
}
|
||||||
|
|
@ -70,8 +67,15 @@ void GameplayScene::Draw() {
|
||||||
DrawSceneOutline();
|
DrawSceneOutline();
|
||||||
DrawText("Gravity Surfing", 14, 12, 20, Color{230, 238, 255, 255});
|
DrawText("Gravity Surfing", 14, 12, 20, Color{230, 238, 255, 255});
|
||||||
|
|
||||||
auto worldScroll = entities[0]->GetComponent<ScrollComponent>();
|
std::optional<std::reference_wrapper<ScrollComponent>> worldScroll;
|
||||||
auto probeTransform = entities[2]->GetComponent<TransformComponent>();
|
if (context.worldEntity) {
|
||||||
|
worldScroll = context.worldEntity->GetComponent<ScrollComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<TransformComponent>> probeTransform;
|
||||||
|
if (context.probeEntity) {
|
||||||
|
probeTransform = context.probeEntity->GetComponent<TransformComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
if (worldScroll) {
|
if (worldScroll) {
|
||||||
DrawText(TextFormat("scrollX: %.2f", worldScroll->get().scrollX), 14, 40, 16,
|
DrawText(TextFormat("scrollX: %.2f", worldScroll->get().scrollX), 14, 40, 16,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue