diff --git a/circular_maze.cpp b/circular_maze.cpp index 93818787958ed6ee278da75bcb955a856bd382f8..14304155656b3f0713f25c37d7f2e4cad0793752 100644 --- a/circular_maze.cpp +++ b/circular_maze.cpp @@ -84,6 +84,7 @@ class circular_maze range2f bounds; float corridor_radius; + float wall_wdith; float initial_radius; float2 center; @@ -144,6 +145,7 @@ class circular_maze fov_range{-fov/2,+fov/2}, bounds{fit(screen_size,{cord_length(fov),1.f})}, corridor_radius( size(bounds).y() / (layers+2) ), + wall_wdith(corridor_radius/6), initial_radius(corridor_radius * 2), center{bounds.lower()+(bounds.upper() - bounds.lower()) * float2{0.5f,1.f}} { @@ -183,10 +185,10 @@ class circular_maze const float2& screen_size() { return _screen_size; } - float hit_test(float angle, float level, const float_NxN& elements) + std::optional<float> hit_test(float angle, float level, const float_NxN& elements) { if(level < 0 || level >= layers) - return -1; + return std::nullopt; for(auto&& element : elements[level]) { @@ -196,30 +198,30 @@ class circular_maze if(quadrance(player_position - element_position) < corridor_radius * corridor_radius / 4) return element; } - return -1; + return std::nullopt; } - bool wall_hit_test(float angle) + std::optional<float> wall_hit_test(float angle) { - return -1 != hit_test(angle, player_level, walls); + return hit_test(angle, player_level, walls); } - float path_hit_test_up(float angle) + std::optional<float> path_hit_test_up(float angle) { return hit_test(angle, player_level + 1, paths); } - float path_hit_test_up(float angle, float level) + std::optional<float> path_hit_test_up(float angle, float level) { return hit_test(angle, level + 1, paths); } - float path_hit_test_down(float angle) + std::optional<float> path_hit_test_down(float angle) { return hit_test(angle, player_level, paths); } - float path_hit_test_down(float angle, float level) + std::optional<float> path_hit_test_down(float angle, float level) { return hit_test(angle, level, paths); } @@ -233,7 +235,6 @@ class circular_maze auto fov_range_up = fov_range - 1.f/4; - constexpr float wall_wdith = 6; {auto sketch = frame.begin_sketch(); float radius = initial_radius; @@ -246,10 +247,10 @@ class circular_maze } {auto sketch = frame.begin_sketch(); - float radius = initial_radius; + float radius = initial_radius - corridor_radius/2; for(size_t level = 0; level < paths.size(); ++level) { - float path_arc_angle = corridor_radius/tau/radius; + float path_arc_angle = (corridor_radius * 0.8)/tau/radius; auto path_arc_range = range{-path_arc_angle, path_arc_angle}/2; for(size_t angle = 0; angle < paths[level].size(); ++angle) { @@ -259,7 +260,9 @@ class circular_maze if(!(fov_range_up + 1.f).intersects(path_arc_range + path_angle)) continue; - sketch.arc(center, (path_arc_range + path_angle) * tau, radius - corridor_radius/2); + // TODO: approximate arc with a polygin so that we don't need to convert to radians, + // here and everywhere + sketch.arc(center, (path_arc_range + path_angle) * tau, radius); } radius += corridor_radius; } sketch.line_width(wall_wdith + 3).outline(0x1d4151_rgb); } @@ -366,10 +369,12 @@ using circular_motion_t = motion<float, quadratic_curve>; symphony<circular_motion_t, radial_motion_t> radial_motion; -float target_player_level = maze.player_level; - -float upway = -1; -float downway = -1; +struct radial_movement +{ + float path = 0; + float level = 0; +}; +std::queue<radial_movement> radial_movements; bool diagram = false; @@ -382,15 +387,27 @@ void start(Program& program) switch(code) { case scancode::j: - downway = maze.path_hit_test_down(maze.current_angle, target_player_level); - if(downway > 0) - target_player_level -= 1; + { + auto level = !empty(radial_movements) ? radial_movements.back().level : maze.player_level; + auto angle = !empty(radial_movements) + ? wrap(3/4.f - radial_movements.back().path, 1.f) + : maze.current_angle; + auto path = maze.path_hit_test_down(angle, level); + if(path) + radial_movements.push({*path, level - 1}); + } break; case scancode::k: - upway = maze.path_hit_test_up(maze.current_angle, target_player_level); - if(upway > 0) - target_player_level += 1; + { + auto level = !empty(radial_movements) ? radial_movements.back().level : maze.player_level; + auto angle = !empty(radial_movements) + ? wrap(3/4.f - radial_movements.back().path, 1.f) + : maze.current_angle; + auto path = maze.path_hit_test_up(angle, level); + if(path) + radial_movements.push({*path, level + 1}); + } break; case scancode::d: @@ -423,19 +440,23 @@ void start(Program& program) if(!radial_motion.done()) { float unwrapped_angle = maze.current_angle; - radial_motion.move(std::forward_as_tuple( + auto result = radial_motion.move(std::forward_as_tuple( unwrapped_angle, maze.player_level) , delta); maze.current_angle = wrap(unwrapped_angle, 1.f); + + if(!result.success) + radial_movements.pop(); } else { - if(target_player_level != maze.player_level) + if(!empty(radial_movements)) { - auto way = target_player_level > maze.player_level ? upway : downway; - auto circular_distance = mod_difference(maze.current_angle, wrap(3/4.f - way, 1.f), 1.f); - auto radial_distance = target_player_level - maze.player_level; + auto movement = radial_movements.front(); + + auto circular_distance = mod_difference(maze.current_angle, wrap(3/4.f - movement.path, 1.f), 1.f); + auto radial_distance = movement.level - maze.player_level; radial_motion = symphony( circular_motion_t{ maze.current_angle, @@ -443,7 +464,7 @@ void start(Program& program) abs(circular_distance) * 10s}, radial_motion_t{ maze.player_level, - target_player_level, + movement.level, abs(radial_distance) * 100ms} ); } diff --git a/common/motion.hpp b/common/motion.hpp index 4d1c4f1e39f473c2f897ae5501a34bc689a5f3cf..b7e72e09cc0d21c7ea61609d7fe3339d045306bc 100644 --- a/common/motion.hpp +++ b/common/motion.hpp @@ -189,4 +189,6 @@ class symphony } }; +class conductor; // TODO: dynamic symphony with all strings attached + #endif /* end of include guard */ diff --git a/common/sketchbook.hpp b/common/sketchbook.hpp index 5b7e8a9315e637ba65730d203a1847532371946b..4ead34ad1c1d1fa4b11d2c32c1cb0485a5eac817 100644 --- a/common/sketchbook.hpp +++ b/common/sketchbook.hpp @@ -7,7 +7,7 @@ #include <random> #include <vector> #include <array> -#include <deque> +#include <queue> #include "simple/support.hpp" #include "simple/graphical.hpp"