Hey everyone! Excited to spend some time around here.
I've been working my way through the SFML book and ran into a puzzling issue. Firstly, congrats to everyone involved, the book is really great, I couldn't put it down and have been working through it wherever there is a flat surface for my laptop to rest on
.
EDIT: Just noted that the issue is that the SceneNode are never compared against one another not with the shape.
While trying to implement collision detection using the sf::FloatRect::Intersects as per suggested by the book I ran into an interesting issue. I've built a ShapeNode which inherents from SceneNode and does what SpriteNode does for sf::Sprite to an sf::RectangleShape. I am using this simple shape as a temporary platform to test the collision detection. When I get the bounding rectangle of the ShapeNode (from the RectangleShape) it has a valid top and left value but the height and width are zero.
The implementation of ShapeNode is fairly simple:
ShapeNode::ShapeNode(const sf::Vector2f& size, const sf::Color& color, Category::Type type)
: mRectangleShape(size)
, mCategory(type)
{
mRectangleShape.setFillColor(color);
}
void ShapeNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
{
target.draw(mRectangleShape, states);
}
sf::FloatRect ShapeNode::getBoundingRect() const
{
return getWorldTransform().transformRect(mRectangleShape.getGlobalBounds());
}
unsigned int ShapeNode::getCategory() const
{
return mCategory;
}
I then add the player sprite and ShapeNode to the SceneGraph in World.cpp:
std::unique_ptr<Mob> player(new Mob(Mob::Type::Player, mTextures));
mPlayer = player.get();
mPlayer->setPosition(mSpawnPosition);
mPlayer->setVelocity(0.0f, 0.0f);
mSceneLayers[Front]->attachChild(std::move(player));
std::unique_ptr<ShapeNode> platform(new ShapeNode(sf::Vector2f(100, 100), sf::Color::Red, Category::Terrain));
platform->setPosition(mSpawnPosition);
sf::FloatRect testRect = platform->getBoundingRect();
mSceneLayers[Front]->attachChild(std::move(platform));
While debugging I tried to manually test for collisions and that's how I figured that height and width are zero:
bool collision(const SceneNode& lhs, const SceneNode& rhs)
{
std::cout << "Checking intersection" << std::endl;
sf::FloatRect lhsBox = lhs.getBoundingRect();
sf::FloatRect rhsBox = rhs.getBoundingRect();
double rhsBoxRight = rhsBox.left + rhsBox.width;
double lhsBoxRight = lhsBox.left + lhsBox.width;
double rhsBoxBottom = rhsBox.top + rhsBox.height;
double lhsBoxBottom = lhsBox.top + lhsBox.height;
std::cout << "RHS Box (Top, Left): "
<< rhsBox.left << ", " << lhsBox.top
<< "(Width, Height): "
<< rhsBox.width << ", " << rhsBox.height
<< std::endl;
std::cout << "LHS Box (X1,Y1): "
<< lhsBox.left << ", " << lhsBox.top
<< "(Width, Height): "
<< lhsBox.width << ", " << lhsBox.height
<< std::endl;
if(lhsBox.left < rhsBoxRight &&
rhsBox.left < lhsBoxRight &&
lhsBox.top < rhsBoxBottom &&
rhsBox.top < lhsBoxBottom )
{
std::cout << "Intersection detected" << std::endl;
return (true);
}
return (false);
}
The interesting thing is that at the point before adding the platform to the SceneGraph, the height and width of the platform are valid. But when doing the collision detection in the code above, the height and width are zero.
Sorry for the long winded post but I figured I would give as much info as possible.