开发游戏常用的设计模式实现案例

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在游戏开发中,设计模式被广泛用于解决代码复用性、可维护性、扩展性和性能优化等问题。以下是游戏开发中常见的几种设计模式及其典型应用场景和作用:

一、单例模式(Singleton)

作用:确保一个类只有一个实例,并提供全局访问点。

应用场景:
全局管理器(如 GameManager、AudioManager、SaveManager)。
共享资源池(如配置表、日志系统)。

注意:需谨慎使用,过度依赖单例会提高代码耦合度。

class GameManager {
private:
    static GameManager* instance;
    GameManager() {} // 私有构造函数
    
public:
    // 删除拷贝构造函数和赋值操作符
    GameManager(const GameManager&) = delete;
    void operator=(const GameManager&) = delete;
	//确保全局只有一个实例
    static GameManager* getInstance() {
        if (!instance) {
            instance = new GameManager();
        }
        return instance;
    }

    void loadLevel(int level) {
        // 加载关卡逻辑
    }
};

// 静态成员初始化
GameManager* GameManager::instance = nullptr;

// 使用示例:
GameManager::getInstance()->loadLevel(1);

二、观察者模式(Observer)

作用:定义对象间的一对多依赖关系,当一个对象状态变化时,自动通知所有依赖它的对象。

应用场景:
事件系统(如成就系统、UI 更新、技能触发)。
游戏内广播(如玩家死亡、任务完成、资源变动)。

优势:解耦事件发布者和订阅者,支持动态添加/移除监听。

#include <vector>
#include <functional>

// 事件发布者
class Player {
private:
    int health;
    std::vector<std::function<void(int)>> healthListeners;

public:
    void addHealthListener(const std::function<void(int)>& listener) {
        healthListeners.push_back(listener);
    }

    void setHealth(int value) {
        health = value;
        for (auto& listener : healthListeners) {
            listener(health); // 通知所有监听者
        }
    }
};

// 事件订阅者(UI)
class HealthUI {
public:
    void updateHealthDisplay(int health) {
        std::cout << "Health: " << health << std::endl;
    }
};

// 使用示例:
Player player;
HealthUI ui;

// 绑定监听(使用 lambda 或 std::bind)
player.addHealthListener([&ui](int health) { ui.updateHealthDisplay(health); });
player.setHealth(80); // 触发 UI 更新

三、状态模式(State)

作用:它的核心作用是通过将对象的状态逻辑封装为独立的类,实现状态切换与行为变化的解耦。
场景:角色或对象的行为可能随状态变化(如待机、移动、攻击、死亡),传统方法会依赖大量 if-else 或 switch 分支判断,导致代码臃肿。

#include <iostream>

// 状态接口
class IPlayerState {
public:
    virtual void enter(class Player* player) = 0;
    virtual void update(Player* player) = 0;
    virtual ~IPlayerState() = default;
};

// 具体状态:待机
class IdleState : public IPlayerState {
public:
    void enter(Player* player) override {
        std::cout << "进入待机状态" << std::endl;
    }

    void update(Player* player) override;
};

// 具体状态:移动
class MoveState : public IPlayerState {
public:
    void enter(Player* player) override {
        std::cout << "进入移动状态" << std::endl;
    }

    void update(Player* player) override;
};

// 玩家类(前向声明解决循环依赖)
class Player {
private:
    IPlayerState* currentState = nullptr;

public:
    void changeState(IPlayerState* newState) {
        delete currentState; // 释放旧状态
        currentState = newState;
        currentState->enter(this);
    }

    void update() {
        if (currentState) currentState->update(this);
    }

    // 示例方法:移动逻辑
    void move() {
        std::cout << "玩家移动中..." << std::endl;
    }
};

// IdleState 的 update 实现
void IdleState::update(Player* player) {
    // 假设检测到输入(伪代码)
    bool isKeyWPressed = true; // 示例值
    if (isKeyWPressed) {
        player->changeState(new MoveState());
    }
}

// MoveState 的 update 实现
void MoveState::update(Player* player) {
    player->move();
}

// 使用示例:
Player player;
player.changeState(new IdleState());
player.update(); // 根据输入切换状态

四、对象池模式(Object Pool)

作用:预先创建并复用对象,避免频繁创建/销毁对象的性能开销。

应用场景:
高频生成/销毁的对象(如子弹、粒子特效、NPC)。
内存敏感场景(移动端游戏)。

优势:减少 GC(垃圾回收)压力,优化性能。

#include <queue>
#include <memory>

class Bullet {
public:
    void reset() { /* 重置子弹状态 */ }
    void fire() { /* 发射逻辑 */ }
};

class BulletPool {
private:
    std::queue<std::unique_ptr<Bullet>> pool;
    
public:
    BulletPool(int initialSize) {
        for (int i = 0; i < initialSize; ++i) {
            pool.push(std::make_unique<Bullet>());
        }
    }

    std::unique_ptr<Bullet> acquire() {
        if (pool.empty()) {
            return std::make_unique<Bullet>(); // 池空时新建
        } else {
            auto bullet = std::move(pool.front());
            pool.pop();
            bullet->reset();
            return bullet;
        }
    }

    void release(std::unique_ptr<Bullet> bullet) {
        pool.push(std::move(bullet));
    }
};

// 使用示例:
BulletPool pool(10);
auto bullet = pool.acquire();
bullet->fire();
pool.release(std::move(bullet)); // 回收子弹

注意

关键差异说明:
内存管理:C++ 需要手动管理内存(或使用智能指针如 unique_ptr/shared_ptr)。
接口实现:C++ 通过抽象基类 (class IXXX) 定义接口。
事件系统:C++ 使用 std::function 和 Lambda 实现类似 C# 的委托功能。
线程安全:单例模式的简单实现未考虑线程安全,实际项目中需根据需求添加锁机制。

总结

以上列举为常用的设计模式。设计模式是解决特定问题的工具,而非万能钥匙。

在游戏开发中需结合具体需求选择模式:
性能敏感:优先使用对象池、享元模式。
状态管理:状态模式、组件模式。
事件驱动:观察者模式、命令模式。
代码扩展性:策略模式、组合模式。

避免过度设计,保持代码简洁性和可维护性始终是关键!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值