diff --git a/source/World.cpp b/source/World.cpp index 4ed88a2..2fdcb14 100755 --- a/source/World.cpp +++ b/source/World.cpp @@ -11,6 +11,7 @@ #include "sprites/Tile.h" #include "util/Interval.h" +#include "util/Log.h" /** * Insert a drawable into the group. Drawables should only be handled with shared_ptr. @@ -75,27 +76,35 @@ World::step(int elapsed) { it--; } // Apply movement for movable sprites. - else if (spriteA->getSpeed() != sf::Vector2f()) { - bool overlap = false; - for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) { - for (auto& spriteB : w->second) { - if (spriteA == spriteB) - continue; - // Ignore anything that is filtered by masks. - if (!spriteA->collisionEnabled(spriteB->getCategory()) || - !spriteB->collisionEnabled(spriteA->getCategory())) - continue; - if (testCollision(spriteA, spriteB, elapsed)) { - spriteA->onCollide(spriteB); - overlap = true; - } - } - } - if (!overlap) - spriteA->setPosition(spriteA->getPosition() + speed); + else if (spriteA->getSpeed() != sf::Vector2f() && + !doesOverlap(spriteA, elapsed)) + spriteA->setPosition(spriteA->getPosition() + speed); + } + } +} + +/** + * Tests spriteA for overlap with every other sprite (considering collision + * masks). + */ +bool +World::doesOverlap(std::shared_ptr spriteA, int elapsed) { + for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) { + for (auto& spriteB : w->second) { + if (spriteA == spriteB) + continue; + // Ignore anything that is filtered by masks. + if (!spriteA->collisionEnabled(spriteB->getCategory()) || + !spriteB->collisionEnabled(spriteA->getCategory())) + continue; + if (testCollision(spriteA, spriteB, elapsed)) { + spriteA->onCollide(spriteB); + spriteB->onCollide(spriteA); + return true; } } } + return false; } /** @@ -134,7 +143,6 @@ World::testCollision(std::shared_ptr spriteA, // circle-circle collision if ((spriteA->mShape.type == Sprite::Shape::Type::CIRCLE) && (spriteB->mShape.type == Sprite::Shape::Type::CIRCLE)) { - sf::Vector2f axis = spriteA->getPosition() - spriteB->getPosition(); // If both objects are at the exact same position, allow any movement for unstucking. if (axis == sf::Vector2f()) diff --git a/source/World.h b/source/World.h index c4c96a0..eac3ff9 100755 --- a/source/World.h +++ b/source/World.h @@ -35,8 +35,9 @@ private: private: void draw(sf::RenderTarget& target, sf::RenderStates states) const; - bool testCollision(std::shared_ptr spriteA, std::shared_ptr spriteB, - int elapsed) const; + bool testCollision(std::shared_ptr spriteA, + std::shared_ptr spriteB, int elapsed) const; + bool doesOverlap(std::shared_ptr spriteA, int elapsed); private: std::map > > mDrawables; diff --git a/source/sprites/Tile.cpp b/source/sprites/Tile.cpp index 5ad9e47..1f4b05f 100644 --- a/source/sprites/Tile.cpp +++ b/source/sprites/Tile.cpp @@ -25,7 +25,8 @@ const sf::Vector2i Tile::TILE_SIZE = sf::Vector2i(75, 75); */ Tile::Tile(Type type, int x, int y) : Sprite(Data(sf::Vector2f(x * TILE_SIZE.x, y * TILE_SIZE.y), - CATEGORY_WORLD, isSolid(type)), Yaml(getConfig(type))), + CATEGORY_WORLD, (isSolid(type)) ? 0xffff : 0), + Yaml(getConfig(type))), mType(type) { }