Question

I have some sprites (2d-boxes) of the same type stored in a formation vector. Now i want to move them around with the mouse, that works well. But the code should prevent the player to move one sprite onto another already existing sprite of the vector.

My solution is quite ugly and does not work. Whenever a sprite is moved around, i test with the spriteoverlap function if the sprite is moved onto another. The Problem:

Whenever the sprite is directly close to the it stops moving, which is what wanted. But i can't move it anymore afterwards because the overlapfunction sets the bool always to false.

while (App.pollEvent(Event))
{


    //Moving the playerbuttons on the formation screen
    for (size_t k = 0; k < formation.size(); k++)
    {
        bool drag_onto_otherplayer = false;
        if (isMouseOver(formation[k], App) == true)
        {
        //The next loop tests if the sprite being moved with the mouse overlaps with another sprite from the formation vector       
        for (size_t j = 0; j < formation.size(); j++)
        {
            if (spriteOverlap(formation[j], formation[k], App) == true && k!=j)
            {
                std::cout << drag_onto_otherplayer << std::endl;
                drag_onto_otherplayer = true;
                std::cout << drag_onto_otherplayer <<std::endl;                                                 
            }

            if (drag_onto_otherplayer == false)
            //(If the sprite  does not overlap getting the new sprite position from the mouseposition) 

            {
                Mouseposition =sf::Vector2f(sf::Mouse::getPosition(App));
                Mouseposition.x = Mouseposition.x - formation[k].getLocalBounds().width / 2;
                Mouseposition.y = Mouseposition.y - formation[k].getLocalBounds().height / 2;
                formation[k].setPosition(sf::Vector2f(Mouseposition));
                Formation_playernames.clear();
                Formation_playerinformation.clear();
                Formation_Playernames(Font, Formation_playernames, formation, playerlist);
                Formation_Playerinformation(Font, Formation_playerinformation, formation, playerlist);
                    }

So the problem are my loops and the bool test i guess, but i don't know how to solve it. Any ideas ?

Here is my spriteoverlap function:

bool spriteOverlap(sf::Sprite &sprite1, sf::Sprite &sprite2, sf::RenderWindow &App)
{

    float x_min1 = sprite1.getPosition().x;
    float x_max1 = sprite1.getPosition().x + sprite1.getLocalBounds().width;
    float y_min1 = sprite1.getPosition().y;
    float y_max1 = sprite1.getPosition().y + sprite1.getLocalBounds().height;
    float x_min2 = sprite2.getPosition().x;
    float x_max2 = sprite2.getPosition().x + sprite2.getLocalBounds().width;
    float y_min2 = sprite2.getPosition().y;
    float y_max2 = sprite2.getPosition().y + sprite2.getLocalBounds().height;

    if (x_min1 > x_max2 | x_max1 < x_min2 | y_min1 > y_max2 | y_max1 < y_max2)
        return false;
    else
        return true;
};

And my isMouseover function:

bool isMouseOver(sf::Sprite &sprite, sf::RenderWindow &App)
{
    float pos_x = sprite.getPosition().x;
    float pos_y = sprite.getPosition().y;
    if (sf::Mouse::getPosition(App).x > pos_x && sf::Mouse::getPosition(App).x < pos_x+sprite.getLocalBounds().width &&
        sf::Mouse::getPosition(App).y  >pos_y && sf::Mouse::getPosition(App).y < pos_y + sprite.getLocalBounds().height)
    {
        return true;
    }
    else
        return false;

};
Was it helpful?

Solution

Check for collision is already included somewhat in sfml:

bool spriteOverlap(sf::Sprite& sprite1, sf::Sprite& sprite2) // possibly const, dunno
{
    return sprite1.getGlobalBounds().intersects(sprite2.getGlobalBounds());
}

Generally try this: Only move, if the position of the next frame is valid. This prevents objects being stuck, because you already moved them into an invalid position, thus preventing any further movement

edit:

//untested
bool spritesWillOverlap(sf::Sprite& sprite1, sf::Sprite& sprite2, sf::Vector2f vel)
{
   top1 = sprite1.getGobalBounds().top + vel.y;
   left1 = sprite1.getGlobalBounds().left + vel.x;
   right1 = left1 + sprite1.getGlobalBounds().width;
   bottom1 = top1 + sprite1.getGlobalBounds().height;

   top2 = sprite2.getGobalBounds().top + vel.y;
   left2 = sprite2.getGlobalBounds().left + vel.x;
   right2 = left2 + sprite1.getGlobalBounds().width;
   bottom2 = top2 + sprite1.getGlobalBounds().height;

   sf::FloatRect rect1(top1, left1, right1 - left1, bottom1 - top1);
   sf::FloatRect rect2(top2, left2, right2 - left2, bottom2 - top2);

   return rect1.intersects(rect2);
}

vel: velocity -> an object is moved by this 2D vector every frame

If the concept of "frames" is unfamiliar, read up on framerates/fixed framerate and/or timestep. here's an example article to get started: Fix Your Timestep!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top