Original Post
Hi folks,
I'm working on a simple game (basically pong meets breakout) and am trying to implement framerate-independant movement.
I'm polling my Timer object for a speedfactor (= seconds per frame) and multiplying my movement with this number. This causes my objects to move VERY slowly - obviously I'm not doing this right. I used to multiply with "deltaTime" (= seconds since last frame) but the results are the same.
Is this a rounding error or something - what am I not getting here?
Timer object (polled function is getSpf())
[source lang="cpp"]
#include "Timer.h"
#include "defines.h"
/*
double m_secondsPerCount;
double m_deltaTime;
__int64 m_baseTime;
__int64 m_pausedTime;
__int64 m_stopTime;
__int64 m_prevTime;
__int64 m_currTime;
boom m_bStopped;
*/
Timer::Timer()
: m_secondsPerCount(0.0),
m_deltaTime(-1.0),
m_baseTime(0),
m_pausedTime(0),
m_prevTime(0),
m_currTime(0),
m_stopTime(0),
m_bStopped(false)
{
__int64 countsPerSecond;
QueryPerformanceFrequency((LARGE_INTEGER*) &countsPerSecond);
m_secondsPerCount = 1.0 / (double)countsPerSecond;
}
Timer::~Timer()
{
}
void Timer::tick()
{
if(m_bStopped)
{
m_deltaTime = 0.0;
return;
}
//get the time this frame
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*) ¤tTime);
m_currTime = currentTime;
//time difference between this frame and the previous frame in seconds
m_deltaTime = (m_currTime - m_prevTime) * m_secondsPerCount;
//prepare for the next frame
m_prevTime = m_currTime;
//threading or power save mode can cause non-negative values for delta time
//we correct this here
if(m_deltaTime < 0.0)
m_deltaTime = 0.0;
}
float Timer::getGameTime() const
{
//if we're stopped, get frequency difference between start and stop
//then translate the difference into seconds
if(m_bStopped)
return (float)((m_stopTime - m_baseTime) * m_secondsPerCount);
else //same idea but we need to remove the amount of paused time
return (float)(((m_currTime - m_pausedTime) - m_baseTime) * m_secondsPerCount);
}
double Timer::getDeltaTime() const
{
return m_deltaTime;
}
double Timer::getSpf() const
{
return 1.0 / getFps();
}
short Timer::getFps() const
{
return (short) 1.0/m_deltaTime;
}
void Timer::reset()
{
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*) ¤tTime);
m_baseTime = currentTime;
m_prevTime = currentTime;
m_stopTime = 0;
m_bStopped = false;
}
void Timer::stop()
{
//if we're already stopped we don't need to do anything
if(!m_bStopped)
{
__int64 currTime;
QueryPerformanceCounter((LARGE_INTEGER*) &currTime);
//save the time at the moment we stopped
m_stopTime = m_currTime;
m_bStopped = true;
}
}
//resume timer from a stopped state
void Timer::start()
{
__int64 startTime;
QueryPerformanceFrequency((LARGE_INTEGER*) &startTime);
//if we're resuming the timer from a stopped state we need to do a few calculations
if(m_bStopped)
{
//accumumlate paused time
m_pausedTime += (startTime - m_stopTime);
m_prevTime = startTime;
m_stopTime = 0;
m_bStopped = false;
}
}
[/source]
This number is fed into a tick() function for the objects which need to move - move() is then called to perform the actual adjustments
First I multiply the direction with the speed to get the amount of pixels we move (the direction is a normalized vector). Then I multiply this result
with the speedFactor (= secondsPerFrame) in order to adjust to the frame rate. That's the theory anyway :/
[source lang="cpp"]
void Ball::tick(const double& p_secondsPerFrame)
{
XMFLOAT2 movement;
movement.x = (m_direction.x * m_speed) * p_secondsPerFrame;
movement.y = (m_direction.y * m_speed) * p_secondsPerFrame;
move(movement);
}
void Ball::move(XMFLOAT2& p_movement)
{
if(m_bInitialized)
{
m_pHitRegion->move(p_movement);
m_pBitmap->move(p_movement);
}
}
[/source]
This is the movement itself, just an addition
[source lang="cpp"]void Sprite::move(XMFLOAT2& p_movement)
{
m_position.x += p_movement.x;
m_position.y += p_movement.y;
}[/source]
Thanks for reading.
I'm working on a simple game (basically pong meets breakout) and am trying to implement framerate-independant movement.
I'm polling my Timer object for a speedfactor (= seconds per frame) and multiplying my movement with this number. This causes my objects to move VERY slowly - obviously I'm not doing this right. I used to multiply with "deltaTime" (= seconds since last frame) but the results are the same.
Is this a rounding error or something - what am I not getting here?
Timer object (polled function is getSpf())
[source lang="cpp"]
#include "Timer.h"
#include "defines.h"
/*
double m_secondsPerCount;
double m_deltaTime;
__int64 m_baseTime;
__int64 m_pausedTime;
__int64 m_stopTime;
__int64 m_prevTime;
__int64 m_currTime;
boom m_bStopped;
*/
Timer::Timer()
: m_secondsPerCount(0.0),
m_deltaTime(-1.0),
m_baseTime(0),
m_pausedTime(0),
m_prevTime(0),
m_currTime(0),
m_stopTime(0),
m_bStopped(false)
{
__int64 countsPerSecond;
QueryPerformanceFrequency((LARGE_INTEGER*) &countsPerSecond);
m_secondsPerCount = 1.0 / (double)countsPerSecond;
}
Timer::~Timer()
{
}
void Timer::tick()
{
if(m_bStopped)
{
m_deltaTime = 0.0;
return;
}
//get the time this frame
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*) ¤tTime);
m_currTime = currentTime;
//time difference between this frame and the previous frame in seconds
m_deltaTime = (m_currTime - m_prevTime) * m_secondsPerCount;
//prepare for the next frame
m_prevTime = m_currTime;
//threading or power save mode can cause non-negative values for delta time
//we correct this here
if(m_deltaTime < 0.0)
m_deltaTime = 0.0;
}
float Timer::getGameTime() const
{
//if we're stopped, get frequency difference between start and stop
//then translate the difference into seconds
if(m_bStopped)
return (float)((m_stopTime - m_baseTime) * m_secondsPerCount);
else //same idea but we need to remove the amount of paused time
return (float)(((m_currTime - m_pausedTime) - m_baseTime) * m_secondsPerCount);
}
double Timer::getDeltaTime() const
{
return m_deltaTime;
}
double Timer::getSpf() const
{
return 1.0 / getFps();
}
short Timer::getFps() const
{
return (short) 1.0/m_deltaTime;
}
void Timer::reset()
{
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*) ¤tTime);
m_baseTime = currentTime;
m_prevTime = currentTime;
m_stopTime = 0;
m_bStopped = false;
}
void Timer::stop()
{
//if we're already stopped we don't need to do anything
if(!m_bStopped)
{
__int64 currTime;
QueryPerformanceCounter((LARGE_INTEGER*) &currTime);
//save the time at the moment we stopped
m_stopTime = m_currTime;
m_bStopped = true;
}
}
//resume timer from a stopped state
void Timer::start()
{
__int64 startTime;
QueryPerformanceFrequency((LARGE_INTEGER*) &startTime);
//if we're resuming the timer from a stopped state we need to do a few calculations
if(m_bStopped)
{
//accumumlate paused time
m_pausedTime += (startTime - m_stopTime);
m_prevTime = startTime;
m_stopTime = 0;
m_bStopped = false;
}
}
[/source]
This number is fed into a tick() function for the objects which need to move - move() is then called to perform the actual adjustments
First I multiply the direction with the speed to get the amount of pixels we move (the direction is a normalized vector). Then I multiply this result
with the speedFactor (= secondsPerFrame) in order to adjust to the frame rate. That's the theory anyway :/
[source lang="cpp"]
void Ball::tick(const double& p_secondsPerFrame)
{
XMFLOAT2 movement;
movement.x = (m_direction.x * m_speed) * p_secondsPerFrame;
movement.y = (m_direction.y * m_speed) * p_secondsPerFrame;
move(movement);
}
void Ball::move(XMFLOAT2& p_movement)
{
if(m_bInitialized)
{
m_pHitRegion->move(p_movement);
m_pBitmap->move(p_movement);
}
}
[/source]
This is the movement itself, just an addition
[source lang="cpp"]void Sprite::move(XMFLOAT2& p_movement)
{
m_position.x += p_movement.x;
m_position.y += p_movement.y;
}[/source]
Thanks for reading.