【问题标题】:XNA: creating huge imagesXNA:创建巨大的图像
【发布时间】:2017-01-20 18:42:30
【问题描述】:

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

首先是微软XNA好像不支持这么大的文件 第二个问题:我的代码甚至不适用于非常小的图块。

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

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

编辑 2: 也许我的语言有点混乱。我想做的就是将现有关卡保存为大位图或其他图像格式。例如,用于打印或下载人们拥有已建成关卡的地图。

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

//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);
}

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

【问题讨论】:

  • 这是一个非常大的图形;即便如此,您遇到了什么错误?
  • 通过创建它说它太大的位图。所以我想我需要一个额外的包。而对于较小的图像,它根本不起作用。我想我误解了如何使用 spritebatch ......我会期望像一个对象这样我可以绘制瓷砖并将其保存为图像。我没有找到任何可能
  • 我的理解是,比你的视频屏幕大的位图总是一个不确定的提议。
  • 但是我怎么画它们呢?还有其他方法吗?也许我不能使用 XNA,而是使用另一个框架来绘制它们

标签: c# xna


【解决方案1】:

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

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

请参阅我之前在 GameDev 上的回答,了解如何轻松做到这一点:

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

我不久前写的另一个可能对你有帮助的工具,它将关卡位图分解为图块:

https://github.com/aybe/LevelDecomposer

输入:

输出:

您当然希望使用适当的编辑器(例如Tiled)生成关卡。

【讨论】:

  • 编辑和查看本身已经工作,我要做的就是将整个关卡保存为地图
  • 我的问题是:输入 -> 级别,输出 -> 整个地图(所以输出应该和你上面的输入一样)
【解决方案2】:

这是个老问题,但保存生成的纹理需要的是 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,你也可以用它做所有与纹理相关的事情(比如保存等):)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多