Add configuration option for ghost reset distance. Improve documentation.

This commit is contained in:
2025-12-20 17:12:58 -05:00
parent faf3f239d8
commit 7a3705d342
25 changed files with 132 additions and 28 deletions

View File

@@ -22,6 +22,7 @@
#include "text.h"
#include "config.h"
// Forward declarations for GLFW callbacks configured at start-up.
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
@@ -40,6 +41,7 @@ float timed = 0.0f;
float last_frame = 0.0f;
float camera_speed = 20.0f;
float ghost_reset_distance = 10.0f;
const char *projectionC = "projection";
const char *viewC = "view";
@@ -69,10 +71,12 @@ int main(int argc, char *argv[]) {
glm::vec3 start_position;
float start_yaw;
// Load configuration
// Load configuration knobs before spinning up the world.
Config::loadFromFile("ghostland.json");
camera_speed = Config::getFloat("camera_speed", camera_speed);
ghost_reset_distance = Config::getFloat("ghost_reset_distance", ghost_reset_distance);
// Maze file contains serialized spawn and wall mesh data generated by mazeparser.py.
FILE *fp = fopen("maze.txt", "r");
float yaw;
if (fscanf(fp, "%f %f %f %f\n", &position.x, &position.y, &position.z, &yaw) == EOF) {
@@ -150,6 +154,7 @@ int main(int argc, char *argv[]) {
}
fclose(fp);
// Initialize GLFW/GLAD and windowing.
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
@@ -366,6 +371,7 @@ int main(int argc, char *argv[]) {
int FPS = -1;
// Main render/game loop.
while (!glfwWindowShouldClose(window))
{
float current_frame = static_cast<float>(glfwGetTime());
@@ -428,7 +434,7 @@ int main(int argc, char *argv[]) {
glm::vec3 light_front = player->get_light_front();
//printf("light_pos: (%f, %f, %f)\n", light_front.x, light_front.y, light_front.z);
// Sort ghosts by distance to player for optimization
// Sort ghosts by distance to player for optimization.
glm::vec3 player_pos = player->get_pos();
struct {
bool operator()(const Ghost *a, const Ghost *b) const {
@@ -441,6 +447,7 @@ int main(int argc, char *argv[]) {
return a_dist < b_dist;
}
} ghost_compare;
// Only the closest 20% need perfect ordering for blending, so partial_sort is cheaper than full sort.
std::partial_sort(ghosts.begin(), ghosts.begin() + ghosts.size() / 5, ghosts.end(), ghost_compare);
// Calculate nearest ghost distance (first ghost is now closest)
@@ -522,15 +529,15 @@ int main(int argc, char *argv[]) {
glm::mat4 ghost_model = ghosts[i]->get_model(camera_pos);
ghosts[i]->apply_movement(current_frame, timed);
// Check if ghost is within 10.0 units of player
// When ghosts close in, reset player back to the maze entrance.
glm::vec3 ghost_pos = ghosts[i]->get_pos();
glm::vec3 player_pos = player->get_pos();
float distance = glm::length(ghost_pos - player_pos);
if (distance <= 10.0f) {
if (distance <= ghost_reset_distance) {
player->reset_position(start_position, start_yaw);
}
// Check if ghost is within 30.0 units of start_position
// Nudge ghosts away from the spawn area so the player gets a breather.
float start_distance = glm::length(ghost_pos - start_position);
if (start_distance <= 30.0f) {
ghosts[i]->reverse_direction_from_position(start_position);