Moved World::checkDelete into World::step, made checks debug only.

This commit is contained in:
Felix Ableitner 2013-03-03 21:55:15 +01:00
parent 12655e0319
commit 3ea80fa5ed
3 changed files with 42 additions and 41 deletions

View file

@ -86,7 +86,6 @@ Game::loop() {
} }
Character::think(elapsed); Character::think(elapsed);
mWorld.checkDelete();
mWorld.step(elapsed); mWorld.step(elapsed);

View file

@ -18,11 +18,12 @@
*/ */
void void
World::insert(std::shared_ptr<Sprite> drawable) { World::insert(std::shared_ptr<Sprite> drawable) {
#ifndef NDEBUG
Sprite::Category cat = drawable->getCategory(); Sprite::Category cat = drawable->getCategory();
auto item = std::find(mDrawables[cat].begin(), mDrawables[cat].end(), drawable); auto item = std::find(mDrawables[cat].begin(), mDrawables[cat].end(), drawable);
if (item == mDrawables[cat].end()) { assert(item == mDrawables[cat].end());
mDrawables[cat].push_back(drawable); #endif
} mDrawables[drawable->getCategory()].push_back(drawable);
} }
/** /**
@ -38,29 +39,46 @@ World::remove(std::shared_ptr<Sprite> drawable) {
} }
} }
/**
* Checks for collisions and applies movement, also removes sprites if
* Sprite::getDelete returns true.
*
* This method can be improved by only testing each pair of sprites once,
* and using the result for both. Applying movement should be done in
* testCollision, always applying the part that causes no collision.
*/
void void
World::step(int elapsed) { World::step(int elapsed) {
for (auto v = mDrawables.begin(); v != mDrawables.end(); v++) { for (auto v = mDrawables.begin(); v != mDrawables.end(); v++) {
for (auto spriteA : v->second) { for (auto it = v->second.begin(); it != v->second.end(); ) {
sf::Vector2f speed = spriteA->getSpeed(); auto spriteA = *it;
speed *= elapsed / 1000.0f; if (spriteA->getDelete()) {
bool overlap = false; remove(spriteA);
for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) { }
for (auto spriteB : w->second) { else {
if (spriteA == spriteB) { sf::Vector2f speed = spriteA->getSpeed();
continue; speed *= elapsed / 1000.0f;
} bool overlap = false;
if (!spriteA->collisionEnabled(spriteB->getCategory()) || !spriteB->collisionEnabled(spriteA->getCategory())) { for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) {
continue; for (auto spriteB : w->second) {
} if (spriteA == spriteB) {
if (testCollision(spriteA, spriteB, elapsed)) { continue;
spriteA->onCollide(spriteB); }
overlap = true; // 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) {
if (!overlap) { spriteA->setPosition(spriteA->getPosition() + speed);
spriteA->setPosition(spriteA->getPosition() + speed); }
it++;
} }
} }
} }
@ -132,23 +150,6 @@ World::testCollision(std::shared_ptr<Sprite> spriteA,
return false; return false;
} }
/**
* Deletes any sprites which return true for getDelete().
*/
void
World::checkDelete() {
for (auto v = mDrawables.begin(); v != mDrawables.end(); v++) {
for (auto item = v->second.begin(); item != v->second.end(); ) {
if ((*item)->getDelete()) {
item = v->second.erase(item);
}
else {
item++;
}
}
}
}
/** /**
* Draws all elements in the group. * Draws all elements in the group.
*/ */

View file

@ -30,9 +30,8 @@ public:
void insert(std::shared_ptr<Sprite> drawable); void insert(std::shared_ptr<Sprite> drawable);
void remove(std::shared_ptr<Sprite> drawable); void remove(std::shared_ptr<Sprite> drawable);
void step(int elapsed); void step(int elapsed);
void checkDelete();
// Private functions. // Private types.
private: private:
class Interval { class Interval {
public: public:
@ -43,6 +42,8 @@ private:
float getLength(); float getLength();
}; };
// Private functions.
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, int elapsed) const; bool testCollision(std::shared_ptr<Sprite> spriteA, std::shared_ptr<Sprite> spriteB, int elapsed) const;