[策略模式]在游戏开发中的应用
一、策略模式
定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。
概述:策略模式将变化封装起来,使得策略使用环境(Context)与实际策略(ConcreteStrategy)分离。在程序运行过程中,面对实际的使用环境时,再决定 Context 使用什么样的 ConcreteStrategy。
1、核心思想
策略模式把角色的行为(算法)和角色(环境)分开。并将策略的选择权交给高层模块,在运行时才确定角色的具体行为。
2、类图
- Context :是策略的使用者(在 ContextInterface 中使用),拥有一个策略接口对象(图中为 object)。
- Strategy :策略接口,提供策略的使用方法。
- ConcreteStrategy :实际策略,是具体策略的实现者。
- Client :客户端,是实际策略与策略使用环境绑定的地点。
5、应用场景以及优缺点
1)应用场景
只要涉及到算法的封装、复用和切换都可以考虑使用策略模式。
2)优点
采用该模式可以方便地更换算法或者增加新的算法。避免了较难维护的多重选择条件选择语句。
3)缺点
缺点:客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。
解决方案:搭配简单工厂模式。
缺点:客户端一次只能使用一个策略类,也就是说每个具体策略间相互独立。
解决方案:装饰模式(待实践)。
二、游戏应用
穿越火线战场上,玩家打落装备后可以跑过去捡起来使用,这个武器可能是M4A1-翔龙、AT15-沙丘或者是KAC锯式机枪。玩家射击时的射速、射程只跟武器有关,而跟玩家没有直接联系。此时将玩家作为环境类、具体武器作为具体策略类,采用策略模式即可实现该过程。
1、伪代码
////////////环境类///////////////////////
class 玩家{
武器 _weapon;
设置武器(weapon){
_weapon = weapon;
}
射击(){
_weapon->射击();
};
}
////////////策略类///////////////////////
class 武器{
射击();
}
class M4A1-翔龙: 武器{
射击(){
printf("翔龙射击");
};
}
class AT15-沙丘: 武器{
射击(){
printf("沙丘射击");
};
}
class KAC锯式机枪: 武器{
射击(){
printf("机枪扫射");
};
}
////////////客户端///////////////////////
...
玩家 player = new 玩家();
武器 weapon = new KAC锯式机枪();
player->设置武器(weapon);
...
player->射击();
...
2、点评
策略模式在该场景中的使用有一个很明显的缺点,穿越火线中的武器十分多样,把每一种武器都写成一个具体策略类显然是不现实的。笔者这样写是简便起见,方便理解。实际的设计应该是按照步枪、机枪、近战武器这样归为不同的策略类。
三、参考
C++设计模式之策略模式 (这篇文章把策略模式在游戏中的使用讲解地很好,本文主要由此处借鉴而来,感谢原文作者)
策略模式定义及其应用 (以魂斗罗中英雄使用不同类型的子弹为例子介绍策略模式的使用)
奇幻RPG(角色技能 与 Strategy模式) (在策略模式的基础上稍微做了深化,更接近实际的游戏代码)
基于状态机的游戏框架(在游戏中,策略模式也能用于状态机管理,此文介绍了状态机的使用)