Jump to content
  • Advertisement
Sign in to follow this  
nachilau

Implement a camera shake

This topic is 4663 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

Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!