From 91e2779891973cdbefc6e07ca3dee7a432a05112 Mon Sep 17 00:00:00 2001 From: Philipp Sehmisch Date: Mon, 14 Mar 2011 20:56:40 +0100 Subject: Implemented a screen shake effect system in the viewport class. The screen can either be "nudged" in a random direction with a specific intensity or you can define an exact x and y intensity, decay factor and duration. On a tmwAthena server an effect is triggered when the player character dies. A method for stopping all shake effects is also implemented, but not used yet. I added a netcode message for Manaserv to trigger an effect server-sided. Because our protocol has currently no way to transport floating point values, the decay is transported as a fixed point value with 4 decimals which is entirely sufficient for this purpose. --- src/gui/viewport.cpp | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'src/gui/viewport.cpp') diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index ac910d5f..9d03cab5 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -42,6 +42,8 @@ #include "utils/stringutils.h" +#include + extern volatile int tick_time; Viewport::Viewport(): @@ -121,9 +123,9 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) if (mScrollLaziness < 1) mScrollLaziness = 1; // Avoids division by zero - // Apply lazy scrolling while (lastTick < tick_time) { + // Apply lazy scrolling if (player_x > mPixelViewX + mScrollRadius) { mPixelViewX += (player_x - mPixelViewX - mScrollRadius) / @@ -144,6 +146,22 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) mPixelViewY += (player_y - mPixelViewY + mScrollRadius) / mScrollLaziness; } + + // manage shake effect + for (ShakeEffects::iterator i = mShakeEffects.begin(); + i != mShakeEffects.end(); + i++) + { + // 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); + } + } lastTick++; } @@ -222,6 +240,24 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) WindowContainer::draw(gcnGraphics); } +void Viewport::shakeScreen(int intensity) +{ + float direction = rand()%628 / 100.0f; // random value between 0 and 2PI + float x = std::sin(direction) * intensity; + float y = std::cos(direction) * intensity; + shakeScreen(x, y); +} + +void Viewport::shakeScreen(float x, float y, float decay, unsigned duration) +{ + ShakeEffect effect; + effect.x = x; + effect.y = y; + effect.decay = decay; + effect.duration = duration; + mShakeEffects.push_back(effect); +} + void Viewport::logic() { WindowContainer::logic(); -- cgit v1.2.3-60-g2f50