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);
mWorld.checkDelete();
mWorld.step(elapsed);

View file

@ -18,11 +18,12 @@
*/
void
World::insert(std::shared_ptr<Sprite> drawable) {
#ifndef NDEBUG
Sprite::Category cat = drawable->getCategory();
auto item = std::find(mDrawables[cat].begin(), mDrawables[cat].end(), drawable);
if (item == mDrawables[cat].end()) {
mDrawables[cat].push_back(drawable);
}
assert(item == mDrawables[cat].end());
#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
World::step(int elapsed) {
for (auto v = mDrawables.begin(); v != mDrawables.end(); v++) {
for (auto spriteA : v->second) {
sf::Vector2f speed = spriteA->getSpeed();
speed *= elapsed / 1000.0f;
bool overlap = false;
for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) {
for (auto spriteB : w->second) {
if (spriteA == spriteB) {
continue;
}
if (!spriteA->collisionEnabled(spriteB->getCategory()) || !spriteB->collisionEnabled(spriteA->getCategory())) {
continue;
}
if (testCollision(spriteA, spriteB, elapsed)) {
spriteA->onCollide(spriteB);
overlap = true;
for (auto it = v->second.begin(); it != v->second.end(); ) {
auto spriteA = *it;
if (spriteA->getDelete()) {
remove(spriteA);
}
else {
sf::Vector2f speed = spriteA->getSpeed();
speed *= elapsed / 1000.0f;
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);
if (!overlap) {
spriteA->setPosition(spriteA->getPosition() + speed);
}
it++;
}
}
}
@ -132,23 +150,6 @@ World::testCollision(std::shared_ptr<Sprite> spriteA,
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.
*/

View file

@ -30,9 +30,8 @@ public:
void insert(std::shared_ptr<Sprite> drawable);
void remove(std::shared_ptr<Sprite> drawable);
void step(int elapsed);
void checkDelete();
// Private functions.
// Private types.
private:
class Interval {
public:
@ -43,6 +42,8 @@ private:
float getLength();
};
// Private functions.
private:
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
bool testCollision(std::shared_ptr<Sprite> spriteA, std::shared_ptr<Sprite> spriteB, int elapsed) const;