Простая проблема столкновения с использованием C ++ и sfml - PullRequest
1 голос
/ 09 августа 2011

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

    #include <SFML/Graphics.hpp>
    #include <SFML/Window.hpp>
    #include <iostream>

    using namespace std;

    bool isCollision(int x, int y, int x2, int y2){ // borrowed function, all credits go to whom ever made it
        if (abs(x2 - x) > 20 || abs(y2 - y) > 20)
            return false;
        else
            return true;
    }

    int main()
    {
        sf::RenderWindow App(sf::VideoMode(800, 600, 32), "My SFML Window");
        sf::RenderWindow Warning(sf::VideoMode(400, 225, 32), "WARNING!");
        sf::Shape Rect = sf::Shape::Rectangle(0, 0, 20, 20, sf::Color::Red);
        sf::Shape Rect2 = sf::Shape::Rectangle(50, 0, 70, 20, sf::Color::Blue);


        while (App.IsOpened())
        {
            sf::Event event;
            while (App.GetEvent(event)) // I now know the shorter way to handle events, just haven't edited it yet. No functional difference
            {
                if (event.Type == sf::Event::Closed)
                    App.Close();
                if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Escape))
                    App.Close();
                if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Right))
                    Rect.Move(5.0, 0);
                if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Left))
                    Rect.Move(-5.0, 0);
                if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Down))
                    Rect.Move(0, 5.0);
                if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Up))
                    Rect.Move(0, -5.0);

            }

            int x = Rect.GetPosition().x;
            int y = Rect.GetPosition().y;

            int x2 = Rect2.GetPosition().x;
            int y2 = Rect2.GetPosition().y;

            isCollision(x, y, x2, y2);

            if (isCollision(x, y, x2, y2) == true) // if loop that I am messing up somehow
            }
                Warning.Clear(sf::Color::White);

            }

            App.Clear();
            App.Draw(Rect);
            App.Draw(Rect2);
            App.Display();
        }

        return EXIT_SUCCESS;
    }

Я получил функцию bool isCollision из пачки, которую смотрел, но она была сделана в allegro, поэтому я вычеркнул из нее все, что мог. (Моя логика в использовании его функции заключалась в том, что наши кубы имеют одинаковый размер и идентичны по своим свойствам [один движется один неподвижно]. Я полагаю, что проблема заключается в том, как я вызываю функцию. Любая и вся помощь очень цениться

Ответы [ 5 ]

1 голос
/ 03 мая 2014

Попробуйте использовать более простой способ выяснить, в чем именно заключается ошибка. molbdnilo может быть прав, поэтому вместо использования нового окна для проверки правильности кода столкновения вы можете сделать что-то, что определенно будет работать. Я обычно просто выводить сообщения с cout:

#include <iostream>

            if (isCollision(x, y, x2, y2) == true)
        {
            cout << "squares r colliding!!!";
            Warning.Clear(sf::Color::White);

        }

Просто убедитесь, что вы видите консоль (иногда для этого нужно использовать режим отладки)

Также нет циклов if;)

1 голос
/ 09 августа 2011

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

1 голос
/ 09 августа 2011

Я думаю, что ваша функция не возвращается должным образом, вы должны попробовать это следующим образом. (К вашему сведению, возвращение 2 - очень плохая практика)

bool isCollision(int x, int y, int x2, int y2){
     bool exitVal;   // maybe make it static if this is being called over and over
     if (abs(x2 - x) > 20 || abs(y2 - y) > 20)
         exitVal = false;
     else
         exitVal = true;

     return exitVal;
}

Надеюсь, это поможет: D

1 голос
/ 09 августа 2011

в вашем примере кода:

isCollision(x, y, x2, y2);

            if (isCollision(x, y, x2, y2) == true) // if loop that I am messing up somehow
            }
                Warning.Clear(sf::Color::White);

            }

Почему вы вызываете функцию isCollision дважды?

Вы можете просто сделать так:

bool is_coll = isCollision(x, y, x2, y2);
if(is_coll) {
//....
}

Кроме того, оператор brace } после if выглядит как несоответствующий ....

Более того, при реализации функции isCollision, что такое abs(x2 - x)

Я чувствую, что abs() возможно макрос, поэтому проверьте, правильно ли определен макрос или нет?Два макро вызова в операторе if() могут действительно испортить ситуацию.

1 голос
/ 09 августа 2011

В C ++ вызывающий объект должен собирать возвращаемое значение.

isCollision(x, y, x2, y2);

Теперь вызов вышеуказанной функции ничего полезного не делает.Вам нужно собрать возвращаемое значение и использовать его как флаг для условия if.Или непосредственно поместите вызов функции в само условие if.

if ( isCollision(x, y, x2, y2) ){

   // Code here
}
...