// rectilinear distance is good enough for this case
float dist(const sf::Vector2f& a, const sf::Vector2f& b)
{
return std::abs(a.x - b.x) + std::abs(a.y - b.y);
}
void Player::setNextPosition()
{
// remove the first character of the route as the corresponding position was reached
if(!route.empty())
route.erase(route.begin())
// set the next position
if(!route.empty())
switch(route[0])
{
case '0':
m_nextPosition += sf::Vector2f(32, 0);
break;
case '1':
m_nextPosition += sf::Vector2f(0, 32);
break;
case '2':
m_nextPosition += sf::Vector2f(-32, 0);
break;
case '3':
m_nextPosition += sf::Vector2f(0, -32);
break;
}
}
void Player::update(sf::Time frameTime)
{
float toTravel = m_speed * frameTime.asSeconds(); // distance to travel
// while the player can travel and the route is not finished
while(toTravel > 0.f && !route.empty())
{
float toNext = dist(m_position, m_nextPosition); // distance to the next position on the route
if(toNext >= toTravel)
{
// go towards the next position
m_position += toTravel * (m_nextPosition - m_position) / toNext;
toTravel = 0.f;
}
else
{
// go to the next position
m_position = m_nextPosition;
toTravel -= toNext;
// and update the next position
setNextPosition();
}
}
}