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开发者_如何学Python);
}
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
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
}
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
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.
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.
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 ;)
精彩评论