Sign in to follow this  

Implement a camera shake

This topic is 4357 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

My way of doing this was to take several random points in a certain radius, and then construct a spline based on them. Using TCB you can choose proper coefficients for desired smoothness/"sharpness".

Then use it as an offset for, say, 3 seconds long amount of time.

Share this post


Link to post
Share on other sites
Here's a small sample from my engine's API. I have incorporated shaking into Renderer class.

Header:


//! Only sets some values, actual shaking will appear on the next frame and will last for _time miliseconds.
void ShakeScreen(int _factorX, int _factorY, ulint _time);

void SetShakeBoundaries(int _boundaryX, int _boundaryY)
{
boundaryX = _boundaryX;
boundaryY = _boundaryY;
}

//! Immediately sets shake screen state to given _state
void SetShakeScreenState(bool _state) { shakeScreenEnabled = _state; }

//! Returns actual shake screen state
bool GetShakeScreenState() const { return shakeScreenEnabled; }

void UpdateShakeState();

// -------------------------------------------------

private:

bool shakeScreenEnabled;
float shakeFactorX, shakeFactorY;
TimeMarker shakeStart;
ulint shakeTime;
int boundaryX, boundaryY;



Implementation:



// ------------------------------------------------- start Render

void SC :: Renderer :: Render()
{
if (shakeScreenEnabled && shakeTime)
{
UpdateShakeState();
}

SDL_GL_SwapBuffers();
}

// ------------------------------------------------- end Render

// ------------------------------------------------- start ShakeScreen

void SC :: Renderer :: ShakeScreen(int _factorX, int _factorY, ulint _time)
{
// multiple users can call ShakeScreen, screen should be shaked for the longest time
if (shakeTime == 0)
{
shakeTime = _time;
glPushMatrix();
shakeStart.Mark();
}
else
{
shakeTime = Max(shakeTime, _time);
}

shakeFactorX += _factorX;
shakeFactorY += _factorY;

}

// ------------------------------------------------- end ShakeScreen

// ------------------------------------------------- start UpdateShakeState

void SC :: Renderer :: UpdateShakeState()
{
if (shakeStart.HasElapsed(shakeTime))
{
shakeTime = 0;
shakeStart.Reset();
glPopMatrix();
shakeFactorX = 0;
shakeFactorY = 0;
return;
}
else
{
int sign = 1;
if (getRandGen.Integer(100) > 50)
sign = -1;

glPopMatrix();
glPushMatrix();

float timeLeft = ( (float) shakeTime - (float) shakeStart.HowManyElapsed() + 1) / 1000.0f;

float shakeX = sign * timeLeft * (getRandGen.FloatingPoint( shakeFactorX * 8 ) / 8) ;
float shakeY = sign * timeLeft * (getRandGen.FloatingPoint( shakeFactorY * 8 ) / 8) ;

shakeX -= 10 * getTimer.GetDeltaTime();
shakeY -= 10 * getTimer.GetDeltaTime();

shakeX = ClampTo(shakeX, (float) -boundaryX, (float) boundaryX);
shakeY = ClampTo(shakeY, (float) -boundaryY, (float) boundaryY);

glTranslatef( shakeX, shakeY, 0 );
}
}

// ------------------------------------------------- end UpdateShakeState




Sample usage:



if ( getInput.GetMouseButtonNowPressed(mb_Left) )
getRenderer.ShakeScreen(2, 2, 15000); // will shake a little for 15 seconds




You can see how this this shake looks in real world game - it's been used in "Herbata Kto Ty Tak Kroliczk" (link in sig).

HTH :-)

Share this post


Link to post
Share on other sites

This topic is 4357 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this