Changed World::getNearestItem to getNearbySprites for better reusability.

This commit is contained in:
Felix Ableitner 2013-08-18 13:13:49 +02:00
parent e469211e95
commit 28b086fdc4
4 changed files with 42 additions and 35 deletions

View file

@ -193,19 +193,14 @@ World::raycast(const Vector2f& lineStart,
} }
/** /**
* Returns the item closest to position after linear search. * Returns all sprites that are at most distance pixels away from position.
*/ */
std::shared_ptr<Item> std::vector<std::shared_ptr<Sprite> >
World::getNearestItem(const Vector2f& position) const { World::getNearbySprites(const Vector2f& position, float distance) const {
std::shared_ptr<Item> closest; std::vector<std::shared_ptr<Sprite> > ret;
float distance = std::numeric_limits<float>::max(); for (const auto& v : mDrawables)
for (const auto& v : mDrawables) { for (const auto& d : v.second)
for (const auto& d : v.second) { if (thor::squaredLength(d->getPosition() - position) <= distance * distance)
std::shared_ptr<Item> converted = std::dynamic_pointer_cast<Item>(d); ret.push_back(d);
if (converted.get() != nullptr && return ret;
thor::squaredLength(converted->getPosition() - position) < distance)
closest = converted;
}
}
return closest;
} }

View file

@ -31,7 +31,8 @@ public:
getCharacters(const Vector2f& position, float maxDistance) const; getCharacters(const Vector2f& position, float maxDistance) const;
bool raycast(const Vector2f& lineStart, bool raycast(const Vector2f& lineStart,
const Vector2f& lineEnd) const; const Vector2f& lineEnd) const;
std::shared_ptr<Item> getNearestItem(const Vector2f& position) const; std::vector<std::shared_ptr<Sprite> > getNearbySprites(
const Vector2f& position, float radius) const;
private: private:

View file

@ -18,7 +18,7 @@
const float Character::VISION_DISTANCE = 500.0f; const float Character::VISION_DISTANCE = 500.0f;
const float Character::POINT_REACHED_DISTANCE = 1.0f; const float Character::POINT_REACHED_DISTANCE = 1.0f;
const float Character::ITEM_PICKUP_MAX_DISTANCE_SQUARED = 2500.0f; const float Character::ITEM_PICKUP_MAX_DISTANCE = 50.0f;
/** /**
* Saves pointer to this instance in static var for think(). * Saves pointer to this instance in static var for think().
@ -267,26 +267,37 @@ Character::getRightGadgetName() const {
*/ */
void void
Character::pickUpItem() { Character::pickUpItem() {
std::shared_ptr<Item> item = mWorld.getNearestItem(getPosition()); auto sprites = mWorld.getNearbySprites(getPosition(),
if (item != nullptr && thor::squaredLength(item->getPosition() - getPosition()) <= ITEM_PICKUP_MAX_DISTANCE);
ITEM_PICKUP_MAX_DISTANCE_SQUARED) { float distance = std::numeric_limits<float>::max();
std::shared_ptr<Weapon> weapon = std::dynamic_pointer_cast<Weapon>(item); std::shared_ptr<Item> closest;
if (weapon != nullptr) { for (auto& s : sprites) {
mWorld.insert(mActiveWeapon); std::shared_ptr<Item> converted = std::dynamic_pointer_cast<Item>(s);
mActiveWeapon->drop(getPosition()); if (converted.get() != nullptr &&
mActiveWeapon = weapon; thor::squaredLength(getPosition() - converted->getPosition()) < distance) {
mActiveWeapon->setHolder(*this); closest = converted;
distance = thor::squaredLength(getPosition() - converted->getPosition());
} }
std::shared_ptr<Gadget> gadget = std::dynamic_pointer_cast<Gadget>(item);
if (gadget != nullptr) {
mWorld.insert(mRightGadget);
mRightGadget->drop(getPosition());
mRightGadget = mLeftGadget;
mLeftGadget = gadget;
}
mWorld.remove(item);
} }
else {
if (closest == nullptr) {
std::swap(mLeftGadget, mRightGadget); std::swap(mLeftGadget, mRightGadget);
return;
} }
std::shared_ptr<Weapon> weapon = std::dynamic_pointer_cast<Weapon>(closest);
if (weapon != nullptr) {
mWorld.insert(mActiveWeapon);
mActiveWeapon->drop(getPosition());
mActiveWeapon = weapon;
mActiveWeapon->setHolder(*this);
}
std::shared_ptr<Gadget> gadget = std::dynamic_pointer_cast<Gadget>(closest);
if (gadget != nullptr) {
mWorld.insert(mRightGadget);
mRightGadget->drop(getPosition());
mRightGadget = mLeftGadget;
mLeftGadget = gadget;
}
mWorld.remove(closest);
} }

View file

@ -77,7 +77,7 @@ private:
/// avoid floating point equality check). /// avoid floating point equality check).
static const float POINT_REACHED_DISTANCE; static const float POINT_REACHED_DISTANCE;
/// Maximum distance from character where an item can be picked up. /// Maximum distance from character where an item can be picked up.
static const float ITEM_PICKUP_MAX_DISTANCE_SQUARED; static const float ITEM_PICKUP_MAX_DISTANCE;
friend class World; friend class World;
World& mWorld; World& mWorld;
Pathfinder& mPathfinder; Pathfinder& mPathfinder;