C++ 如何通过继承实现同一基类绘制不同敌人的专属Sprite?
问题根因
- 构造逻辑冲突:
goblin子类实例化时会优先调用父类enemy的构造函数,父类构造中已经默认加载了npc1.png,直接覆盖了子类的贴图配置逻辑 - 未启用多态机制:父类
enemy的update方法没有声明为虚函数,通过父类指针调用方法时只会执行父类的update逻辑,不会触发子类goblin的重写方法 - 实例化代码错误:
new goblin::enemy本质创建的是enemy父类对象,根本没有生成goblin子类实例,继承逻辑完全未生效 - 贴图加载逻辑不合理:每次
update都执行IO加载贴图会严重影响性能,贴图只需在构造时加载一次即可
解决方案
继承完全可以实现不同敌人加载不同贴图的需求,不需要额外新建其他类,修正后的代码如下:
class enemy { public: sf::RectangleShape rect; float bottom, left, right, top; sf::Texture enemytexture; sf::Sprite enemysprite; enemy(sf::Vector2f position, sf::Vector2f size, sf::Color color) { rect.setPosition(position); rect.setSize(size); rect.setFillColor(color); // 父类默认加载通用贴图,子类可以在自己的构造里覆盖 loadTexture("npc1.png"); } // 声明虚析构函数,避免子类对象通过父类指针释放时内存泄漏 virtual ~enemy() = default; // 声明虚函数,支持子类重写 virtual void update() { // 公共更新逻辑 } protected: // 封装贴图加载方法,方便子类调用 void loadTexture(const std::string& path) { enemytexture.loadFromFile(path); enemysprite.setTexture(enemytexture); } }; class goblin : public enemy { public: // 调用父类构造函数完成基础初始化后,加载子类自身的贴图 goblin(sf::Vector2f position, sf::Vector2f size, sf::Color color) : enemy(position, size, color) { loadTexture("npc2.png"); } // override关键字标注重写父类虚函数 void update() override { // goblin专属的更新逻辑 } }; std::vector<std::unique_ptr<enemy>> enemies1; // 添加普通敌人 enemies1.emplace_back(std::make_unique<enemy>( sf::Vector2f(100, 100), sf::Vector2f(15, 10), sf::Color(255, 255, 255, 255))); // 正确添加goblin子类实例,不要写goblin::enemy enemies1.emplace_back(std::make_unique<goblin>( sf::Vector2f(100, 100), sf::Vector2f(15, 10), sf::Color(255, 255, 255, 255)));
额外优化建议
- 同类型敌人的贴图可以全局复用,不需要每个实例都单独加载一份,避免内存浪费
- 可以把敌人的移动、碰撞判定等通用逻辑都放到父类的虚函数里,子类只需要重写差异部分即可
内容的提问来源于stack exchange,提问作者studyo34
相关产品推荐
相关产品推荐

