Fixed collision detection.

This commit is contained in:
Felix Ableitner 2013-05-01 19:07:47 +02:00
parent 027006c966
commit 079c4b539b
3 changed files with 32 additions and 22 deletions

View file

@ -11,6 +11,7 @@
#include "sprites/Tile.h" #include "sprites/Tile.h"
#include "util/Interval.h" #include "util/Interval.h"
#include "util/Log.h"
/** /**
* Insert a drawable into the group. Drawables should only be handled with shared_ptr. * Insert a drawable into the group. Drawables should only be handled with shared_ptr.
@ -75,8 +76,19 @@ World::step(int elapsed) {
it--; it--;
} }
// Apply movement for movable sprites. // Apply movement for movable sprites.
else if (spriteA->getSpeed() != sf::Vector2f()) { else if (spriteA->getSpeed() != sf::Vector2f() &&
bool overlap = false; !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<Sprite> spriteA, int elapsed) {
for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) { for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) {
for (auto& spriteB : w->second) { for (auto& spriteB : w->second) {
if (spriteA == spriteB) if (spriteA == spriteB)
@ -87,15 +99,12 @@ World::step(int elapsed) {
continue; continue;
if (testCollision(spriteA, spriteB, elapsed)) { if (testCollision(spriteA, spriteB, elapsed)) {
spriteA->onCollide(spriteB); spriteA->onCollide(spriteB);
overlap = true; spriteB->onCollide(spriteA);
} return true;
}
}
if (!overlap)
spriteA->setPosition(spriteA->getPosition() + speed);
} }
} }
} }
return false;
} }
/** /**
@ -134,7 +143,6 @@ World::testCollision(std::shared_ptr<Sprite> spriteA,
// circle-circle collision // circle-circle collision
if ((spriteA->mShape.type == Sprite::Shape::Type::CIRCLE) && if ((spriteA->mShape.type == Sprite::Shape::Type::CIRCLE) &&
(spriteB->mShape.type == Sprite::Shape::Type::CIRCLE)) { (spriteB->mShape.type == Sprite::Shape::Type::CIRCLE)) {
sf::Vector2f axis = spriteA->getPosition() - spriteB->getPosition(); sf::Vector2f axis = spriteA->getPosition() - spriteB->getPosition();
// If both objects are at the exact same position, allow any movement for unstucking. // If both objects are at the exact same position, allow any movement for unstucking.
if (axis == sf::Vector2f()) if (axis == sf::Vector2f())

View file

@ -35,8 +35,9 @@ private:
private: private:
void draw(sf::RenderTarget& target, sf::RenderStates states) const; void draw(sf::RenderTarget& target, sf::RenderStates states) const;
bool testCollision(std::shared_ptr<Sprite> spriteA, std::shared_ptr<Sprite> spriteB, bool testCollision(std::shared_ptr<Sprite> spriteA,
int elapsed) const; std::shared_ptr<Sprite> spriteB, int elapsed) const;
bool doesOverlap(std::shared_ptr<Sprite> spriteA, int elapsed);
private: private:
std::map<Sprite::Category, std::vector<std::shared_ptr<Sprite> > > mDrawables; std::map<Sprite::Category, std::vector<std::shared_ptr<Sprite> > > mDrawables;

View file

@ -25,7 +25,8 @@ const sf::Vector2i Tile::TILE_SIZE = sf::Vector2i(75, 75);
*/ */
Tile::Tile(Type type, int x, int y) : Tile::Tile(Type type, int x, int y) :
Sprite(Data(sf::Vector2f(x * TILE_SIZE.x, y * TILE_SIZE.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) { mType(type) {
} }