SFML community forums
Help => General => Topic started 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:
while (!game.GetWindow()->GetIsDone()) {
game.HandleInput();
game.Update();
game.Render();
game.RestartClock();
}
inside of game.RestartClock(); I just set
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.
void Game::Animate() {
m_animation.Update(m_elapsed, *(m_beardedDragon.GetSprite()));
}
inside my Animation class this is what i'm doing atm:
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:
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!
-
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.
-
Thanks, will try it as soon as I can. :)
-
So I tried my best to follow what you said.
This is how it is now:
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.