XNA:创造巨大的图像

时间:2017-01-20 18:42:31

标签: c# xna

我想在Visual Studio中使用Microsoft XNA和C#创建一个大型位图或png文件。我有一个普通的Game1-Class,其中有一个spritebatch可以在屏幕上绘制。我是全新的,在XNA中是一个菜鸟。当我想在游戏中显示它时,一切都很好。但我需要选择导出到任何图像类型,如bmp或png。现在我有一个问题,我想创建一个位图文件,其中包含具有64x64像素的100x100磁贴。我知道,这是非常大的,但我不关心我强大的PC。但我有两个问题:

首先,Microsoft XNA似乎不支持这样的大文件 第二个问题:我的代码甚至不能使用非常小的图块。

我真的需要一次绘制大文件的可能性。还有其他方法的线路,我想在将来绘制,这些线路连接sereral块

编辑:有没有办法将texture2d绘制到System.Drawing.Bitmap中?创建一个System.Drawing.Bitmap可以使用那个大小...现在我只需要填充我的Tiles!

编辑2: 也许我的语言有点令人困惑。我想要做的就是将现有级别保存为大位图或其他图像格式。例如,对于打印或下载,人们有一个内置级别的地图。

这是我的代码(添加了一些评论):

//Idea: creating another spritebatch
SpriteBatch spriteBatch = new SpriteBatch(Game1.graphics.GraphicsDevice);
spriteBatch.Begin();
//typical try and catch
try
{
    //The level is 100x100
    for (int x = 0; x < 100; x++)
    {
        for (int y = 0; y < 100; y++)
        {
            //this is just a test to check if my map contains a tile at this place
            if (this.blockContent[y, x].Foreground.Number != 65535)
            {
                //the tileSetBlock is a large tileset containing many recktangles for the single tiles
                //tileSheetBlock is the big sprite with the tiles
                //load the recktangle from the tileSetBlock depending on the block number at x/y
                bounds = Game1.tileSetBlock[(int)this.blockContent[y, x].Foreground.Number];
                //my idea: draw the sprite to the bitmap-file
                spriteBatch.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
            }
        }
    }
    //here i wanted to create the texture
    Texture2D destination = new Texture2D(Game1.graphics.GraphicsDevice, 6400, 6400);
    //here i wanted to draw the content into my texture
    spriteBatch.Draw(destination, new Rectangle(0, 0, 6400, 6400), Color.White);
    //here i just wanted to save everything
    destination.SaveAsPng(new System.IO.FileStream(@"C:\test.png", System.IO.FileMode.CreateNew), 6400, 6400);
}

也许有一些框架或其他任何可能有帮助的东西?将大图像保存在内存中是没有问题的,如果这是唯一的方法。

2 个答案:

答案 0 :(得分:0)

你永远不会通过从中生成一个完整的位图来渲染一个级别,它效率低下,根本没有意义。

相反,您使用基于图块的渲染并仅渲染屏幕上当前可见的内容。

请参阅我之前在GameDev上关于如何轻松完成此操作的答案:

https://gamedev.stackexchange.com/questions/29121/organize-a-game-set/29930#29930

enter image description here

我刚才写的另一个可能对你有帮助的工具,它将一个关卡位图分解为tile:

https://github.com/aybe/LevelDecomposer

输入:

enter image description here

输出:

enter image description here

您肯定希望使用适当的编辑器生成关卡,例如Tiled

答案 1 :(得分:0)

这是个老问题,但保存生成的纹理需要的是 RenderTarget,它可以让您绘制除屏幕之外的其他内容。

目前你做的是:

  1. 将 Game1.tileSheetBlock 绘制到图形设备中
spriteBatch.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
  1. 您创建新的空纹理绘制它并保存该空纹理...
Texture2D destination = new Texture2D(Game1.graphics.GraphicsDevice, 6400, 6400);
            //here i wanted to draw the content into my texture
            spriteBatch.Draw(destination, new Rectangle(0, 0, 6400, 6400), Color.White);
            //here i just wanted to save everything
            destination.SaveAsPng(new System.IO.FileStream(@"C:\test.png",

 System.IO.FileMode.CreateNew), 6400, 6400);

你需要的是:

  1. 创建具有所需尺寸的 RenderTarget
RenderTarget2D renderTarget = new RenderTarget2D(Game1.graphics.GraphicsDevice, 6400, 6400);
  1. 将其设置为 spritebatches 的首选输出
Game1.graphics.GraphicsDevice.SetRenderTarget(renderTarget);
  1. 画画!
spriteBatch.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
  1. 重置渲染目标,以便您可以再次在屏幕上绘制 :)
gd.SetRenderTarget(null);

由于 RenderTarget 是 Texture2D,你也可以用它做所有与纹理相关的事情(比如保存等等):)