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

Author Topic: Collision help  (Read 1808 times)

0 Members and 1 Guest are viewing this topic.

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Collision help
« on: August 16, 2014, 06:59:23 am »
I am making some collision and it sort of works but it's not working as good as it should, its hard to explain but if you run the code you'll see what i mean.

Collision

//Get collision.
        if(rectToMove.intersects(redBlockSprite.getGlobalBounds()))
        {
            if(velocity.x < 0 && position.x < redBlockSprite.getPosition().x + redBlockSprite.getGlobalBounds().width)
            {
                cout << "Touched Right side" << endl;
                position.x = redBlockSprite.getPosition().x + characterSprite.getGlobalBounds().width;
            }
            if(velocity.y > 0 && position.y > redBlockSprite.getPosition().y - redBlockSprite.getGlobalBounds().height)
            {
                cout << "Touched Top" << endl;
                position.y = redBlockSprite.getPosition().y - characterSprite.getGlobalBounds().height;
            }

            if(velocity.x > 0 && position.x > redBlockSprite.getPosition().x - redBlockSprite.getGlobalBounds().width)
            {
                cout << "Touched Left Side" << endl;
                position.x = redBlockSprite.getPosition().x - characterSprite.getGlobalBounds().width;
            }
            if(velocity.y < 0 && position.y < redBlockSprite.getPosition().y + redBlockSprite.getGlobalBounds().height)
            {
                cout << "Touched Bottom" << endl;
                position.y = redBlockSprite.getPosition().y + characterSprite.getGlobalBounds().height;
            }
        }
 


Complete Code

#include <iostream>
#include <math.h>
#include <SFML/Graphics.hpp>

using namespace std;

int main()
{
    sf::Vector2f position;
    sf::Vector2f velocity;
    float maxspeed = 4.0f;
    float accel = 4.5f;
    float decel = 0.01f;
    bool vSyncEnabled = true;

    //Setup Window and Framerate
    sf::RenderWindow window(sf::VideoMode(800, 600), "Bounding Box (Collision)");
    window.setFramerateLimit(60);
    window.setVerticalSyncEnabled(vSyncEnabled);

    //Load Texture
    sf::Texture character;
    if(!character.loadFromFile("Resources/Textures/triangle.png"))
    {
        cout << "Error loading resource 'triangle.png'" << endl;
    }
    else
    {
        cout << "triangle.png texture loaded" << endl;
    }

    //Set Sprite for Character Object
    sf::Sprite characterSprite;
    characterSprite.setTexture(character);
    characterSprite.setOrigin(sf::Vector2f(0, 0));
    characterSprite.setPosition(400, 300);

    //Load Red Block Texture
    sf::Texture redBlock;
    if(!redBlock.loadFromFile("Resources/Textures/RedBlock.png"))
    {
        cout << "Error loading 'RedBlock.png" << endl;
    }
    else
    {
        cout << "RedBlock.png texture loaded" << endl;
    }

    //Set Sprite for Red Block Object
    sf::Sprite redBlockSprite;
    redBlockSprite.setTexture(redBlock);
    redBlockSprite.setOrigin(sf::Vector2f(0, 0));
    redBlockSprite.setPosition(200, 200);

    while(window.isOpen())
    {
        window.clear(sf::Color::White);

        window.draw(characterSprite);
        window.draw(redBlockSprite);

        sf::Event event;

        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                {
                    window.close();
                }
                break;
                //Dont stretch the window contents when its resized
                case sf::Event::Resized:
                {
                    sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
                    window.setView(sf::View(visibleArea));
                }
                break;
            }
        }

        //WASD Movement
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
        {
            velocity.x -= accel;
        }
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
        {
            velocity.x += accel;
        }
        else
        {
            velocity.x *= decel;
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
        {
            velocity.y -= accel;
        }
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
        {
            velocity.y += accel;
        }
        else
        {
            velocity.y *= decel;
        }

        //Make sure the sprite isn't going too fast
        if(velocity.x < -maxspeed) velocity.x = -maxspeed;
        if(velocity.x >  maxspeed) velocity.x =  maxspeed;
        if(velocity.y < -maxspeed) velocity.y = -maxspeed;
        if(velocity.y >  maxspeed) velocity.y =  maxspeed;

        //Update sprite position and move sprite
        position += velocity;

        //Get the window's size
        sf::Vector2u currWSize = window.getSize();

        if(position.x <= 0)
        {
            position.x = 0;
        }
        if(position.y <= 0)
        {
            position.y = 0;
        }
        if(position.x >= currWSize.x - characterSprite.getGlobalBounds().width)
        {
            position.x = currWSize.x - characterSprite.getGlobalBounds().width;
        }
        if(position.y >= currWSize.y - characterSprite.getGlobalBounds().height)
        {
            position.y = currWSize.y - characterSprite.getGlobalBounds().height;
        }

        sf::FloatRect rectToMove(position, {characterSprite.getGlobalBounds().width, characterSprite.getGlobalBounds().width});

        //Get collision.
        if(rectToMove.intersects(redBlockSprite.getGlobalBounds()))
        {
            if(velocity.x < 0 && position.x < redBlockSprite.getPosition().x + redBlockSprite.getGlobalBounds().width)
            {
                cout << "Touched Right side" << endl;
                position.x = redBlockSprite.getPosition().x + characterSprite.getGlobalBounds().width;
            }
            if(velocity.y > 0 && position.y > redBlockSprite.getPosition().y - redBlockSprite.getGlobalBounds().height)
            {
                cout << "Touched Top" << endl;
                position.y = redBlockSprite.getPosition().y - characterSprite.getGlobalBounds().height;
            }

            if(velocity.x > 0 && position.x > redBlockSprite.getPosition().x - redBlockSprite.getGlobalBounds().width)
            {
                cout << "Touched Left Side" << endl;
                position.x = redBlockSprite.getPosition().x - characterSprite.getGlobalBounds().width;
            }
            if(velocity.y < 0 && position.y < redBlockSprite.getPosition().y + redBlockSprite.getGlobalBounds().height)
            {
                cout << "Touched Bottom" << endl;
                position.y = redBlockSprite.getPosition().y + characterSprite.getGlobalBounds().height;
            }
        }

        characterSprite.setPosition(position);
        velocity *= decel;

        window.display();
    }

    return 0;
}
 

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: Collision help
« Reply #1 on: August 16, 2014, 07:31:18 am »
You don't even say what your problem is, good luck.

kimci86

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Re: Collision help
« Reply #2 on: August 16, 2014, 11:24:53 am »
Hi,
You are not computing redBlockSprite sides coordinates properly.
For example, if you want to know the left side x coordinate, it is redBlockSprite.getPosition().x (assuming its origin is (0,0)).

Then, when setting position, there are still issues with sides coordinates for the bottom and right cases.
For example, if you want the left side of the characterSprite to be on the right side of the redBlockSprite, you want that :
position.x // character left side
= redBlockSprite.getPosition().x + redBlockSprite.getGlobalBounds().width; // redBlock right side

This kind of formulas are easy to find with a diagram, so take a paper an a pencil, it will be obvious.

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Collision help
« Reply #3 on: August 16, 2014, 01:26:31 pm »
Well i've been doing that, i try to get the left and right sides and top and bottom and I do get those things so that's not a problem but when i touch the square it sometimes acts like its slippery and goes around it, also if Im pressing a key and then press another direction key it will go to one of the corners of the square. other than that it does collide, so what could be going wrong and how can I fix it?

 

anything