From f08fb7293382dbaf240860119d128486ada62221 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Sat, 21 Oct 2017 14:40:20 +0200 Subject: Improve short paths and do some refactoring. --- src/common.hpp | 4 ++-- src/game.cpp | 36 +++++++++++++++++------------------- src/math.hpp | 6 ++++++ src/path_finder.cpp | 14 +++++++------- src/world.cpp | 22 ++++------------------ 5 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/common.hpp b/src/common.hpp index 8f610a5..79c160a 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -132,8 +132,8 @@ namespace world { ~path_finder_t(); void setup_nodes(v2f_t src_, v2f_t dst_); void find_r(tile_index_t index, float dist); - void find(void); - bool export_path(std::list *list); + bool find(void); + void export_path(std::list *list); }; } diff --git a/src/game.cpp b/src/game.cpp index 97aee59..2dab5c6 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -18,8 +18,9 @@ public: rectf_t size, render_size; struct { - bool moving; + bool moving = false; v2f_t dst; + float angle = 0.0f; std::list path; } move; @@ -38,19 +39,6 @@ public: bool move_towards(v2f_t point, float *time) { bool partial; - v2f_t delta; - - delta = point - x; - - if (delta.len() >= *time) { - partial = true; - x += delta * *time / delta.len(); - *time = 0.0f; - } else { - partial = false; - x = point; - *time -= delta.len(); - } return partial; } @@ -65,12 +53,23 @@ public: time = 0.15; while (time > 0.0f) { + v2f_t delta, next; + if (!move.path.size()) { move.moving = false; break; } - if (!move_towards(*move.path.begin(), &time)) { + next = *move.path.begin(); + delta = next - x; + move.angle = delta.angle(); + + if (delta.len() >= time) { + x += delta * time / delta.len(); + break; + } else { + x = next; + time -= delta.len(); move.path.pop_front(); } } @@ -103,11 +102,10 @@ class human_t : public unit_t { public: void render_to(render::state_t *render) { - float angle = 0; render->render((move.moving ? &assets::human.legs_walking : - &assets::human.legs_idle), render_bounds, angle); - render->render(&assets::human.body_idle, render_bounds, angle); - render->render(&assets::human.head_idle, render_bounds, angle); + &assets::human.legs_idle), render_bounds, move.angle); + render->render(&assets::human.body_idle, render_bounds, move.angle); + render->render(&assets::human.head_idle, render_bounds, move.angle); if (move.moving) render->debug_path(&move.path); diff --git a/src/math.hpp b/src/math.hpp index f3b049b..55bf438 100644 --- a/src/math.hpp +++ b/src/math.hpp @@ -193,6 +193,12 @@ public: return std::sqrt(*this * *this); } + T angle(void) + { + static_assert(N == 2, "angle called for a vector that's not 2-dimensional"); + return atan2(v[1], v[0]); + } + // Compatibility with SFML template diff --git a/src/path_finder.cpp b/src/path_finder.cpp index ab300dc..8ca0ccc 100644 --- a/src/path_finder.cpp +++ b/src/path_finder.cpp @@ -78,10 +78,13 @@ void path_finder_t::find_r(tile_index_t index, float dist) path.pop_back(); } -void path_finder_t::find(void) +bool path_finder_t::find(void) { tile_index_t start; + if ((src - dst).len() < 1.0f) + return true; + start = tile_index_at(src) - base; nodes[start[1] * width + start[0]].accessible = false; @@ -98,21 +101,18 @@ void path_finder_t::find(void) find_r(next, v2f_t(offset).len()); } + + return shortest_path.size() > 0; } -bool path_finder_t::export_path(std::list *list) +void path_finder_t::export_path(std::list *list) { - if (!shortest_path.size()) - return false; - list->clear(); for (tile_index_t &index : shortest_path) list->push_back(v2f_t(index + base) + tile_center); list->push_back(dst); - - return true; } } // namespace world diff --git a/src/world.cpp b/src/world.cpp index 307374c..895eb0f 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -66,7 +66,6 @@ bool world_t::find_path(v2f_t src, v2f_t dst, rectf_t size, std::list *path) { path_finder_t finder; - bool rv; finder.setup_nodes(src, dst); @@ -79,24 +78,11 @@ bool world_t::find_path(v2f_t src, v2f_t dst, rectf_t size, node->accessible = (get_tile(index)->type >= 1); } - finder.find(); - rv = finder.export_path(path); + if (!finder.find()) + return false; - debug.clear(); - - for (size_t y = 0; y < finder.height; y++) - for (size_t x = 0; x < finder.width; x++) { - path_node_t *node = finder.nodes + y * finder.width + x; - std::stringstream ss; - - ss << "LT " << tile_index_t(x, y) << "\n"; - ss << " T " << finder.base + tile_index_t(x, y) << "\n"; - ss << " d " << node->dist; - - debug.push_back((debug_t){finder.base + tile_index_t(x, y), ss.str()}); - } - - return rv; + finder.export_path(path); + return true; } sector_t *world_t::get_sector(sector_index_t index) -- cgit