【问题标题】:Handling collisions with objects that use vector of unique pointers处理与使用唯一指针向量的对象的冲突
【发布时间】:2016-09-01 07:59:16
【问题描述】:
 #pragma once
#include "Entity.h"
#include <iostream>

class Projectile : public Entity
{
public:
    Projectile() {}

    Projectile(float x, float y) {
        load("Graphics/Projectile.png");
        m_sprite.setPosition(x, y);
        m_speed = 400;
    }
};

#pragma once

#include "Entity.h"
#include <iostream>
#include "Projectile.h"

enum class Color {
    red, 
    yellow, 
    brown,
    blue
};

class Enemy : public Entity
{
public:
    Enemy(const Color& c, const sf::Vector2f& pos) {
        switch (c) {
            case Color::blue:
            {
                load("Graphics/blueEnemy.png");
            }
            break;
            case Color::red:
            {
                load("Graphics/redEnemy.png");
            }
            break;
            case Color::yellow:
            {
                load("Graphics/yellowEnemy.png");
            }
            break;
            case Color::brown:
            {
                load("Graphics/brownEnemy.png");
            }
            break;
        }
        setPos(pos);
        m_speed = 100; 
    }
};



  #pragma once
    #include "Entity.h"
    #include "Projectile.h"
    #include <vector>

class Spaceship : public Entity 
{
public:
    Spaceship();
    void move(float);
    void shoot(float);
    void update(float);
    void draw(sf::RenderWindow*) override;
private:
    bool wasSpacePressed; 
    std::vector<std::unique_ptr<Projectile>> m_projectiles; 
    sf::Clock m_clock; 
};


class EnemyFleet : public Entity
{
public:
    EnemyFleet();
    ~EnemyFleet();
    void move(float);
    bool isEnemyBottom() const; 
    bool isLeftMost() const;
    bool isRightMost() const;
    void moveX(float);
    void moveDown();
    void update(float);
    void draw(sf::RenderWindow*) override;

private:
    std::vector<std::unique_ptr<Enemy>> m_enemyFleet; 
    bool m_leftToRight; //motion of the enemyfleet
    float m_speedModifier;
};

我希望能够在弹丸和敌人相互碰撞时删除它们,但我不确定如何执行此操作,因为无法将 unique_ptr 复制到某些碰撞管理器类中的任何参数中,因为它具有专有所有权。 unique_ptr 是否仍然是我应该使用的东西,因为我不必调用 delete(比如它是否是原始 ptr)?

【问题讨论】:

  • unique_ptr 可以通过const referenceconst raw pointer 传递,也可以移动。
  • 但如果我在向量中删除它,我会传递一个向量,而且它也不能是 const,因为我会影响向量内的唯一对象

标签: c++ c++11 sfml


【解决方案1】:

是的,您不能复制 unique_ptr,但您可以从 unique_ptr 指向的对象(ProjectileEnemy)复制或获取引用。

//Example

bool collision_manager::is_collision(Projectile & pr, Enemy & en) {
    if (pr.position() == en.position()) {
        return true;
    }
    return false
}

// similar for other objects that contain vector of unique_ptr
Projectile & Spaceship::get_Projectile(size_t num) {
    if(num < m_projectiles.length()) {
        return *projectiles.at(num);
    }
    throw std::invalid_argument("some alert info");
}
  • 您也可以使用std::move(unique_ptr...),而不是复制。

【讨论】:

  • 有趣但删除向量中 unique_ptr 的位置会很困难
  • 好吧,这并不难,但我想我必须在敌人和射弹中标记一些私有 isAlive 成员,然后使用某种垃圾收集功能擦除所有标记为不活动的对象。我想似乎有点多,有没有更好的方法我没有想到?
  • 我不知道有关您项目的详细信息,但您可能有类似于 main_loop 的东西,其中包含 manager_collision 并可以访问其他对象。要删除对象,您只需在检测到碰撞时使用vector.erase(pos_in_vector),此调用 unique_ptr 中的删除器,该删除器调用指向对象的析构函数。
  • 哦,好的,谢谢。抱歉,最后一个问题是为什么我一次只能在 getter fn 中返回一个弹丸?那将如何工作?做一个指向所有射弹对象的指针向量不是更有意义吗?
  • 如果你有获取一个射弹的引用的函数,你可以很容易地编写一个循环来传递所有射弹。为执行基本操作的小函数组织代码是一种很好的做法。
猜你喜欢
  • 2021-03-31
  • 2011-10-01
  • 2014-04-02
  • 2018-06-03
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 2022-11-13
相关资源
最近更新 更多