基本游戏框架
自己的游戏类继承自Microsoft.Xna.Framework.
Game可以重写方法:Initialize、LoadContent、UnloadContent、Update、Draw
其中Initialize、LoadContent、UnloadContent仅在游戏开始的时候运行一次,而Update和Draw每帧运行。
执行时序为:构造函数→Initialize→LoadContent→[Update→<Draw>]→UnloadContent。
自定义定点类型
要实现自定义的定点类型,需要实现IVertexType接口。
典型的实现为:
public struct VertexPositionNormal : IVertexType
public Vector3 Position;
public Vector3 Normal;
public VertexPositionNormal(Vector3 position, Vector3 normal)
{
Position = position;
Normal = normal;
}
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0));
public VertexDeclaration VertexDeclaration { get { return s_vertexDeclaration; } }
}
接口和基本实现分开
将接口和基本实现分开,可以避免必须从某类继承才能拥有某功能与C#只支持单继承所造成的尴尬。如果功能上确实需要有多个接口,那就可以通过聚合基本类,然后再将接口转接即可。从设计上明确的却分了接口和要求和功能的实现,这是将接口和对接口的基本实现分开的源动力。
空的虚函数
写空的虚函数供子类扩展不是空虚,而是真的有需要。将功能交给一个P都不干的虚函数去做,避免了子类必须明确的一些基类处理约定,并能保证基类将来改动的弹性。要用户每次必须记得子类sub.f中调个base.f(),还要考虑是在sub.f的开头还是结尾去调还真是难为用户了。
对单件的引用
如果类似于Engine这样的类用单件实现,则系统中到处会分布Engine.GetInstance()这样的代码,而从接口上并不能明显看到系统各部分和Engine的耦合,实际上这种“隐式耦合”遍布系统各处。另外一种方式是对需要使用Engine的对象,直接在内部保存一份对Engine的引用,这样接口上会比较明确该对象使用了Engine。单件可通过这种方式拆开的。当然也就提供了Engine变通的可能性。
自定义xml序列化
如果不想单步调试进入太细节的部分可以采用该属性。
公共语言运行库不向该属性附加任何语义。提供它供源代码调试器使用。例如,Visual Studio 调试器不会在标有此属性的方法中停止,但允许在该方法中设置断点。
评论