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>
World::getNearestItem(const Vector2f& position) const {
std::shared_ptr<Item> closest;
float distance = std::numeric_limits<float>::max();
for (const auto& v : mDrawables) {
for (const auto& d : v.second) {
std::shared_ptr<Item> converted = std::dynamic_pointer_cast<Item>(d);
if (converted.get() != nullptr &&
thor::squaredLength(converted->getPosition() - position) < distance)
closest = converted;
}
}
return closest;
std::vector<std::shared_ptr<Sprite> >
World::getNearbySprites(const Vector2f& position, float distance) const {
std::vector<std::shared_ptr<Sprite> > ret;
for (const auto& v : mDrawables)
for (const auto& d : v.second)
if (thor::squaredLength(d->getPosition() - position) <= distance * distance)
ret.push_back(d);
return ret;
}

View file

@ -31,7 +31,8 @@ public:
getCharacters(const Vector2f& position, float maxDistance) const;
bool raycast(const Vector2f& lineStart,
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:

View file

@ -18,7 +18,7 @@
const float Character::VISION_DISTANCE = 500.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().
@ -267,26 +267,37 @@ Character::getRightGadgetName() const {
*/
void
Character::pickUpItem() {
std::shared_ptr<Item> item = mWorld.getNearestItem(getPosition());
if (item != nullptr && thor::squaredLength(item->getPosition() - getPosition()) <=
ITEM_PICKUP_MAX_DISTANCE_SQUARED) {
std::shared_ptr<Weapon> weapon = std::dynamic_pointer_cast<Weapon>(item);
if (weapon != nullptr) {
mWorld.insert(mActiveWeapon);
mActiveWeapon->drop(getPosition());
mActiveWeapon = weapon;
mActiveWeapon->setHolder(*this);
auto sprites = mWorld.getNearbySprites(getPosition(),
ITEM_PICKUP_MAX_DISTANCE);
float distance = std::numeric_limits<float>::max();
std::shared_ptr<Item> closest;
for (auto& s : sprites) {
std::shared_ptr<Item> converted = std::dynamic_pointer_cast<Item>(s);
if (converted.get() != nullptr &&
thor::squaredLength(getPosition() - converted->getPosition()) < distance) {
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);
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).
static const float POINT_REACHED_DISTANCE;
/// 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;
World& mWorld;
Pathfinder& mPathfinder;