我有一个小的演示,我想创建一个类,在屏幕上绘制消息像fps率。 我正在阅读一本XNA书,他们评论GameComponents。 我创建了一个inheritanceDrawableGameComponent的类
public class ScreenMessagesComponent : Microsoft.Xna.Framework.DrawableGameComponent
我重写了一些像Initialize或LoadContent的方法。 但是当我想重写绘制我有一个问题,我想传递给它的一些参数。
重写的方法不允许我传递参数。
public override void Draw(GameTime gameTime) { StringBuilder buffer = new StringBuilder(); buffer.AppendFormat("FPS: {0}\n", framesPerSecond); // Where get framesPerSecond from??? spriteBatch.DrawString(spriteFont, buffer.ToString(), fontPos, Color.Yellow); base.Draw(gameTime); }
如果我用参数创建一个方法,那么我不能覆盖它,不会自动调用:
public void Draw(SpriteBatch spriteBatch, int framesPerSecond) { StringBuilder buffer = new StringBuilder(); buffer.AppendFormat("FPS: {0}\n", framesPerSecond); spriteBatch.DrawString(spriteFont, buffer.ToString(), fontPos, Color.Yellow); base.Draw(gameTime); }
所以我的问题是:
给你的DrawableGameComponent一些属性,例如framesPerSecond,你在调用Draw(GameTime)之前设置。 这可能只适用于属性是组件的“自然”部分。
另一种select是使用游戏服务机制。 游戏服务是维持需要彼此交互的对象之间松散耦合的机制。 将服务类添加到游戏服务容器;
//this is usually in the Game.Initialize() Services.AddService(typeof(ContentManager), Content); Services.AddService(typeof(Camera), camera);
DrawableGameCompontent对象可以通过服务提供者访问该服务对象;
//DrawableGameComponent method public void Draw(GameTime gt) { Camera camera = (Camera)Game.Services.GetService(typeof(Camera)); foreach (ModelMesh mesh in invaderModel.Meshes) { foreach (BasicEffect effect in mesh.Effects) { //Effect Settings Goes here effect.LightingEnabled = true; effect.EnableDefaultLighting(); effect.World = world; effect.Projection = camera.Proj; effect.View = camera.View; } mesh.Draw(); } }
这个问题有一个关于使用GameComponents的利弊的有趣的讨论。
主要有两种方式:
看看这个计算帧率: 计算游戏中每秒的帧数
我已经在堆栈溢出回答了一个非常类似的问题。 总结:
将parameter passing给游戏组件方法的最好方法是将parameter passing给! 不幸的是,这排除了GameComponent
的使用 – 因为它的接口是固定的。 这是一个相当弱的API。
最好把GameComponent
当作你如何在游戏中设置“游戏组件”或“角色”系统的例子 。 像XNA的许多其他部分(精灵字体,模型, Game
类本身等) – 你能够并鼓励他们取代它,如果你需要的function,它不提供。
虽然听起来你根本不需要演员或组件系统。 我想你所拥有的每个“组件”都需要传入不同的数据? 简单地用Draw
方法创建一个类? 看看这个答案 。
但是,如果您必须使用GameComponent
,那么可能下一个最好的方法是在其Draw
和/或Update
方法被调用之前在GameComponent
上设置成员属性或字段(他们在Game.Draw
和Game.Update
被调用 – 所以在哪里你可以在你自己的游戏类中调用base.Draw
和base.Update
)。
(可以使用其他方法,只要做最简单的事就行了 。)
问题是像GameComponent
有一个固定的接口; 你不能把它作为一个论点。 因此,你可以做的是创建一个新的项目,作为主游戏类中的服务。 然后,将其添加到您的游戏服务中,并在您需要绘制时尝试获取它。
所以,在你的游戏开始(构造函数或Initialize
方法,无论什么作品)你可以做:
DebugInformer informer = new DebugInformer(); Services.AddService(typeof(DebugInformer), informer);
DebugInformer
是您自己devise的一类。 给它的属性,为你工作像FramesPerSecond
。 你可以添加你想要的特定于你的游戏的其他东西,比如ItemsOnGround
和其他任何适合你的东西。 在代码的后面,你可以得到这些属性,并像这样使用它们:
//In the middle of your specific Component's draw call: DebugInformer informer = Game.Services.GetService(typeof(DebugInformer)) as DebugInformer; if (informer != null) { // Informer is present, use informer.FramesPerSecond and other stuff }
服务是为了这样的问题而devise的,所以不要害怕使用它。
祝你好运!