游戏开发中常用的设计模式 【game design patterns】

  1. 单例模式(Singleton Pattern):用于确保在游戏中只存在一个实例,例如游戏管理器(Game Manager)或资源管理器(Resource Manager)。
  2. 工厂模式(Factory Pattern):用于创建对象实例,例如创建不同类型的敌人(Enemy)或武器(Weapon)。
  3. 观察者模式(Observer Pattern):用于实现对象间的事件通知,例如实现角色(Character)与任务(Quest)的交互。
  4. 状态模式(State Pattern):用于管理游戏中对象的状态转换,例如角色在游戏中的状态(生命值、能量等)。
  5. 策略模式(Strategy Pattern):用于实现不同的算法和行为,例如实现不同的AI(Artificial Intelligence)策略。
  6. 组合模式(Composite Pattern):用于创建和管理游戏中的复杂对象结构,例如实现游戏中的菜单(Menu)或场景(Scene)。
  7. 命令模式(Command Pattern):用于将操作(操作)与其执行分离,例如实现游戏中的键盘快捷键。
  8. 装饰器模式(Decorator Pattern: 通过创建一个包装对象,即装饰器,来包裹真正的对象,并且在保持接口的前提下,为它提供额外的功能。

Factory Pattern 工厂

工厂模式 (Factory Pattern) 是一种常用的设计模式,用于创建对象,它能够隐藏创建对象的复杂性,并且使代码更加灵活。在游戏开发中,工厂模式通常用于创建游戏对象、敌人、道具等。

//首先我们定义一个接口,表示我们要创建的对象:
public interface IGameObject
{
    void Update();
}

//创建具体的游戏对象类:
public class Player : IGameObject
{
public void Update()
{
Console.WriteLine("Player is updating.");
}
}

public class Enemy : IGameObject
{
public void Update()
{
Console.WriteLine("Enemy is updating.");
}
}

//创建一个工厂类,用于创建游戏对象
public class GameObjectFactory
{
    public IGameObject CreateGameObject(string type)
    {
        switch (type)
        {
            case "Player":
                return new Player();
            case "Enemy":
                return new Enemy();
            default:
                throw new ArgumentException($"Invalid game object type: {type}");
        }
    }
}

//使用工厂类来创建游戏对象:
GameObjectFactory factory = new GameObjectFactory();

IGameObject player = factory.CreateGameObject("Player");
player.Update(); // Output: "Player is updating."

IGameObject enemy = factory.CreateGameObject("Enemy");
enemy.Update(); // Output: "Enemy is updating."

Singleton Pattern 单例

单例模式是一种常用的设计模式,用于确保一个类只有一个实例,并提供全局访问点。在游戏开发中,单例模式通常用于管理全局状态、资源池等。

public class GameManager
{
    private static GameManager _instance;

    // 私有构造函数,确保只能在类内部创建实例
    private GameManager()
    {
        // 初始化游戏管理器
        Console.WriteLine("GameManager initialized.");
    }

    // 全局访问点
    public static GameManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new GameManager();
            }
            return _instance;
        }
    }

    // 游戏管理器的功能
    public void StartGame()
    {
        Console.WriteLine("Game started.");
    }
}

GameManager gameManager = GameManager.Instance;
gameManager.StartGame(); // Output: "Game started."

GameManager gameManager2 = GameManager.Instance; // 和 gameManager 引用同一个对象

Observer Pattern 观察者

观察者模式是一种常用的设计模式,用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,其它依赖于它的对象都会得到通知并自动更新。在游戏中,观察者模式常常被用来实现游戏中各种实体之间的交互。

public interface IObserver
{
    void OnNotify();
}

public class Subject
{
    private List<IObserver> observers = new List<IObserver>();

    public void AddObserver(IObserver observer)
    {
        observers.Add(observer);
    }

    public void RemoveObserver(IObserver observer)
    {
        observers.Remove(observer);
    }

    public void NotifyObservers()
    {
        foreach (IObserver observer in observers)
        {
            observer.OnNotify();
        }
    }
}

public class Player : IObserver
{
    private Subject subject;

    public Player(Subject subject)
    {
        this.subject = subject;
        subject.AddObserver(this);
    }

    public void OnNotify()
    {
        Console.WriteLine("Player has been notified of a change.");
    }
}

public class Enemy : IObserver
{
    private Subject subject;

    public Enemy(Subject subject)
    {
        this.subject = subject;
        subject.AddObserver(this);
    }

    public void OnNotify()
    {
        Console.WriteLine("Enemy has been notified of a change.");
    }
}

// Usage example
Subject subject = new Subject();
Player player = new Player(subject);
Enemy enemy = new Enemy(subject);

// Notify all observers of a change
subject.NotifyObservers();

State Pattern 状态

状态模式是一种常用的设计模式,用于管理对象的状态转换。在游戏中,状态模式常常被用来管理游戏中实体的各种状态,例如角色的生命值、能量值、攻击状态等。

//定义一个 ICharacterState 接口,它包含了角色状态的公共行为
public interface ICharacterState
{
    void Update();
}

//定义多个具体的状态类
public class RunningState : ICharacterState
{
    public void Update()
    {
        Console.WriteLine("Character is running.");
    }
}

public class JumpingState : ICharacterState
{
    public void Update()
    {
        Console.WriteLine("Character is jumping.");
    }
}

public class AttackingState : ICharacterState
{
    public void Update()
    {
        Console.WriteLine("Character is attacking.");
    }
}

//定义一个 Character 类,它包含了一个 ICharacterState 类型的 State 成员变量,表示当前的状态
public class Character
{
    public ICharacterState State { get; set; }

    public Character(ICharacterState state)
    {
        State = state;
    }

    //定义了一个 ChangeState 方法,用于切换到下一个状态
    public void ChangeState(ICharacterState state)
    {
        State = state;
    }

    public void Update()
    {
        State.Update();
    }
}


Strategy Pattern 策略

定义了一族算法、封装每个算法,并使它们可以互换。策略模式让算法的变化独立于使用算法的客户端,从而提高了程序的灵活性和可维护性。

//定义一个 IStrategy 接口
public interface IStrategy
{
    void Execute();
}
//定义具体的算法实现类
public class AggressiveStrategy : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("Aggressive strategy: attack the player.");
    }
}

public class DefensiveStrategy : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("Defensive strategy: retreat from the player.");
    }
}

public class Enemy
{
    private IStrategy _strategy;

    public Enemy(IStrategy strategy)
    {
        _strategy = strategy;
    }

    public void SetStrategy(IStrategy strategy)
    {
        _strategy = strategy;
    }

    public void DoAction()
    {
        _strategy.Execute();
    }
}

Enemy enemy = new Enemy(new AggressiveStrategy());
enemy.DoAction(); // Output: "Aggressive strategy: attack the player."

enemy.SetStrategy(new DefensiveStrategy());
enemy.DoAction(); // Output: "Defensive strategy: retreat from the player."

策略模式和状态模式的区别

  1. 策略模式通常会将不同的算法实现封装成不同的策略类,客户端可以根据需要选择合适的策略来使用。而状态模式通常会将不同的状态封装成不同的状态类,每个状态类都包含了该状态下的行为实现,并且可以根据对象的内部状态来切换不同的状态。
  2. 在策略模式中,客户端通常需要显式地将选择合适的策略传递给使用该策略的对象,从而实现算法的动态切换。而在状态模式中,对象的状态切换是由对象自身根据内部状态的变化来进行的,客户端无需干预。

策略模式需要客户端明确选择某个策略,状态模式则是游戏过程中根据对象的内部状态变化来进行不同状态的行为

Composite Pattern 组合

用来表示“部分-整体”的层次结构,它允许客户端使用统一的方式处理单个对象和组合对象,从而简化客户端代码

//一个角色可以包含多个装备节点,一个装备节点可以包含多个属性节点。
//这样,你可以通过组合模式来管理角色属性和装备的关系,可以方便地计算出最终的角色属性值。

// 定义一个角色和装备的接口
public interface ICharacter
{
    int GetLevel();
    int GetAttack();
    int GetDefense();
    void Equip(IEquipment equipment);
}

public interface IEquipment
{
    int GetAttackBonus();
    int GetDefenseBonus();
}

// 实现角色类和装备类
public class Player : ICharacter
{
    private int level;
    private int attack;
    private int defense;
    private List<IEquipment> equipments = new List<IEquipment>();

    public Player(int level, int attack, int defense)
    {
        this.level = level;
        this.attack = attack;
        this.defense = defense;
    }

    public int GetLevel()
    {
        return level;
    }

    public int GetAttack()
    {
        int totalAttack = attack;
        foreach (IEquipment equipment in equipments)
        {
            totalAttack += equipment.GetAttackBonus();
        }
        return totalAttack;
    }

    public int GetDefense()
    {
        int totalDefense = defense;
        foreach (IEquipment equipment in equipments)
        {
            totalDefense += equipment.GetDefenseBonus();
        }
        return totalDefense;
    }

    public void Equip(IEquipment equipment)
    {
        equipments.Add(equipment);
    }
}

public class Sword : IEquipment
{
    public int GetAttackBonus()
    {
        return 10;
    }

    public int GetDefenseBonus()
    {
        return 0;
    }
}

public class Shield : IEquipment
{
    public int GetAttackBonus()
    {
        return 0;
    }

    public int GetDefenseBonus()
    {
        return 20;
    }
}

Command Pattern 命令

将请求封装成对象,从而允许我们使用不同的请求、队列或日志来参数化其他对象。命令模式可以实现撤销、恢复操作、事务处理等功能,是一种常见的设计模式之一。
在游戏开发中,命令模式经常用于处理玩家输入和操作。

//定义一个命令接口,它包含执行和撤销方法:
public interface ICommand
{
    void Execute();
    void Undo();
}

//创建具体的命令类
public class MoveCommand : ICommand
{
    private readonly Character _character;
    private readonly Vector3 _direction;
    
    public MoveCommand(Character character, Vector3 direction)
    {
        _character = character;
        _direction = direction;
    }
    
    public void Execute()
    {
        _character.Move(_direction);
    }
    
    public void Undo()
    {
        _character.Move(-_direction);
    }
}

public class AttackCommand : ICommand
{
    private readonly Character _character;
    private readonly Enemy _enemy;
    
    public AttackCommand(Character character, Enemy enemy)
    {
        _character = character;
        _enemy = enemy;
    }
    
    public void Execute()
    {
        _character.Attack(_enemy);
    }
    
    public void Undo()
    {
        _character.StopAttack(_enemy);
    }
}
//创建一个命令队列
public class CommandQueue
{
    private readonly Queue<ICommand> _commands = new Queue<ICommand>();
    
    public void AddCommand(ICommand command)
    {
        _commands.Enqueue(command);
    }
    
    public void ExecuteCommands()
    {
        while (_commands.Count > 0)
        {
            ICommand command = _commands.Dequeue();
            command.Execute();
        }
    }
    
    public void UndoCommands()
    {
        while (_commands.Count > 0)
        {
            ICommand command = _commands.Dequeue();
            command.Undo();
        }
    }
}

//使用命令模式来处理玩家输入
public class PlayerInputHandler : MonoBehaviour
{
    public Character PlayerCharacter;
    public Enemy TargetEnemy;
    
    private readonly CommandQueue _commandQueue = new CommandQueue();
    
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            ICommand command = new MoveCommand(PlayerCharacter, Vector3.forward);
            _commandQueue.AddCommand(command);
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            ICommand command = new MoveCommand(PlayerCharacter, Vector3.back);
            _commandQueue.AddCommand(command);
        }
        else if (Input.GetKeyDown(KeyCode.Space))
        {
            ICommand command = new AttackCommand(PlayerCharacter, TargetEnemy);
            _commandQueue.AddCommand(command);
        }
        else if (Input.GetKeyDown(KeyCode.Z))
        {
            _commandQueue.UndoCommands();
        }
    }
    
    private void FixedUpdate()
    {
        _commandQueue.ExecuteCommands();
    }
}

Decorator Pattern 装饰

是一种结构型设计模式,它动态地将责任附加到对象上,以扩展对象的功能。装饰器模式通过创建一个包装对象,即装饰器,来包裹真正的对象,并且在保持接口的前提下,为它提供额外的功能。

//定义抽象组件
public interface IComponent
{
    void Operation();
}
//定义具体组件类
public class ConcreteComponent : IComponent
{
    public void Operation()
    {
        Console.WriteLine("执行具体组件操作");
    }
}
//定义抽象装饰器类:
public abstract class Decorator : IComponent
{
    protected IComponent component;

    public Decorator(IComponent component)
    {
        this.component = component;
    }

    public virtual void Operation()
    {
        component.Operation();
    }
}

//定义具体装饰器类:
public class ConcreteDecoratorA : Decorator
{
    public ConcreteDecoratorA(IComponent component) : base(component)
    {
    }

    public override void Operation()
    {
        base.Operation();
        Console.WriteLine("具体装饰器A的操作");
    }
}

public class ConcreteDecoratorB : Decorator
{
    public ConcreteDecoratorB(IComponent component) : base(component)
    {
    }

    public override void Operation()
    {
        base.Operation();
        Console.WriteLine("具体装饰器B的操作");
    }
}


//使用装饰器模式来扩展一个对象的功能。例如:
IComponent component = new ConcreteComponent();
component = new ConcreteDecoratorA(component);
component = new ConcreteDecoratorB(component);
component.Operation();

你可能感兴趣的:(设计模式,设计模式)