summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2017-11-08 12:26:43 +0100
committerPaweł Redman <pawel.redman@gmail.com>2017-11-08 12:26:43 +0100
commitcdd75000effac0216588766234cfa5b3e8e304d5 (patch)
tree3832063bf12dae9e8b29c9e787d08dc75a9ba704
parentc5a621b3ebeb180d2181df35038ed856714b64e2 (diff)
Frametime-independent dynamics.
-rw-r--r--src/common.hpp15
-rw-r--r--src/game.cpp9
-rw-r--r--src/interface.cpp4
-rw-r--r--src/main.cpp19
-rw-r--r--src/render.cpp5
5 files changed, 34 insertions, 18 deletions
diff --git a/src/common.hpp b/src/common.hpp
index f89ae08..df14f6f 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -175,7 +175,7 @@ namespace game {
class unit_t;
class state_t {
- double now;
+ double now, dt;
std::unordered_set<unit_t*> units;
std::unordered_set<unit_t*> selected_units;
@@ -185,7 +185,7 @@ namespace game {
void start(void);
void stop(void);
- void tick(double now_);
+ void tick(double now_, double dt_);
// These are called by the interface.
void select(rectf_t rect);
@@ -213,7 +213,7 @@ namespace interface {
public:
state_t(sf::RenderWindow *window_, game::state_t *game);
- void tick(void);
+ void tick(double dt);
void render_to(render::state_t *render);
};
}
@@ -264,10 +264,10 @@ namespace render {
void drender_text(rectf_t rect, std::string str);
void drender_entity(world::entity_t *ent);
public:
- double now;
+ double now, dt;
state_t(sf::RenderWindow *window_);
- void begin_frame(double time_);
+ void begin_frame(double time_, double dt_);
void end_frame(void);
void render(game::state_t *game);
void render(animated_texture_t *anim, rectf_t bounds, bool mirror = false);
@@ -333,3 +333,8 @@ T bilerp(T a, T b, T c, T d, T x, T y)
cd = lerp(c, d, x);
return lerp(ab, cd, y);
}
+
+static inline float expfade(float a, float b, float l, float dt)
+{
+ return b + (a - b) * exp(-l * dt);
+}
diff --git a/src/game.cpp b/src/game.cpp
index bfc698d..a3af9ed 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -73,7 +73,7 @@ public:
link(world);
}
- void keep_moving(double now)
+ void keep_moving(double now, double dt)
{
float time;
@@ -83,7 +83,7 @@ public:
if (move.blocked && now < move.next_attempt)
return;
- time = 0.15; // FIXME
+ time = dt * 10;
while (time > 0.0f) {
v2f_t delta, next, x_new;
@@ -241,12 +241,13 @@ void state_t::command(v2f_t x)
unit->start_moving(x, now);
}
-void state_t::tick(double now_)
+void state_t::tick(double now_, double dt_)
{
now = now_;
+ dt = dt_;
for (unit_t *unit : units)
- unit->keep_moving(now);
+ unit->keep_moving(now, dt);
}
} //namespace game
diff --git a/src/interface.cpp b/src/interface.cpp
index 11e297e..3a6a294 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -15,7 +15,7 @@ static sf::Vector2f compute_pan(sf::RenderWindow *window, sf::Vector2f pan_ref)
return -(vmouse - pan_ref);
}
-void state_t::tick(void)
+void state_t::tick(double dt)
{
sf::Vector2u size;
sf::Event event;
@@ -24,7 +24,7 @@ void state_t::tick(void)
size = window->getSize();
- camera.zoom = (camera.zoom + camera.target_zoom) / 2;
+ camera.zoom = expfade(camera.zoom, camera.target_zoom, 15, dt);
{
float view_scale;
diff --git a/src/main.cpp b/src/main.cpp
index 1059cb6..f6a2de5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,6 +20,8 @@ int main()
render::state_t render(&window);
game::state_t game;
interface::state_t interface(&window, &game);
+ size_t frame = 0;
+ double before = NAN;
window.setVerticalSyncEnabled(false);
@@ -29,21 +31,28 @@ int main()
game.start();
while (1) {
- double now = (nano_clock() - t0) * 1.0e-9;
+ double now = (nano_clock() - t0) * 1.0e-9, dt;
- game.tick(now);
- interface.tick();
+ if (frame)
+ dt = now - before;
+ else
+ dt = 0.01;
+
+ game.tick(now, dt);
+ interface.tick(dt);
if (!window.isOpen())
break;
window.clear();
- render.begin_frame(now);
+ render.begin_frame(now, dt);
render.render(&game);
interface.render_to(&render);
render.end_frame();
+
+ before = now;
+ frame++;
}
game.stop();
-
return 0;
}
diff --git a/src/render.cpp b/src/render.cpp
index 259d898..d1b9752 100644
--- a/src/render.cpp
+++ b/src/render.cpp
@@ -65,9 +65,10 @@ state_t::state_t(sf::RenderWindow *window_)
font.loadFromFile("assets/LiberationMono-Regular.ttf");
}
-void state_t::begin_frame(double time_)
+void state_t::begin_frame(double now_, double dt_)
{
- now = time_;
+ now = now_;
+ dt = dt_;
window->clear();
}