利用 C++ 的简单碰撞问题和 sfml
我编写了一个简单的程序,屏幕上有两个立方体,一个用户可以移动,另一个是静止的。我刚刚开始使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 C++ 中,由调用者来收集返回值。
现在对上述函数的调用没有任何用处。您需要收集返回值并将其用作 if 条件的标志。或者直接将函数调用放在 if 条件本身中。
In C++, it is up to the caller to collect the returned value.
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.
我认为你的函数没有正确返回,你应该这样尝试。 (仅供参考 2 退货确实是不好的做法)
希望这会有所帮助:D
i think your function isnt returning properly, you should try it like this. (FYI 2 returns is real bad practice)
Hope this helps :D
在您的代码示例中:
为什么要调用函数
isCollision
两次?你可以这样做:
另外,
if
语句之后的brace}
看起来也不匹配......而且在函数
isCollision
的实现中,什么是abs(x2 - x)
我感觉
abs()
可能是一个宏,所以检查宏是否定义正确?if()
语句中的两个宏调用确实会把事情搞砸。in your code sample:
Why are you calling the function
isCollision
twice?You can just do like this:
Also the
brace }
afterif
statement look like not matched ....moreover in the implementation of function
isCollision
, what isabs(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.我怀疑
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.
尝试用更简单的方法来找出错误到底出在哪里。 molbdnilo 可能是对的,因此您可以做一些肯定有效的事情,而不是使用新窗口来检查碰撞代码是否正确。我通常只是用 cout 输出消息:
只需确保您可以看到控制台(有时您需要使用调试模式)
而且没有 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:
Just make sure you can see the console (sometimes you need to use debug mode for that)
Also there are no if loops ;)