如何在XNA中运行2个游戏对象,或实时更改绘图目的地?

时间:2015-02-18 10:41:02

标签: vb.net multithreading loops xna

我是新来的! 为了我的问题,我搜索了很多网,但我没有找到任何东西 - 或者我真的错了。

我从2年开始在VB.NET上编程,从6个月开始在XNA上编程。我为这个游戏构建了一个游戏和一个编辑器,它们运行得很好。

关于我的编辑(关于RPG游戏)的问题,我会尽力解释。

我有一个带有menustrips的主表单和一个覆盖整个表单的大图片框,当它以Run()命令开始时绑定到Game1对象的picbox。

Game1对象处理两个类,它们基本上是在主窗体的picbox上绘制的面板:标签页左下方的tileset面板和右侧的地图面板。这非常有效。

问题是我昨天第一次尝试在表格上使用XNA绘图。我有多种形式来管理NPC,设备,条件,事件,变量等,在事件形式中,我有一个管理地图传送事件的标签页。在这个标签页上,我有一个地图列表和一个picbox,我想在其中绘制所选地图的小视图。为此,我创建了一个minimap面板,其中包含自己的绘图和更新方法。

...但当然,小地图出现在法线贴图的主窗体上。

我试图实时更改DeviceWindowHandle,但我失败了......显然,它只在Run()

期间发生变化

我试图创建一个新的游戏对象并将他绑定到事件传送形式,但是在对该对象的Run()进行午餐时,调试器停止说我无法在一个线程中启动更多的游戏循环

我无法相信XNA不会在不同形式上绘制多个东西......我无法暂停主循环从事件表单(从NPC表单调用)到启动迷你地图循环!

我觉得这很容易,不幸的是我不知道...... 我变得疯狂和失落......我能做些什么? 请帮助我,谢谢!!

2 个答案:

答案 0 :(得分:0)

您想要的所有内容都显示给您需要在游戏窗口中绘制的玩家。你有一个游戏与一个GraphicsDevice,默认情况下你绘制的所有游戏都会在游戏窗口上呈现。但是您可以调用GraphicsDevice.SetRenderTarget方法来更改渲染目标。使用RenderTarget2D对象作为参数调用它,并在此之后绘制,并将其渲染到该渲染目标。 接下来,您需要调用GraphicsDevice.SetRenderTarget(null)将游戏窗口再次设置为渲染目标。

我的(尚未完成) custom GUI realization用于XNA。我希望它可以帮到你。

更新

class Game1 : Game
{
    GraphicsDevice graphicsDevice;
    SpriteBatch spriteBatch;

    public RenderTarget2D MinimapRenderBuffer;
    public RenderTarget2D AnotherRenderBuffer1;
    public RenderTarget2D AnotherRenderBuffer2;

    public EventHandler RenderBuffersUpdated;

    void Initialize()
    {
        // Better initialize them only once, don't do it in Draw method
        this.MinimapRenderBuffer = new RenderTarget2D(this.graphicsDevice, 100, 100); // any size you want
        this.AnotherRenderBuffer1 = new RenderTarget2D(this.graphicsDevice, 50, 50);
        this.AnotherRenderBuffer2 = new RenderTarget2D(this.graphicsDevice, 500, 500);
    }

    void Draw()
    {
        this.graphicsDevice.SetRenderTarget(this.MinimapRenderBuffer);
        // draw minimap to MinimapRenderBuffer

        this.graphicsDevice.SetRenderTarget(this.AnotherRenderBuffer1);
        // draw whatewer to AnotherRenderBuffer1

        this.graphicsDevice.SetRenderTarget(this.AnotherRenderBuffer2);
        // draw whatewer to AnotherRenderBuffer2

        this.graphicsDevice.SetRenderTarget(null);
        // now draw to screen

        if (this.RenderBuffersUpdated != null)
        {
            RenderBuffersUpdated(null, null);
        }
    }
}

在举办活动时在编辑器中使用rendertargets。你可以convert them to bitmaps

答案 1 :(得分:0)

以下是我评论的一个例子(对不起,它是在C#中,但我并没有真正编写VB.Net。虽然翻译它应该非常简单):

private MainGame mainGame;
private ToolboxGame toolbox1;
private ToolboxGame toolbox2;

// And this should be put in some Form Initialization method:

Task.Factory.StartNew(() => {
        this.mainGame = new MainGame(imgEditorPictureBox.Handle)
        this.mainGame.Run();
    }
Task.Factory.StartNew(() => {
        this.toolbox1 = new ToolboxGame(toolbox1PictureBox.Handle)
        this.toolbox1.Run();
    }
Task.Factory.StartNew(() => {
        this.toolbox2 = new ToolboxGame(toolbox2PictureBox.Handle)
        this.toolbox2.Run();
    }

这样的事情应该这样做。显然,每当你将变量从一个“游戏”“移动”到另一个“游戏”时,请记住它们在不同的线程上运行,所以无论你在哪里使用它,你都需要

lock (dummyObject)
{
    // Use data
}

确保你没有在一个游戏中访问它,而另一个则试图设置它。

锁定VB.Net:Is there a lock statement in VB.NET?

显然,您需要提供一些智能基础设施才能使其顺利运行,但由于您之前已经制作过游戏和编辑器,我相信这不应该是一个巨大的挑战。