I'm working on some code to check which side of the box had collided, and then I align the first object to the second one like in 2D games. I know *what* is happening, but I'm pretty confused as to how I would fix it.
The following code will iterate through every tile and check the player against it. Best way I know how to explain the issue is by an example, so here goes.
http://imgur.com/l4ND9Xc
If the above picture continues on its course upwards it will register as a top and right collision. It will register as a right collision and be aligned as such, but then register as a top collision and align as such in one iteration. I'm trying to figure out a way so the following scenario would register as top collision only, and ignore side scenarios (typical 2D collision game play). However, if the user was colliding to the bottom and right like so:
http://imgur.com/wAbBYUp
It should keep the character in position.
BoundingBox and playerSprite has to do with the Player class.
object is a tile or rectangle.
Simply not sure how to go on about this issue since the way I'm thinking of now is checking (colLeft && (!colTop&&!colBottom) then performing proper movement for left collision, but that would be a lot of if-statements. I figured there was someone more experienced that could offer some insight.
// Move sprite
playerSprite.move(movement * deltaTime.asSeconds());
// Set bounding box to current position
boundingBox.setPosition(playerSprite.getPosition());
// Check for collision
for (auto layer = myLoader.GetLayers().begin(); layer != myLoader.GetLayers().end(); ++layer)
{
if (layer->name == "Collision")
{
for (auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
// collision = object->GetAABB().intersects(boundingBox.getGlobalBounds());
if ((boundingBox.getPosition().x + boundingBox.getGlobalBounds().width > object->GetPosition().x &&
boundingBox.getPosition().x < object->GetPosition().x + object->GetAABB().width) &&
(boundingBox.getPosition().y + boundingBox.getGlobalBounds().height > object->GetPosition().y &&
boundingBox.getPosition().y < object->GetPosition().y + object->GetAABB().height))
{
if ((boundingBox.getPosition().x > object->GetPosition().x) &&
(boundingBox.getPosition().x + boundingBox.getGlobalBounds().width > object->GetPosition().x + object->GetAABB().width))
{
boundingBox.setPosition(object->GetPosition().x + object->GetAABB().width, boundingBox.getPosition().y);
std::cout << "Collide on left" << std::endl;
}
else if ((boundingBox.getPosition().x < object->GetPosition().x) &&
(boundingBox.getPosition().x + boundingBox.getGlobalBounds().width < object->GetPosition().x + object->GetAABB().width))
{
boundingBox.setPosition(object->GetPosition().x - boundingBox.getGlobalBounds().width, boundingBox.getPosition().y);
std::cout << "Collide on right" << std::endl;
}
else if ((boundingBox.getPosition().y > object->GetPosition().y) &&
(boundingBox.getPosition().y + boundingBox.getGlobalBounds().height > object->GetPosition().y + object->GetAABB().height))
{
boundingBox.setPosition(boundingBox.getPosition().x, object->GetPosition().y + object->GetAABB().height);
std::cout << "Collide on top" << std::endl;
}
else if ((boundingBox.getPosition().y < object->GetPosition().y) &&
(boundingBox.getPosition().y + boundingBox.getGlobalBounds().height < object->GetPosition().y + object->GetAABB().height))
{
boundingBox.setPosition(boundingBox.getPosition().x, object->GetPosition().y - boundingBox.getGlobalBounds().height);
std::cout << "Collide on bottom" << std::endl;
}
}
}
}
}
playerSprite.setPosition(boundingBox.getPosition());
I managed to figure this out while thinking about it at work. If anyone has a solution to this similar problem I would be interested to see how you checked for collision.
// Move sprite
playerSprite.move(movement * deltaTime.asSeconds());
// Set bounding box to current position
boundingBox.setPosition(playerSprite.getPosition());
// Check for collision
bool collide = false;
float left = 1000;
float right = 1000;
float top = 1000;
float bottom = 1000;
for (auto layer = myLoader.GetLayers().begin(); layer != myLoader.GetLayers().end(); ++layer)
{
if (layer->name == "Collision")
{
for (auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
// collision = object->GetAABB().intersects(boundingBox.getGlobalBounds());
if ((boundingBox.getPosition().x + boundingBox.getGlobalBounds().width > object->GetPosition().x &&
boundingBox.getPosition().x < object->GetPosition().x + object->GetAABB().width) &&
(boundingBox.getPosition().y + boundingBox.getGlobalBounds().height > object->GetPosition().y &&
boundingBox.getPosition().y < object->GetPosition().y + object->GetAABB().height))
{
left = 1000;
right = 1000;
top = 1000;
bottom = 1000;
if ((boundingBox.getPosition().x > object->GetPosition().x) &&
(boundingBox.getPosition().x + boundingBox.getGlobalBounds().width > object->GetPosition().x + object->GetAABB().width))
{
// boundingBox.setPosition(object->GetPosition().x + object->GetAABB().width, boundingBox.getPosition().y);
left = object->GetPosition().x + object->GetAABB().width - boundingBox.getPosition().x;
std::cout << "Left: " << left << std::endl;
std::cout << "Collide on left" << std::endl;
collide = true;
}
if ((boundingBox.getPosition().x < object->GetPosition().x) &&
(boundingBox.getPosition().x + boundingBox.getGlobalBounds().width < object->GetPosition().x + object->GetAABB().width))
{
// boundingBox.setPosition(object->GetPosition().x - boundingBox.getGlobalBounds().width, boundingBox.getPosition().y);
right = boundingBox.getPosition().x + boundingBox.getGlobalBounds().width - object->GetPosition().x;
std::cout << "Right: " << right << std::endl;
std::cout << "Collide on right" << std::endl;
collide = true;
}
if ((boundingBox.getPosition().y > object->GetPosition().y) &&
(boundingBox.getPosition().y + boundingBox.getGlobalBounds().height > object->GetPosition().y + object->GetAABB().height))
{
// boundingBox.setPosition(boundingBox.getPosition().x, object->GetPosition().y + object->GetAABB().height);
top = (object->GetPosition().y + object->GetAABB().height) - boundingBox.getPosition().y;
std::cout << "Top: " << top << std::endl;
std::cout << "Collide on top" << std::endl;
collide = true;
}
if ((boundingBox.getPosition().y < object->GetPosition().y) &&
(boundingBox.getPosition().y + boundingBox.getGlobalBounds().height < object->GetPosition().y + object->GetAABB().height))
{
// boundingBox.setPosition(boundingBox.getPosition().x, object->GetPosition().y - boundingBox.getGlobalBounds().height);
bottom = (boundingBox.getPosition().y + boundingBox.getGlobalBounds().height) - object->GetPosition().y;
std::cout << "Bottom: " << bottom << std::endl;
std::cout << "Collide on bottom" << std::endl;
collide = true;
}
if (collide)
{
if (left < bottom && left < top && left < right)
{
boundingBox.setPosition(object->GetPosition().x + object->GetAABB().width, boundingBox.getPosition().y);
}
else if (right < bottom && right < top && right < left)
{
boundingBox.setPosition(object->GetPosition().x - boundingBox.getGlobalBounds().width, boundingBox.getPosition().y);
}
else if (top < right && top < left && top < bottom)
{
boundingBox.setPosition(boundingBox.getPosition().x, object->GetPosition().y + object->GetAABB().height);
}
else if (bottom < right && bottom < left && bottom < top)
{
boundingBox.setPosition(boundingBox.getPosition().x, object->GetPosition().y - boundingBox.getGlobalBounds().height);
}
}
}
}
}
}
playerSprite.setPosition(boundingBox.getPosition());