Ajuda com SFML em C++

Tenho um codigo que faz a colisão entre 2 circulos, após a colisão eles retornam para lado oposto com o mesmo angulo e a mesma velocidade, mas tem um problema, os circulos sempre colidem no mesmo ponto, gostaria de saber se tem alguma forma deles colidirem em pontos aleatorios da tela?
O codigo é o seguinte:

[code]#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include
#include

bool collision(sf::RenderWindow &Window, sf::Shape Circle1, sf::Shape &Circle2){//função de colisão entre os circulos
if((abs(Circle1.GetPosition().x - Circle2.GetPosition().x)) +
abs((Circle1.GetPosition().y - Circle2.GetPosition().y)) <= 100){
return true;
}else{
return false;
}
}

int main()
{
int x = 350;
int y = 100;
int xVetor = 3;
int yVetor = 3;
int x2 = 300;
int y2 = 300;
int x2Vetor = -3;
int y2Vetor = -3;
bool collided = false;

sf::Shape Circle1 = sf::Shape::Circle(0, 0, 50, sf::Color(0, 0, 0), 1, sf::Color(0, 0, 0));
sf::Shape Circle2 = sf::Shape::Circle(0, 0, 50, sf::Color(0, 0, 0), 1, sf::Color(0, 0, 0));

sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Colisão entre Circulos");

//GAME LOOP
while(Window.IsOpened()){
    sf::Event Event;
    while(Window.GetEvent(Event)){
        if(Event.Type == sf::Event::Closed || Event.Key.Code == sf::Key::Escape)
        Window.Close();
    }

    Circle1.SetPosition(x, y);
    Circle2.SetPosition(x2, y2);

    x += xVetor;
    if((x < 50) || (x > 750)){
        xVetor *= (-1);
    }

    y += yVetor;
    if ((y < 50) || (y > 550)){
        yVetor *= (-1);
    }

    x2 += x2Vetor;
    if((x2 < 50) || (x2 > 750)){
        x2Vetor *= (-1);
    }

    y2 += y2Vetor;
    if ((y2 < 50) || (y2 > 550)){
        y2Vetor *= (-1);
    }

    //CHAMADA DE FUNÇÔES
    if (collision(Window, Circle1, Circle2) && !collided){
        yVetor *= (-1);
        xVetor *= (-1);
        y2Vetor *= (-1);
        x2Vetor *= (-1);

        collided = true;
    }

    if (!collision(Window, Circle1, Circle2) && collided){
        //x2Vetor *= (-1);
        collided = false;
    }

    Window.Clear(sf::Color(255, 255, 255));
    Window.Draw(Circle1);
    Window.Draw(Circle2);
    Window.Display();
    sf::Sleep(0.01f);
}
return EXIT_SUCCESS;

}
[/code]

Sua fórmula de colisão de círculos está incorreta.
Dois círculos colidem quando a distância entre seus dois centros for menor do que a distância entre os raios.

De qualquer forma, se você quer uma física mais realista no seu game, recomendo que use uma engine, como a Box2D:
http://box2d.org/

A colisao aqui deu certo, eles colidem e voltam, mas sempre colidem no mesmo ponto
:frowning:
Ja to usando a SFML, acho que usar a box2D ficaria meo ruim

Por que? A SFML é uma biblioteca gráfica, a Box2D é uma biblioteca de física. Elas se complementam. Além disso, a Box2D é uma lib estática, não depende de nenhuma dll.

Por que é um exercicio da faculdade e nao sei se o professor aceitaria usar box2D, o trabalho ja ta feito, a questao de colidirem em lugares diferentes é parte minha, uma questao de aprender alem do que o professor pede e dar uma enfeitada tambem.

O que você quer dizer com “colidem no mesmo lugar”? E “colidirem em lugares diferentes”?

Isso no mesmo lugar eu digo em ralação ao eixo x e o eixo y, sempre colidem no mesmo ponto x,y na tela

Não seria só usar random nos vetores iniciais?

sim, eu tava tentando fazer isso, com a função rand e srand, mas nao consegui
:frowning:

Inclua:

Em seguida, no início do main, faça:

Depois, para sortear, faça algo como:

Só um comentário, no C++11, já seria possível usar as classes de números aleatórios:

Vamos supor que você quisesse gerar números de 0 até 350, você poderia fazer:

std::uniform_int_distribution&lt;int&gt; distribution(0, 350); std::mt19937 engine; // Mersenne twister MT19937 auto gerador = std::bind(distribution, engine); int x = gerador(); int y = gerador();

Mas ali no int x, eu faço com o y tbm né?

Sim, é só um exemplo. Um comando como:

Vai gerar um número entre 0 até 349. Se você quiser especificar um intervalo, use o método:

int random(int min, int max) { return min + (rand % (max+1 - min)); }

Essa função inclui ambos os números na possibilidade de geração. Ou seja:
random(10,50) vai gerar um número entre 10 e 50.

Outra coisa. Corrija sua função de colisão.
Ela está errada. Como falei, a colisão entre círculo ocorre só se a distância entre os centros for menor do que a soma dos raios.

O calculo correto seria:

bool collision(const sf::Shape& Circle1, const sf::Shape& Circle2) { Vector2f diff = Circle1.GetPosition() - Circle2.GetPosition(); float dist = sqrt(diff.GetPosition().x * diff.GetPosition().x + diff.GetPosition().y * diff.GetPosition().y); return dist &lt;= 100; }

Não achei na documentação formas de calcular diretamente o tamanho do vetor, ou mesmo o produto escalar.
Simplificaria um bocado os cálculos.

Eu fiz isso que você falou, mas o circulo não vai pra uma aprte aleatoria da tela na hora da colisão, ele vai no inicio da tela, se ficar iniciando e fechando a tela, os dois circulos iniciais começam em posições diferentes e direções diferentes, queria saber se tem como eles irem pra uma posição aleatória da tela na hora da colisão, por via das duvidas o codigo atual esta assim:

[code]#include <SFML/Graphics.hpp>

const int CIRCLE1WIDTH = 10;
const int CIRCLE1HEIGHT = 10;
const int CIRCLE2WIDTH = 10;
const int CIRCLE2HEIGHT = 10;

bool collision(sf::RenderWindow &Window, sf::Shape Circle1, sf::Shape &Circle2){//função de colisão entre os circulos
if((abs(Circle1.GetPosition().x - Circle2.GetPosition().x)) +
abs((Circle1.GetPosition().y - Circle2.GetPosition().y)) <= 100){

    return true;
}else{
    return false;
}

}

int main()
{
srand(time(0));
int x = rand() % 800;
int y = rand() % 600;
int xVetor = 3;
int yVetor = 3;
int x2 = 300;
int y2 = 300;
int x2Vetor = -3;
int y2Vetor = -3;
bool collided = false;

sf::Shape Circle1 = sf::Shape::Circle(0, 0, 50, sf::Color(0, 0, 0), 1, sf::Color(0, 0, 0));
sf::Shape Circle2 = sf::Shape::Circle(0, 0, 50, sf::Color(0, 0, 0), 1, sf::Color(0, 0, 0));

sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Colisão entre Circulos");

//GAME LOOP
while(Window.IsOpened()){
    sf::Event Event;
    while(Window.GetEvent(Event)){
        if(Event.Type == sf::Event::Closed || Event.Key.Code == sf::Key::Escape)
        Window.Close();
    }

    Circle1.SetPosition(x, y);
    Circle2.SetPosition(x2, y2);

    x += xVetor;
    if((x < 50) || (x > 750)){
        xVetor *= (-1);
    }

    y += yVetor;
    if ((y < 50) || (y > 550)){
        yVetor *= (-1);
    }

    x2 += x2Vetor;
    if((x2 < 50) || (x2 > 750)){
        x2Vetor *= (-1);
    }

    y2 += y2Vetor;
    if ((y2 < 50) || (y2 > 550)){
        y2Vetor *= (-1);
    }

    //CHAMADA DE FUNÇÔES
    if (collision(Window, Circle1, Circle2) && !collided){
        yVetor *= (-1);
        xVetor *= (-1);
        y2Vetor *= (-1);
        x2Vetor *= (-1);

        collided = true;
    }

    if (!collision(Window, Circle1, Circle2) && collided){
        //x2Vetor *= (-1);
        collided = false;
    }

    Window.Clear(sf::Color(255, 255, 255));
    Window.Draw(Circle1);
    Window.Draw(Circle2);
    Window.Display();
    sf::Sleep(0.01f);
}
return EXIT_SUCCESS;

}
[/code]