2010-10-29 40 views
5

我有一个由2个类(FreeCamera,StaticCamera)实现的接口(ICamera)。这些类是从GameComponent继承的。XNA在运行时动态更改游戏服务

例definiton:

public class FreeCamera : GameComponent, ICamera 
{ 
    ... 
} 

现在我加入了类的游戏组件,并注册的组件之一的游戏服务

private FreeCamera freeCam; 
private StaticCamera staticCam; 

public Game1() 
{ 
    graphics = new GraphicsDeviceManager(this); 
    Content.RootDirectory = "Content"; 
    freeCam = new FreeCamera(this) { Enabled = true }; 
    staticCam = new StaticCamera(this) { Enabled = false }; 
    Services.AddService(typeof(ICamera, freeCam); 
    Components.Add(freeCam); 
    Components.Add(staticCam); 
    ... 
} 

然后我想改变供应商在应用程序流程期间借助于切换功能的服务

namespace Game1 
{ 
    protected override void Update(GameTime gameTime) 
    { 
    var keyboard = Keyboard.GetState(); 
    if(keyboard.IsKeyDown(Keys.C)) 
    { 
     if(freeCam.Enabled) 
     { 
     Services.RemoveService(typeof(ICamera)); 
     Services.AddService(typeof(ICamera, staticCam); 
     freeCam.Enabled = !freeCam.Enabled; 
     staticCam.Enabled = !staticCam.Enabled; 
     } 
     else 
     { 
     Services.RemoveService(typeof(ICamera)); 
     Services.AddService(typeof(ICamera, freeCam); 
     freeCam.Enabled = !freeCam.Enabled; 
     staticCam.Enabled = !staticCam.Enabled; 
     }   
    } 
    base.Update(gameTime); 
    } 
} 

Th e StaticCamera只通过鼠标输入(您可以旋转相机),FreeCamera也可以通过键盘输入来移动。当我调用上面的方法时(通过按下键盘上的C键),FreeCamera类被取消激活,但视口看起来是冻结的,并且不会对任何输入做出反应。当我在短时间内再次调用该方法时,FreeCamera会再次被激活,并且所有内容都按预期工作。

现在我有2个对此问题:

  • 是否有可能改变游戏服务的服务提供商 在 游戏循环?
  • 有没有更好的方法 来处理 游戏中的不同相机类型并轻松切换它们?

在此先感谢您的帮助。

+0

只是一个快速提示为:

所以我建议你更新这个样子的'keyboard.IsKeyDown(Keys.C)&& keyboardLastFrame.IsKeyUp(Keys.C)' – 2010-10-29 12:20:56

回答

0

感谢您的提示。我只是从头脑里写下代码,没有我的IDE,所以请不要过分注意语法错误等。

在我的游戏中,我使用包装类进行输入。代码只是一个简单的例子 - 如果两个类都使用相同的接口,如何替换游戏服务。

我的新想法:我可以使用(在这种情况下,像CameraManager)一个“经理”类有以下方法

public void SetCameraType(CameraType type) //CameraType could be an enum 
public ICamera GetCamera() 

,然后把经理级到服务(拥有自己的界面类似ICameraManager)。

编辑:这被认为是一个答案,上面的评论......但似乎我按错了按钮 -​​ 对不起

1

像你的回答,请使用相机的经理。它既是当前相机的工厂又是容器。经理你可以注册为一项服务。经理看起来像这样:

public class CameraManager 
{ 
    private Dictionary<Type, ICamera> _cameras; 
    private ICamera _current; 

    public ICamera Current 
    { 
     get 
     { 
      return _current; 
     } 
    } 

    // Sets the current cammera to the internal instance of the camera type 
    public void SetCurrent<T>() where T : ICamera 
    { 
     if (!_cameras.ContainsKey(typeof(T))) 
     { 
      // TODO: Instantiate a new camera class here... 
     } 

     _current = _cameras[typeof(T)]; 
    } 
} 

这只是粗略的代码 - 需要填写更多。一个限制是你每个类型只能有一个摄像头。给相机一个字符串名称或一个枚举标志可以让你在任意数量的相机之间切换。

0

我想如果你没有在Update中添加和删除服务的代码,你会很好,并增加了改变Visible属性的行。 Enable属性影响调用Update,但Visible属性影响调用Draw。现在

protected override void Update(GameTime gameTime) 
    { 
    var keyboard = Keyboard.GetState(); 
    if(keyboard.IsKeyDown(Keys.C)) 
    { 
     if(freeCam.Enabled) 
     { 
     freeCam.Enabled = false; 
     freeCam.Visible = false; 

     staticCam.Enabled = true; 
     staticCam.Visible= true; 
     } 
     else 
     { 
     freeCam.Enabled = true; 
     freeCam.Visible = true; 

     staticCam.Enabled = false; 
     staticCam.Visible= false; 
     }   
    } 
    base.Update(gameTime); 
    }