2016-07-06 9 views
2

В последнее время я работаю над простой игрой, используя последнюю версию C++ и SFML, но у меня возникла проблема, которая заключается в том, что обнаружение столкновений не так уж и хорошо, например, игрок умирает, даже если противник еще не коснулся его , но рядом с ним. Вот код класса плеера с функцией перемещения и кода обнаружения столкновений и ходов враждебного класса:Столкновение в SFML не так уж хорошо, как его улучшить?

класс `PlayerA: общественный CircleShape { общественности:

//Constructor: 
    PlayerA(float xposition, float yposition, float radius, float s) 
    { 
     setRadius(radius); 
     setFillColor(Color::Yellow); 
     setOutlineColor(Color(00,80,00)); 
     setOutlineThickness(-2); 
     setPointCount(3); 
     setSpeed(s); 
     setPosition(xposition,yposition); 
    } 

    //Movements of the player: 
    void up() 
    { 
     move(0,-10*speed); 
    } 
    void down() 
    { 
     move(0,10*speed); 
    } 
    void right() 
    { 
     move(10*speed,0); 
    } 
    void left() 
    { 
     move(-10*speed,0); 
    } 
    void checkA(ObsA *obs1=NULL,ObsA *obs2=NULL, ObsA *obs3=NULL, ObsA *obs4=NULL, ObsA *obs5=NULL) 
    { 
     if(obs2==NULL) 
     { 
      if(getGlobalBounds().intersects(obs1->getGlobalBounds())) 
      { 
       relevel(); 
      } 
     } 
    private: 
     float speed=0.00; 

    void obs() 
    { 
     if(speed > 0) 
     { 
       rotate(0.5*speed); 
     } 
     else 
     { 
       rotate(0.5*speed); 
     } 
    } 


private: 
    float speed = 0.00; 


    void obs() 
    { 
     if(speed > 0) 
     { 
       rotate(0.5*speed); 
     } 
     else 
     { 
       rotate(0.5*speed); 
     } 
    } 


private: 
    float speed = 0.00; 

Есть ли что-то неправильно с кодом, как исправить проблему, спасибо!

+3

Возможного дубликат [SFML ограничительного Box Collision Detection] (http://stackoverflow.com/questions/27280264/sfml-bounding-box-collision-detection) – Conduit

ответ

6

Функция intersects просто проверяет, пересекаются ли два прямоугольника. Если вам требуется идеальное обнаружение столкновений в SFML, вы должны написать это сами.

В принципе, начать с intersects, если оно истинно, то получим, пересекающую прямоугольник и проверить, если какие-либо из пикселей в них обоих исходных прямоугольников содержит перекрывающихся соответствующие пикселей.

+0

Спасибо! Это лучшее, что я думаю. – QApps

0

Вы используете круг? Если я правильно помню, у круга будет прямоугольник hitbox. Если это так, то вы можете столкнуться между углами невидимого прямоугольника.

Если вы используете круг, возможно, измените класс на квадратный прямоугольник и посмотрите, работает ли столкновение правильно. Или попробуйте проверить столкновение непосредственно на оси x или y с помощью ваших кругов; то есть перемещение их по прямой по отношению друг к другу, только изменение оси 1. (край круга будет таким же, как край прямоугольника слева, справа, сверху и снизу).

Если вам нужно лучшее столкновение для кругов, в SFML может быть уже построено. Но я не думаю, что было бы слишком сложно написать свою собственную логику, используя радиус ваших двух кругов, центр ваших двух объектов и угол между центрами.

+0

Да, ты прав, я попробую. Спасибо за вашу помощь! – QApps

+0

«Угол между центрами». Я рекомендую использовать длину гипотенузы правого треугольника, образованного центральными точками, и проверять это на радиус 1 + радиус2, вместо того, чтобы пытаться сделать проекцию на угол. Это было то, что вы намеревались? (извините, если я раздражающе педантичен) –

0

Вы можете использовать эту функцию для выполнения более коллизии detection.Its основных один, но работает хорошо

bool circleTest(const sf::Sprite &first, const sf::Sprite &second) 
{ 
    sf::Vector2f firstRect(first.getTextureRect().width, first.getTextureRect().height); 
    firstRect.x *= first.getScale().x; 
    firstRect.y *= first.getScale().y; 

    sf::Vector2f secondRect(second.getTextureRect().width, second.getTextureRect().height); 
    secondRect.x *= second.getScale().x; 
    secondRect.y *= second.getScale().y; 

    float r1 = (firstRect.x + firstRect.y)/4; 
    float r2 = (secondRect.x + secondRect.y)/4; 
    float xd = first.getPosition().x - second.getPosition().x; 
    float yd = first.getPosition().y - second.getPosition().y; 

    return std::sqrt(xd * xd + yd * yd) <= r1 + r2; 
} 
+0

Вместо того, чтобы уклоняться от квадрата с одной стороны, вы должны скрещивать другую сторону. Он работает намного быстрее и дает те же результаты. Я также не согласился бы, что это «лучше» - совсем другое. Он по-прежнему не идеален для пикселя (что может иметь значение или не имеет значения), и он намного медленнее, чем выравнивание по осевым границам. –