游戏编程模式算是一本比较著名的书了,全书针对游戏编程中的问题介绍了多种设计模式。学习设计模式可以加强我们的程序架构能力,写出更加强大和优雅的程序。
在线C#
写在前面
其实针对设计模式,之前我就学习过《大话设计模式》自己也随书将二十多种设计模式实现了一遍;但我在学习游戏开发的过程中发现,标准的设计模式并非对游戏编程支持良好,故而有了专门看一看游戏设计模式的打算,加上寒假学习cpp,让我有了拿起这本书的想法。
此文仅为学习记录,欢迎指正。
设计模式并不是刻意为之的东西,是前辈经验的总结,也许你在不知不觉中就已经使用了某种设计模式。
命令模式
将一个请求封装成一个对象,从而允许你使用不同的请求、队列和日志将将客户端参数化,支持请求的撤销与恢复。
从上述的描述中我们可以找到几个关键点:请求队列,日志,撤销与恢复。
如果你需要这些特性,此事不妨试试命令模式吧。
适用场景
- 试想一下,我们在游戏中需要监听用户的输入,以让我们控制的角色响应玩家发布的
命令,这个命令可能是移动,攻击,也可能是打开菜单,退出游戏。在需要复杂的输入检测时,你可能需要将玩家输入进行组合,如在恰当的时机按下某几个键位就可以使用特殊技能。
- 在网络游戏中,我们操控我们的角色需要在所有连接的客户端中同步,其中有一种同步方式称为
状态同步,及玩家操作角色时,客户端会向所有服务器执行相同的命令,以同步角色的状态信息。这样的情况,多少也使用了命令模式在里面。
- 如果你需要撤销和重做,如一款回合制策略游戏,你可能需要撤销之前的动作,让玩家更专注于策略本身。
代码
根据上述描述,我们可以建立一个最基础的命令模式模板。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| using System; using System.Collections.Generic; using System.Linq;
public class Program { public static void Main() { var pl=new Player(0,0); Console.WriteLine(pl); var moveC=new MoveCommand(1,0,pl); moveC.Excute(); Console.WriteLine(pl); moveC.Undo(); Console.WriteLine(pl); } }
public class Player { public int x,y;
public Player(int x,int y) { this.x=x; this.y=y; }
public override string ToString() { return $"玩家pos:[{x},{y}]"; } }
public abstract class Command { public abstract void Excute(); public abstract void Undo(); }
public class MoveCommand:Command { private int x,y; private Player player; public MoveCommand(int x,int y,Player pl){this.x=x;this.y=y;this.player=pl;} public override void Excute() { Console.WriteLine("Move Excute!"); Console.WriteLine("Move To {0},{1}",x,y); player.x+=x; player.y+=y; } public override void Undo() { Console.WriteLine("Move Undo!!"); player.x-=x; player.y-=y; } }
|
如上所示就是一个命令模式的基本使用,在某些情况下我们应该将所有操作用命令管理,尽管这样比较麻烦,但一旦建立起一个统一的管理模式后,你会发现一切都是值得的。
存在的问题
仔细观察你会发现,我们每次我们使用一个命令都会创建一个命令对象,如果我们频繁的使用命令我们就会不断的创建对象,而这些对象其实我们只使用了一次。怎么解决这个问题呢?下一章的享元模式让我们一起来解决吧。