SFML community forums

Help => General => Topic started by: Oakvalley on June 27, 2017, 09:46:03 pm

Title: Frame-speed on animation
Post by: Oakvalley on June 27, 2017, 09:46:03 pm
Hi, I have a problem regarding updating animation, like many other people I have a problem with it updating to fast.
I've read so many other post from everywhere but i'm not just smart enough to understand it ^^

my main loop looks like this:
Code: [Select]
while (!game.GetWindow()->GetIsDone()) {
game.HandleInput();
game.Update();
game.Render();
game.RestartClock();
}

inside of game.RestartClock(); I just set
Code: [Select]
void RestartClock() { m_elapsed = m_clock.restart(); }

m_elapsed if of datatype sf::Time.
My first thought is that it should be m_clock.restart().AsSeconds(); but I don't know.

In my Game class i just pass m_elapsed to my Animation update function.
Code: [Select]
void Game::Animate() {

m_animation.Update(m_elapsed, *(m_beardedDragon.GetSprite()));
}

inside my Animation class this is what i'm doing atm:
Code: [Select]
void Animation::Update(sf::Time p_time, sf::Sprite& p_sprite)
{

if (m_active) {
float test = p_time.asSeconds();
std::cout << test << std::endl;
m_frameCounter += 1000 * test; //tested with 1000 and it updates more correctly,
   //seems to go faster after a while...
}

if (m_frameCounter >= m_switchFrame) {
m_frameCounter = 0;
m_currentFrame.x += m_frameSize.x;
if (m_currentFrame.x >= p_sprite.getTexture()->getSize().x) {
m_currentFrame.x = 0;
}
}
p_sprite.setTextureRect(sf::IntRect(m_currentFrame.x, m_currentFrame.y, m_frameSize.x, m_frameSize.y));
}

switchFrame is 60.

What I try to achieve is to have a framerate that not jitter around, and ideally have it set to like 60fps.
Am I somewhat on the right track?

Would love to get some input.
EDIT2: Nope. It goes faster after a while.

i've tried:
Code: [Select]
if (m_position.x != 0.f && m_position.y != 0.f)
m_position /= std::sqrt(2.f);
But it does not work as intended.

Thanks in advance!


Title: Re: Frame-speed on animation
Post by: Gleade on June 28, 2017, 02:05:06 am
You will want the animation to update based on time. For example; every 0.25 seconds that have passed you increment the current frame by 1. That magical "0.25" seconds I mentioned would be your frame speed. You can achieve this by having a counter variable that stores the elapsed time since the last frame update, once that counter reaches the "frame speed", we increment the frame & set the counter back to 0.
Title: Re: Frame-speed on animation
Post by: Oakvalley on June 28, 2017, 05:42:22 am
Thanks, will try it as soon as I can. :)
Title: Re: Frame-speed on animation
Post by: Oakvalley on June 28, 2017, 10:06:23 am
So I tried my best to follow what you said.

This is how it is now:
Code: [Select]
void Animation::Update(sf::Sprite& p_sprite, sf::Time &p_time)
{
m_elapsed = p_time.asSeconds();
if (m_active) {
m_frameCounter += m_frameSpeed * m_elapsed;
}

std::cout << "frameCounter: " << m_frameCounter << std::endl;
if (m_frameCounter >= m_frameSpeed) {
//m_elapsed = 0.0f;
m_frameCounter = 0;
m_currentFrame.x += m_frameSize.x;
if (m_currentFrame.x >= p_sprite.getTexture()->getSize().x) {
m_currentFrame.x = 0;
}
}
p_sprite.setTextureRect(sf::IntRect(m_currentFrame.x, m_currentFrame.y, m_frameSize.x, m_frameSize.y));
}

It is indeed working as intended. But shouldn't I utilize getElapsedTime() instead? I guess it's there for a reason. Have to keep reading c++ books to understand more.
Sorry for writing with honestly not enough knowledge. Have to start somewhere I guess.

Cheers.