summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2017-12-21 11:29:41 +0100
committerPaweł Redman <pawel.redman@gmail.com>2017-12-21 11:29:41 +0100
commit6eed8de736ff18a2aed65cd9ba62c6a7b5d18c59 (patch)
tree524692f5063254f51bcba65490fbe69ad069bc35 /src
parentf01e03f6b858c27e54c561f2b430853ada2f2268 (diff)
Vastly improve following.
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp22
-rw-r--r--src/game/interface.cpp89
2 files changed, 67 insertions, 44 deletions
diff --git a/src/common.hpp b/src/common.hpp
index 7221b44..87706c8 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -266,13 +266,16 @@ namespace interface {
float em;
struct {
+ v2f_t zero_point_s = v2f_t(0, 0);
v2f_t center = v2f_t(0, 0);
- int target_zoom = 3;
- float zoom = 3.0f;
+
+ int zoom = 3;
+ float zoom_s = 3.0f;
+
bool panning = false;
sf::Vector2f pan_ref;
+
bool following = true;
- v2f_t follow_center = v2f_t(0, 0);
} camera;
struct {
@@ -290,6 +293,8 @@ namespace interface {
double perf_hist[10] = {0};
size_t perf_hist_index = 0;
+ void start_following(void);
+ void stop_following(void);
public:
state_t(sf::RenderWindow *window_, game::state_t *game);
void tick(double dt);
@@ -408,7 +413,14 @@ T bilerp(T a, T b, T c, T d, T x, T y)
return lerp(ab, cd, y);
}
-static inline float expfade(float a, float b, float l, float dt)
+template <typename T>
+static inline void expfade(T *a, T b, T l, T dt)
+{
+ *a = b + (*a - b) * exp(-l * dt);
+}
+
+template <typename T, size_t N>
+static inline void expfade(vec_t<T, N> *a, vec_t<T, N> b, float l, float dt)
{
- return b + (a - b) * exp(-l * dt);
+ *a = b + (*a - b) * exp(-l * dt);
}
diff --git a/src/game/interface.cpp b/src/game/interface.cpp
index 1300e95..7697a22 100644
--- a/src/game/interface.cpp
+++ b/src/game/interface.cpp
@@ -35,56 +35,72 @@ static sf::Vector2f compute_pan(sf::RenderWindow *window, sf::Vector2f pan_ref)
return -(vmouse - pan_ref);
}
+void state_t::start_following(void)
+{
+ camera.following = true;
+ camera.zero_point_s = camera.center;
+ camera.center = v2f_t(0, 0);
+ print(text::get(text::FOLLOWING_ON));
+}
+
+void state_t::stop_following(void)
+{
+ camera.following = false;
+ camera.center += camera.zero_point_s;
+ camera.zero_point_s = v2f_t(0, 0);
+ print(text::get(text::FOLLOWING_OFF));
+}
+
void state_t::tick(double dt)
{
- sf::Vector2u size;
+ vec_t<int, 2> window_size;
sf::Event event;
- sf::Vector2f view_size;
- v2f_t wmouse; // Mouse position in world space;
+
+ v2f_t view_size;
v2f_t follow_center(0, 0), view_center, pan_delta;
float view_scale;
+ v2f_t wmouse; // Mouse position in world space;
- size = window->getSize();
+ window_size = window->getSize();
- camera.zoom = expfade(camera.zoom, camera.target_zoom, 15, dt);
- view_scale = 4.5 * exp(camera.zoom * 0.12);
- if (size.x < size.y) {
- view_size.y = view_scale;
- view_size.x = view_scale * size.x / size.y;
+ expfade<float>(&camera.zoom_s, camera.zoom, 15, dt);
+ view_scale = 4.5 * exp(camera.zoom_s * 0.12);
+ if (window_size[0] < window_size[1]) {
+ view_size[1] = view_scale;
+ view_size[0] = view_scale * window_size[0] / window_size[1];
} else {
- view_size.x = view_scale;
- view_size.y = view_scale * size.y / size.x;
+ view_size[0] = view_scale;
+ view_size[1] = view_scale * window_size[1] / window_size[0];
}
- if (!game->selected_units.size() && camera.following) {
- camera.center = camera.follow_center;
- print(text::get(text::FOLLOWING_OFF));
- camera.following = false;
- }
+ if (!game->selected_units.size() && camera.following)
+ stop_following();
if (camera.following) {
+ float limit;
+
for (entity_t *ent : game->selected_units)
follow_center += ent->render_bounds.center();
follow_center /= game->selected_units.size();
- camera.follow_center[0] = expfade(camera.follow_center[0], follow_center[0], dt, 25);
- camera.follow_center[1] = expfade(camera.follow_center[1], follow_center[1], dt, 25);
- }
-
- view_center = camera.center;
+ expfade<float, 2>(&camera.zero_point_s, follow_center, 15, dt);
- if (camera.following)
- view_center += camera.follow_center;
+ limit = view_scale * 0.2f;
+ if (camera.center.len() > limit * 2.0f)
+ stop_following();
+ else if (camera.center.len() > limit)
+ expfade<float, 2>(&camera.center, camera.center.norm() * limit, 3, dt);
+ }
+ view_center = camera.zero_point_s + camera.center;
window->setView(sf::View(view_center, view_size));
if (camera.panning) {
pan_delta = compute_pan(window, camera.pan_ref);
view_center += compute_pan(window, camera.pan_ref);
+ window->setView(sf::View(view_center, view_size));
}
- window->setView(sf::View(view_center, view_size));
-
wmouse = window->mapPixelToCoords(sf::Mouse::getPosition(*window));
while (window->pollEvent(event)) {
@@ -134,11 +150,11 @@ void state_t::tick(double dt)
break;
case sf::Event::MouseWheelScrolled:
- camera.target_zoom -= event.mouseWheelScroll.delta;
- if (camera.target_zoom < 0)
- camera.target_zoom = 0;
- if (camera.target_zoom > 17)
- camera.target_zoom = 17;
+ camera.zoom -= event.mouseWheelScroll.delta;
+ if (camera.zoom < 0)
+ camera.zoom = 0;
+ if (camera.zoom > 17)
+ camera.zoom = 17;
break;
case sf::Event::KeyPressed:
@@ -152,15 +168,10 @@ void state_t::tick(double dt)
break;
case sf::Keyboard::Key::F:
- camera.following ^= 1;
-
- if (!camera.following) {
- camera.center = view_center;
- print(text::get(text::FOLLOWING_OFF));
- } else {
- camera.center = v2f_t(0, 0);
- print(text::get(text::FOLLOWING_ON));
- }
+ if (camera.following)
+ stop_following();
+ else
+ start_following();
break;
case sf::Keyboard::Key::H: