代码之家  ›  专栏  ›  技术社区  ›  scottdomini

如何在C++中获取映射中的值的引用?

c++
  •  0
  • scottdomini  · 技术社区  · 3 年前

    我希望我的游戏玩家在与其他实体碰撞时不要移动。 我认为一个解决方案是跟踪游戏中的所有实体,当试图移动时,检查它是否会与其中任何实体发生碰撞。 问题是,当循环向量时,我没有得到实体的引用,而是得到新的值,因此它们有新的ID,我不能再检查ID是否检查。

     // Actor.cpp
    Actor::Actor(float x, float y) : x(x), y(y), m_MovementSpeed(1), m_Alive(true) {
        // ...
        EntityTracker::addEntity(*this);
        this->ID = EntityTracker::entityAmount();
    }
    
    void Actor::move(float _x, float _y) {
        for (auto& e : EntityTracker::entities()) {
            if (this->ID != e->ID && this->collides(*e)) {
                return;
            }
        }
    
        this->x = this->x + _x * m_MovementSpeed;
        this->y = this->y + _y * m_MovementSpeed;
        this->m_Sprite.move(_x * m_MovementSpeed, _y * m_MovementSpeed);
    }
    
    // EntityTracker.cpp
    uint64_t EntityTracker::s_EntityAmount = 0;
    std::map<uint64_t, Actor> EntityTracker::s_Entities {};
    
    void EntityTracker::addEntity(const Actor& actor) {
        EntityTracker::s_Entities.insert(std::pair<uint64_t, Actor>(s_EntityAmount, actor));
        s_EntityAmount++;
    }
    
    std::vector<Actor*> EntityTracker::entities() {
        std::vector<Actor*> actors;
    
        for (auto& it : EntityTracker::s_Entities) {
            std::cout << it.second.ID << std::endl;
            std::cout << it.first << std::endl;
            actors.push_back(&it.second);
        }
    
        return actors;
    }
    
    // EntityTracker.h
    class EntityTracker {
    public:
        static void addEntity(const Actor& actor);
        static bool removeEntity(uint64_t ID);
        static uint64_t entityAmount();
        static std::vector<Actor*> entities();
    private:
        static uint64_t s_EntityAmount;
        static std::map<uint64_t, Actor> s_Entities;
    };
    

    当我按下一个键时,std::cout's print this:

    1571901079888 // actor's internal ID from vector
    0 // ID from vector
    1571901079888
    1
    1571901079888
    0
    ...
    

    我该怎么解决这个问题?

    0 回复  |  直到 3 年前
        1
  •  1
  •   marcinj    3 年前

    可以返回类型为的向量 std::vector<std::reference_wrapper<Actor>> 从…起 EntityTracker::entities() ,以下是此类用途的一个示例:

    // Original data
    std::vector<std::string> vec;
    vec.push_back("one");
    vec.push_back("two");
    
    // Now its copied as references to rvec
    std::vector< std::reference_wrapper<std::string>> rvec;
    for(auto& r: vec)
        rvec.push_back(r);
        
    // Now output original data using rvec references.
    for(auto s: rvec)
        std::cout << s.get() << std::endl;
    

    然后进去 Actor::move 您将可以访问真实参与者的引用,而不是其副本。你也可以考虑 Actor s作为智能指针使用 std::share_ptr .