summaryrefslogtreecommitdiff
path: root/src/gui/viewport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/viewport.cpp')
-rw-r--r--src/gui/viewport.cpp100
1 files changed, 51 insertions, 49 deletions
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index cdc4076e..8dbdf7c7 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -79,8 +79,6 @@ void Viewport::setMap(Map *map)
void Viewport::draw(gcn::Graphics *gcnGraphics)
{
- static int lastTick = tick_time;
-
// Check whether map was successfully loaded since
// the rest of this function relies on it
if (!mMap || !local_player)
@@ -95,12 +93,6 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
auto *graphics = static_cast<Graphics*>(gcnGraphics);
- // Avoid freaking out when tick_time overflows
- if (tick_time < lastTick)
- {
- lastTick = tick_time;
- }
-
// Calculate viewpoint
int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 2;
int midTileY = (graphics->getHeight() + mScrollCenterOffsetX) / 2;
@@ -109,49 +101,57 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
const int player_x = (int) playerPos.x - midTileX;
const int player_y = (int) playerPos.y - midTileY;
- if (mScrollLaziness < 1)
- mScrollLaziness = 1; // Avoids division by zero
+ const float ticks = Time::deltaTimeMs() / static_cast<float>(MILLISECONDS_IN_A_TICK);
+ float scrollFraction = 1.0f;
- while (lastTick < tick_time)
+ if (mScrollLaziness > 1)
{
- // Apply lazy scrolling
- if (player_x > mPixelViewX + mScrollRadius)
- {
- mPixelViewX += (player_x - mPixelViewX - mScrollRadius) /
- mScrollLaziness;
- }
- if (player_x < mPixelViewX - mScrollRadius)
- {
- mPixelViewX += (player_x - mPixelViewX + mScrollRadius) /
- mScrollLaziness;
- }
- if (player_y > mPixelViewY + mScrollRadius)
- {
- mPixelViewY += (player_y - mPixelViewY - mScrollRadius) /
- mScrollLaziness;
- }
- if (player_y < mPixelViewY - mScrollRadius)
- {
- mPixelViewY += (player_y - mPixelViewY + mScrollRadius) /
- mScrollLaziness;
- }
+ // mScrollLaziness defines the fraction of the desired camera movement
+ // that is applied every 10ms. To make this work independently of the
+ // frame duration, we calculate the actual scroll fraction based on the
+ // time delta.
+ scrollFraction = 1.0f - std::pow(1.0f - 1.0f / mScrollLaziness, ticks);
+ }
+
+ // Apply lazy scrolling
+ if (player_x > mPixelViewX + mScrollRadius)
+ {
+ mPixelViewX += (player_x - mPixelViewX - mScrollRadius) *
+ scrollFraction;
+ }
+ if (player_x < mPixelViewX - mScrollRadius)
+ {
+ mPixelViewX += (player_x - mPixelViewX + mScrollRadius) *
+ scrollFraction;
+ }
+ if (player_y > mPixelViewY + mScrollRadius)
+ {
+ mPixelViewY += (player_y - mPixelViewY - mScrollRadius) *
+ scrollFraction;
+ }
+ if (player_y < mPixelViewY - mScrollRadius)
+ {
+ mPixelViewY += (player_y - mPixelViewY + mScrollRadius) *
+ scrollFraction;
+ }
+
+ // manage shake effect
+ for (auto i = mShakeEffects.begin(); i != mShakeEffects.end(); i++)
+ {
+ // The decay defines the reduction in amplitude per 10ms. Here
+ // we calculate the reduction based on the ticks.
+ const float decay = std::pow(i->decay, ticks);
+
+ // apply the effect to viewport
+ mPixelViewX += i->x *= -decay;
+ mPixelViewY += i->y *= -decay;
- // manage shake effect
- for (auto i = mShakeEffects.begin();
- i != mShakeEffects.end();
- i++)
+ // check death conditions
+ if (std::abs(i->x) + std::abs(i->y) < 1.0f ||
+ (i->timer.isSet() && i->timer.passed()))
{
- // apply the effect to viewport
- mPixelViewX += i->x *= -i->decay;
- mPixelViewY += i->y *= -i->decay;
- // check death conditions
- if (abs(i->x) + abs(i->y) < 1.0f ||
- (i->duration > 0 && --i->duration == 0))
- {
- i = mShakeEffects.erase(i);
- }
+ i = mShakeEffects.erase(i);
}
- lastTick++;
}
// Auto center when player is off screen
@@ -264,7 +264,9 @@ void Viewport::shakeScreen(float x, float y, float decay, unsigned duration)
effect.x = x;
effect.y = y;
effect.decay = decay;
- effect.duration = duration;
+
+ if (duration > 0)
+ effect.timer.set(duration * MILLISECONDS_IN_A_TICK);
}
void Viewport::logic()
@@ -528,9 +530,9 @@ void Viewport::mouseDragged(gcn::MouseEvent &event)
if (mPlayerFollowMouse && !event.isShiftPressed())
{
- if (get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay)
+ if (mLocalWalkTimer.passed())
{
- mLocalWalkTime = tick_time;
+ mLocalWalkTimer.set(walkingMouseDelay);
local_player->setDestination(event.getX() + (int) mPixelViewX,
event.getY() + (int) mPixelViewY);
local_player->pathSetByMouse();