利用 C++ 的简单碰撞问题和 sfml

发布于 2024-11-28 17:29:27 字数 2628 浏览 1 评论 0原文

我编写了一个简单的程序,屏幕上有两个立方体,一个用户可以移动,另一个是静止的。我刚刚开始使用 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;
    }

我从我正在观看的一个 tut 中获得了 bool isCollision 函数,但是 tut 是在 allegro 中完成的,所以我从它那里得到了我能做的。 (我使用他的函数的逻辑是,我们的立方体大小完全相同,并且属性相同[一个移动一个静止]。我认为问题一定在于我如何调用该函数。任何和所有帮助都非常重要赞赏

I coded a simple program with two cubes on screen, one the user can move, the other is stationary. I just started using sfml and have never touched on collision, so this was completely new to me. In my code, I aim to have a warning window pop up when the user steers the cube into the stationary one. the problem, however, is that the warning window appears as soon as I start the program, even though It is in an if loop. Here is my code:

    #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;
    }

I got the bool isCollision function from a tut I was watching, but the tut was done in allegro, so I scraped from it what I could. (My logic in using his function was that our cubes are the exact same size, and identical in their properties [one moving one stationary]. The problem must lie, I assume, in how I call the function. Any and all help is greatly appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

吝吻 2024-12-05 17:29:27

在 C++ 中,由调用者来收集返回值。

isCollision(x, y, x2, y2);

现在对上述函数的调用没有任何用处。您需要收集返回值并将其用作 if 条件的标志。或者直接将函数调用放在 if 条件本身中。

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

   // Code here
}

In C++, it is up to the caller to collect the returned value.

isCollision(x, y, x2, y2);

Now the call to the above function, does nothing useful. You need to collect the returned value and serve it as a flag for an if condition. Or directly place the function call in the if condition itself.

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

   // Code here
}
愛放△進行李 2024-12-05 17:29:27

我认为你的函数没有正确返回,你应该这样尝试。 (仅供参考 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

i think your function isnt returning properly, you should try it like this. (FYI 2 returns is real bad practice)

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;
}

Hope this helps :D

痴骨ら 2024-12-05 17:29:27

在您的代码示例中:

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) {
//....
}

另外,if语句之后的brace}看起来也不匹配......

而且在函数isCollision的实现中,什么是 abs(x2 - x)

我感觉 abs() 可能是一个宏,所以检查宏是否定义正确?
if() 语句中的两个宏调用确实会把事情搞砸。

in your code sample:

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);

            }

Why are you calling the function isCollision twice?

You can just do like this:

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

Also the brace } after if statement look like not matched ....

moreover in the implementation of function isCollision, what is abs(x2 - x)

I feel like abs() is probably a macro, so check if the macro is defined properly or not?
Two macro calls in the if() statement can really mess things up.

美人骨 2024-12-05 17:29:27

我怀疑 RenderWindow 构造函数创建并显示了窗口。
在发生碰撞之前,您不应该创建它(或者至少延迟显示它)。
我将把它作为练习,让您弄清楚如何实现这一目标。

I suspect that the RenderWindow constructor creates and shows the window.
You shouldn't create it (or at least delay displaying it) until there has been a collision.
I will leave it as an exercise for you to figure out how to accomplish that.

唐婉 2024-12-05 17:29:27

尝试用更简单的方法来找出错误到底出在哪里。 molbdnilo 可能是对的,因此您可以做一些肯定有效的事情,而不是使用新窗口来检查碰撞代码是否正确。我通常只是用 cout 输出消息:

#include <iostream>

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

        }

只需确保您可以看到控制台(有时您需要使用调试模式)

而且没有 if 循环;)

Try to use a more simple way to figure out where exactly the mistake lies. molbdnilo might be right, so instead of using the new window to check whether your collision code is correct you could do something that will definately work. I usually just output messages with cout:

#include <iostream>

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

        }

Just make sure you can see the console (sometimes you need to use debug mode for that)

Also there are no if loops ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文