Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Simple collision detection problems... Using sf::FloatRect for hitboxes  (Read 6429 times)

0 Members and 1 Guest are viewing this topic.

Mal1

  • Newbie
  • *
  • Posts: 18
    • View Profile
Hello, first time posting here...
I'm a newbie in programming, haven't really completed any projects, besides really simple ones, I just did some testing and move on.
Anyway, I have this problem, I'm really annoyed by it and need help  :-\
I really can't figure it out myself, anyway, about the problem, first code, then the explanation.
bool collisionCheck( sf::FloatRect object1, sf::FloatRect object2 )
{

    float left1, left2;
    float right1, right2;
    float top1, top2;
    float bottom1, bottom2;

    left1 = object1.left;
    left2 = object2.left;
    right1 = object1.left + object1.width;
    right2 = object2.left + object2.width;
    top1 = object1.top;
    top2 = object2.top;
    bottom1 = object1.top + object1.height;
    bottom2 = object2.top + object2.height;

    // Trivial rejections:
    if (bottom1 < top2)
        return true;

    if (top1 > bottom2)
        return true;

    if (right1 < left2)
        return true;

    if (left1 > right2)
        return true;

    return false;

}

bool checkMovement()
{
    if( Character.hasHitbox == false )
        return false;

    sf::FloatRect newPosRequest = Character.Hitbox;

    if( EventAction == Right_Arrow || Left_Arrow || Up_Arrow || Down_Arrow )
    {
        switch( EventAction )
        {
        case Right_Arrow:
            newPosRequest.left = newPosRequest.left + 5.0;
            break;
        case Left_Arrow:
            newPosRequest.left = newPosRequest.left - 5.0;
            break;
        case Down_Arrow:
            newPosRequest.top = newPosRequest.top + 5.0;
            break;
        case Up_Arrow:
            newPosRequest.top = newPosRequest.top - 5.0;
            break;
        }
    }

    sf::FloatRect Temp;
    bool blocked = false;
    bool end = false;

    int i = 0;
    int i2 = Active_Map.SizeOf_Obstacles();

    do
    {
        std::cout << "Checking collision for i = " << i << std::endl;
        Temp = Active_Map.GetObstacleData( i );
        blocked = collisionCheck( newPosRequest, Temp );
        std::cout << "Blocked = " << blocked << std::endl;

        if( blocked == true )
        {
            collisionDetected = true;
            return true;
        }
        else
            collisionDetected = false;

        i++;
        if( i = i2 )
            end = true;

    } while( end != true );

    return false;
}

void movement()
{
    bool blocked = checkMovement();

    if( blocked == false )
    {
        sf::Vector2f newPosition = Character.Sprite.getPosition();

        switch( EventAction )
        {
        case Right_Arrow:
            newPosition.x = newPosition.x + 5.0;
            break;
        case Left_Arrow:
            newPosition.x = newPosition.x - 5.0;
            break;
        case Down_Arrow:
            newPosition.y = newPosition.y + 5.0;
            break;
        case Up_Arrow:
            newPosition.y = newPosition.y - 5.0;
            break;
        }

        Character.Sprite.setPosition( newPosition );
        Character.updateHitbox();
    }
}

So, in here, Character is an object of my class for characters (duh), it's basicly a little class to put few sfml classes together to make it easier for me (Sprite, Texture, FloatRect, and a bool for hasHitbox - if hitbox exists (set in constructor))
In loop for this part of game called is movement(), I use mostly global variables (Bad, I know, don't hurt me),
And it should work like

  • movement() starts
  • bool blocked checks by calling checkMovement()
  • rejection if there's no hitbox to check for, then continue (hitbox is off unless creating with texture)
  • EventAction is an enum that holds the event in a more friendly for me way (Again, global variable)
  • Get Hitbox from the character and apply the offset for it like movement would happen
  • Active_Map is active map, it's a texture + vector for sf::FloatRect for holding obstacles - Active_Map.Sizeof obstacles returns size of the said vector
  • then it enters collisionCheck in a loop (temp values, checking for every obstacle in a loop and seeing if there has been a true value for any
  • collisionDetected is another global (only for me, program doesn't really use it and it'll be deleted later on)

Point is, when I start it up, with

Data used - Object 1 Hitbox:
  • top - 100.0
  • left - 100.0
  • width - 50.0
  • height - 50.0

Data used - Object 2 Obstacle:
  • top - 600.0
  • left - 1200.0
  • width - 100.0
  • height - 100.0
It always give out a true, even though they do not collide  :(
Help? Anyone?
._.

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Simple collision detection problems... Using sf::FloatRect for hitboxes
« Reply #1 on: August 31, 2012, 09:29:52 am »
Object 1 bottom=150
Object 2 top=600
if (bottom1 < top2)
        return true;
Use rect's intersect method.
Back to C++ gamedev with SFML in May 2023

Mal1

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Simple collision detection problems... Using sf::FloatRect for hitboxes
« Reply #2 on: August 31, 2012, 09:45:47 am »
Could I please get an example/link for any ref for it?
I can't find it...

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Back to C++ gamedev with SFML in May 2023

Mal1

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Simple collision detection problems... Using sf::FloatRect for hitboxes
« Reply #4 on: August 31, 2012, 09:53:30 am »
I was looking for it there but somehow missed it >_<
Thanks for help, FRex
/edit:
Kay, figured it out with the example in the doc.
Sorry for bothering
« Last Edit: August 31, 2012, 10:07:05 am by Mal1 »

 

anything