154 lines
3.8 KiB
C++
154 lines
3.8 KiB
C++
|
#include "entity.cpp"
|
||
|
#include <string.h>
|
||
|
|
||
|
constexpr struct {
|
||
|
size_t min;
|
||
|
size_t max;
|
||
|
} QUADRANT_STARS = {100, 300};
|
||
|
|
||
|
constexpr struct {
|
||
|
size_t min;
|
||
|
size_t max;
|
||
|
} QUADRANT_ORBITALS = {0, 7};
|
||
|
|
||
|
constexpr auto QUADRANT_RANGE = 512;
|
||
|
|
||
|
constexpr auto QUADRANT_SIZE = (QUADRANT_RANGE * 2);
|
||
|
|
||
|
struct EntityUpdateInfo {
|
||
|
bool hasPassedQuadrant;
|
||
|
|
||
|
bool hasMoved;
|
||
|
};
|
||
|
|
||
|
struct Worldspace {
|
||
|
enum struct OrbitalType {
|
||
|
SUN,
|
||
|
MOON
|
||
|
};
|
||
|
|
||
|
struct Orbital {
|
||
|
OrbitalType type;
|
||
|
Vector2 localPosition;
|
||
|
float orientation;
|
||
|
float scale;
|
||
|
};
|
||
|
|
||
|
struct Quadrant {
|
||
|
QuadrantCoords id;
|
||
|
size_t starCount;
|
||
|
size_t orbitalCount;
|
||
|
Vector2 stars[QUADRANT_STARS.max];
|
||
|
Orbital orbitals[QUADRANT_ORBITALS.max];
|
||
|
};
|
||
|
|
||
|
Seed seed;
|
||
|
SpaceshipEntity player;
|
||
|
Vector2 nebulaParallaxScroll;
|
||
|
Quadrant loadedQuadrantMap[9];
|
||
|
};
|
||
|
|
||
|
Worldspace const CreateWorldspace(Seed const seed) {
|
||
|
Worldspace world = {0};
|
||
|
world.seed = seed;
|
||
|
world.player.entity.localPosition = Vector2{0, 0};
|
||
|
|
||
|
return world;
|
||
|
}
|
||
|
|
||
|
void GenerateWorldspace(Worldspace& world) {
|
||
|
QuadrantCoords offset = {-1, -1};
|
||
|
|
||
|
memset(((void*)world.loadedQuadrantMap), 0, (sizeof(Worldspace::Quadrant) * 9));
|
||
|
|
||
|
for (size_t i = 0; i < 3; i += 1) {
|
||
|
for (size_t j = 0; j < 3; j += 1) {
|
||
|
Worldspace::Quadrant* quadrant = (&world.loadedQuadrantMap[j + (i * 3)]);
|
||
|
|
||
|
QuadrantCoords const quadrantId = {
|
||
|
(world.player.entity.quadrantPosition.x + offset.x),
|
||
|
(world.player.entity.quadrantPosition.y + offset.y)
|
||
|
};
|
||
|
|
||
|
quadrant->id = quadrantId;
|
||
|
|
||
|
XorShifter seededGenerator = CreateXorShifter(
|
||
|
(QUADRANT_SIZE - (quadrantId.x + quadrantId.y)) * world.seed);
|
||
|
|
||
|
quadrant->starCount =
|
||
|
(size_t const)GetXorShifterValue(&seededGenerator, QUADRANT_STARS.min, QUADRANT_STARS.max);
|
||
|
|
||
|
quadrant->orbitalCount = (size_t const)GetXorShifterValue(
|
||
|
&seededGenerator, QUADRANT_ORBITALS.min, QUADRANT_ORBITALS.max);
|
||
|
|
||
|
for (size_t k = 0; k < quadrant->starCount; k += 1) {
|
||
|
quadrant->stars[k] = (Vector2){
|
||
|
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE),
|
||
|
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
for (size_t k = 0; k < quadrant->orbitalCount; k += 1) {
|
||
|
quadrant->orbitals[k] = (Worldspace::Orbital){
|
||
|
(Worldspace::OrbitalType)GetXorShifterValue(&seededGenerator, 0, 1),
|
||
|
(Vector2){
|
||
|
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE),
|
||
|
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE)
|
||
|
},
|
||
|
(float const)GetXorShifterValue(&seededGenerator, -PI, PI),
|
||
|
(((float const)GetXorShifterValue(&seededGenerator, 10, 100)) / 100.0f)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
offset.x += 1;
|
||
|
}
|
||
|
|
||
|
offset.x = -1;
|
||
|
offset.y += 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool const CheckEntityQuadrantBounds(Entity& entity, int* const xBounds, int* const yBounds) {
|
||
|
int const x = ((entity.localPosition.x > QUADRANT_RANGE) ?
|
||
|
1 : ((entity.localPosition.x < -QUADRANT_RANGE) ? -1 : 0));
|
||
|
|
||
|
int const y = ((entity.localPosition.y > QUADRANT_RANGE) ?
|
||
|
1 : ((entity.localPosition.y < -QUADRANT_RANGE) ? -1 : 0));
|
||
|
|
||
|
if (xBounds) {
|
||
|
*xBounds = x;
|
||
|
}
|
||
|
|
||
|
if (yBounds) {
|
||
|
*yBounds = y;
|
||
|
}
|
||
|
|
||
|
return !(x || y);
|
||
|
}
|
||
|
|
||
|
EntityUpdateInfo const UpdateEntity(Entity& entity) {
|
||
|
int quadrantBoundsCheckX;
|
||
|
int quadrantBoundsCheckY;
|
||
|
EntityUpdateInfo info = {0};
|
||
|
|
||
|
if (CheckEntityQuadrantBounds(entity, &quadrantBoundsCheckX, &quadrantBoundsCheckY)) {
|
||
|
entity.localPosition += entity.speed;
|
||
|
info.hasMoved = true;
|
||
|
} else {
|
||
|
if (quadrantBoundsCheckX) {
|
||
|
entity.localPosition.x = ((QUADRANT_RANGE * -quadrantBoundsCheckX) + entity.speed.x);
|
||
|
entity.quadrantPosition.x += quadrantBoundsCheckX;
|
||
|
}
|
||
|
|
||
|
if (quadrantBoundsCheckY) {
|
||
|
entity.localPosition.y = ((QUADRANT_RANGE * -quadrantBoundsCheckY) + entity.speed.y);
|
||
|
entity.quadrantPosition.y += quadrantBoundsCheckY;
|
||
|
}
|
||
|
|
||
|
info.hasPassedQuadrant = true;
|
||
|
info.hasMoved = true;
|
||
|
}
|
||
|
|
||
|
return info;
|
||
|
}
|