C# 新华社:创造巨大的图像
我想在visual Studio中使用Microsoft XNA和C#创建一个大型位图或png文件。我有一个普通的Game1类,可以在屏幕上绘制spritebatch。我是新来的,是新华社的一个新手。当我想在游戏中展示它时,一切都很好。但我需要的选项导出到任何图像类型,如bmp或png。现在我有一个问题,我想创建一个位图文件,其中包含100x100个具有64x64像素的平铺。我知道,这台电脑很大,但我不在乎我的功能强大的电脑。但我有两个问题: 首先,微软XNA似乎不支持如此大的文件 第二个问题:我的代码甚至不能处理非常小的分幅 我真的需要一些可能性来立即绘制那个大文件。还有我将来想画的其他方法的线条,这些线条连接着所有的块 编辑:有没有办法将纹理2D绘制到System.Drawing.Bitmap中?创建System.Drawing.Bitmap可使用该大小。。。现在我只需要把我的瓷砖填满 编辑2: 也许我的语言有点混乱。我所要做的就是将现有级别保存为大位图或其他图像格式。例如,为了打印或下载,人们有一个构建级别的地图 以下是我的代码(添加了一些注释):C# 新华社:创造巨大的图像,c#,xna,C#,Xna,我想在visual Studio中使用Microsoft XNA和C#创建一个大型位图或png文件。我有一个普通的Game1类,可以在屏幕上绘制spritebatch。我是新来的,是新华社的一个新手。当我想在游戏中展示它时,一切都很好。但我需要的选项导出到任何图像类型,如bmp或png。现在我有一个问题,我想创建一个位图文件,其中包含100x100个具有64x64像素的平铺。我知道,这台电脑很大,但我不在乎我的功能强大的电脑。但我有两个问题: 首先,微软XNA似乎不支持如此大的文件 第二个问题:
//想法:创建另一个spritebatch
SpriteBatch SpriteBatch=新SpriteBatch(Game1.graphics.GraphicsDevice);
spriteBatch.Begin();
//典型的试一试
尝试
{
//液位为100x100
对于(int x=0;x<100;x++)
{
对于(int y=0;y<100;y++)
{
//这只是一个测试,用于检查我的地图是否包含此位置的平铺
if(this.blockContent[y,x].Foreground.Number!=65535)
{
//tileSetBlock是一个大型tileset,其中包含单个Tile的多个Recktangle
//tileSheetBlock是有瓷砖的大精灵
//根据x/y处的块号,从平铺块加载recktangle
bounds=Game1.tileSetBlock[(int)this.blockContent[y,x].Foreground.Number];
//我的想法:将精灵绘制到位图文件
spriteBatch.Draw(Game1.tileSheetBlock,新矢量2((y*64),(x*64)),边界,颜色。白色);
}
}
}
//在这里,我想创建纹理
Texture2D destination=新的Texture2D(Game1.graphics.GraphicsDevice,64006400);
//在这里,我想将内容绘制到我的纹理中
spriteBatch.Draw(目标,新矩形(0,0,6400,6400),彩色,白色);
//在这里,我只是想保存一切
destination.SaveAsPng(new System.IO.FileStream(@“C:\test.png”,System.IO.FileMode.CreateNew),64006400);
}
也许有一些框架或其他什么可以帮助你?如果这是唯一的方法,那么在内存中保存大图像是没有问题的。你永远不会通过生成一个完整的位图来渲染一个级别,这是低效的,毫无意义。 而是使用基于平铺的渲染,只渲染屏幕上当前可见的内容 请参阅我之前在GameDev上关于如何轻松实现这一点的回答: 我刚才编写的另一个工具可能对您有所帮助,它将一个级别位图分解为平铺: 输入: 输出:
当然,您最希望使用适当的编辑器生成关卡,例如。这是一个老问题,但保存生成的纹理需要的是RenderTarget,它允许您绘制屏幕以外的其他内容 目前您要做的是:
由于RenderTarget是Texture2D,您也可以使用它来执行与纹理相关的所有操作(如保存等):这是一个非常大的图形;即使如此,你得到了什么错误?通过创建位图它说它太大了。所以我想我需要一个额外的包裹。对于较小的图像,它根本不起作用。我想我误解了如何使用spritebatch。。。我会尝试一些类似于对象的东西,在那里我可以绘制瓷砖并将其保存为图像。我没有发现任何可能性我的理解是,比你的视频屏幕大的位图总是一个不确定的命题。但是我怎么能画它们呢?还有其他方法吗?也许我不能使用XNA,但另一个框架来绘制它们编辑和查看本身已经工作了,我只想将整个级别保存为地图我的问题是:输入->级别,输出->整个地图(因此输出应该与上面的输入类似)
//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.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
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);
RenderTarget2D renderTarget = new RenderTarget2D(Game1.graphics.GraphicsDevice, 6400, 6400);
Game1.graphics.GraphicsDevice.SetRenderTarget(renderTarget);
spriteBatch.Draw(Game1.tileSheetBlock, new Vector2((y * 64), (x * 64)), bounds, Color.White);
gd.SetRenderTarget(null);