This is a software design pattern class project, and its main content is a game like "Plants vs Zombies".
将植物与兔子的管理者(RabbitManager, PlantManager)的使用由直接使用构造函数改为单例模式。
之前游戏中植物种植按钮始终为同一种状态,无论当前雨滴数目是否足够种植这种植物,玩家只有在点击按钮并种植到对应位置时才能发现有足够的雨滴来种植这种植物。
经过修改后,我们为植物按钮添加了一种状态(灰色),表示当前这种植物还没有足够的阳光种植。
考虑到只有在雨滴数目发生变化时,植物按钮的状态才会发生改变,因此我们选择在每一帧进行判断,将这一帧的雨滴数目与上一帧进行比较,仅在数目发生变化时才对按钮状态(可点击/不可点击)进行判断刷新
。
种植植物时,原来的做法是将鼠标点击事件的监听、解析与种植动作在一起实现,耦合性过高,不利于实现 Redo/Undo 机制;将其改为监听者承担监听与解析任务,之后由监听者调用种植函数,实现命令模式。
系统维护一个 vector 类型变量,将命令依次存入其中,执行 redo 操作时,在 vector 中向前移动一个命令;执行 undo 操作时, 在 vector 中向后移动一个命令;正常种植时,当前命令以后命令均抛弃,将当前命令加入 vector 中。
为管理命令模式中的命令,自己实现一个类似于链表(最多包含一个分叉的树状结构)的数据结构的模板,可实现添加、删除和恢复功能,使得场景类中的逻辑更加清晰。
方法 | 功能 |
---|---|
addItem | 添加成员,可能需要新开分支,此时删除原分支,创建新分支 |
deleteItem | 删除当前成员(仅指针前移一位),并返回它 |
currentItem | 恢复最近删除的成员(指针后移一位),并返回它 |
当需要选择执行多个行为中的一个行为时,将多个行为的算法分别封装起来成为一个单独的具体strategy,继承于一个抽象的父类Strategy。通过一个环境类维护一个对Strategy对象的引用,再定义一个接口来让Strategy访问它的数据。通过策略模式以达到避免暴露具体算法的数据结构,并使策略易于切换、易于理解、易于扩展。
之前种植植物时,不同植物的种植方法通过if/else直接暴露在场景类下,可维护性低,现在将不同植物的种植方法封装为plantManager下的一个策略,提供接口供环境类访问,在具体的植物管理者子类下分别实现各自的种植策略行为。玩家在选择植物种植时,即选择了一种种植策略,通过环境类来维护选择的strategy,调用其具体的种植算法的方法,有效的降低耦合度。
同样将植物的移除方法封装在plantManager下,在具体的不同植物管理者里实现各自的移除行为。玩家选择移除植物时,环境类会将玩家的选择赋给removeStrategy,然后再调用该strategy算法的方法。
之前兔子的攻击行为只有一种策略,维护性很低,现在将兔子攻击改为多种策略,用多个子攻击策略类封装起来继承于一个抽象的父策略类,分别在各个的子类中实现具体的攻击策略算法。再通过环境类来调用具体的接口,这样方便用户选择攻击策略而又隐藏具体的实现细节,实现低耦合高内聚。并且简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试,保证修改其中任一个或者未来添加新的策略时也不会影响其他的算法,使程序更加灵活。