So I have the class below which will move to the location of the mouse after the "M" key is pressed (was originally going to use right-click, but it isn't registering my trackpad's right clicks), provided the sprite was clicked on first. Obviously I want it to be able to do this multiple times and at a fixed speed, so this presents two problems with my implementation:
1) If I tell the ship to move to a point whose x AND y coordinates are smaller than the current position, it just teleports there instantly; if the ships moves to point whose x OR y coordinate is smaller than the current position, it reaches the point in the appropriate amount of time ('timeToReach'), but then it just flies past and keeps moving on forever in that direction.
2) I am just not sure how exactly to implement fixed speed; 'moveToRightClick' will cause the ship to traverse any distance, big or small, in 'timeToReach' amount of time. How do I get it to move with a fixed speed of let's say 20 pixels a second, for example?
class Ship : public sf::Sprite
{
public:
int posX, posY;
bool clickedOn = false, moving = false;
sf::Vector2i moveToPoint;
Ship(int x, int y, sf::Texture &texture) : posX(x), posY(y)
{
setPosition(x, y);
setTexture(texture);
setColor( sf::Color(0,255,0) );
}
void isClickedOn(sf::Window &window)
{
sf::FloatRect spriteBounds = getGlobalBounds();
if( sf::Mouse::isButtonPressed(sf::Mouse::Left) )
{
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
if( spriteBounds.contains(mousePos.x, mousePos.y) )
{
clickedOn = true;
}
}
}
void beginMoving(sf::Window &window, sf::Event &event)
{
//using sf::Event as a parameter to place in the event processing loop
//to check if button is pressed and/or released
sf::FloatRect spriteBounds = getGlobalBounds();
if( clickedOn )
{
if( (event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::M) )
{
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
if( !( spriteBounds.contains(mousePos.x,mousePos.y) ) )
{
clickedOn = false;
moving = true;
moveToPoint.x = mousePos.x;
moveToPoint.y = mousePos.y;
}
}
if( sf::Mouse::isButtonPressed(sf::Mouse::Left) )
{
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
if( !( spriteBounds.contains(mousePos.x,mousePos.y) ) )
clickedOn = false;
}
}
}
void moveTo(sf::Time delta, int timeToReach)
{
if(moving)
{
sf::Vector2f currentPos = getPosition();
float newX = (moveToPoint.x - posX) / timeToReach;
float newY = (moveToPoint.y - posY) / timeToReach;
newX *= delta.asSeconds();
newY *= delta.asSeconds();
move(newX,newY);
if( (currentPos.x >= moveToPoint.x) && (currentPos.y >= moveToPoint.y) )
{
setPosition(moveToPoint.x, moveToPoint.y);
moving = false;
posX = moveToPoint.x;
posY = moveToPoint.y;
//if newX < 0 && newY < 0, then teleports to point instantly
//if newX < 0 or newY < 0, then goes to point in correct time, but then keeps moving past
}
}
}
}