执行此代码时出现“内存不足异常”问题。该代码拍摄主板的快照,并将其存储起来以便稍后重新编译成电影。
如果有另一种方法来重播该字段,我将非常感激,因为现在我必须拍摄电路板然后将其重新编译成avi电影。 请帮忙。
public class JSTART_Main : Microsoft.Xna.Framework.Game
{
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
private Texture2D background;
private Rectangle mainFrame;
private SpriteFont font;
private bool finished = false;
private BackgroundWorker bw = new BackgroundWorker();
private Navigation navigation;
public JSTART_Main()
{
graphics = new GraphicsDeviceManager(this);
this.graphics.PreferredBackBufferWidth = 1280;
this.graphics.PreferredBackBufferHeight = 768;
navigation = new Navigation();
navigation.graphics = graphics;
navigation.window = Window;
navigation.CreateClasses();
//this.graphics.IsFullScreen = true;
Content.RootDirectory = "Content";
this.IsMouseVisible = true;
navigation.controls.CreateControls();
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_screenshots);
}
protected override void Initialize()
{
base.Initialize();
bw.RunWorkerAsync();
}
void bw_screenshots(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
capture();
capture();
if ((worker.CancellationPending == true))
{
e.Cancel = true;
}
else
{
bw.Dispose();
}
}
void capture()
{
while (finished == false)
{
count += 1;
string counter = count.ToString();
int w = GraphicsDevice.PresentationParameters.BackBufferWidth;
int h = GraphicsDevice.PresentationParameters.BackBufferHeight;
//force a frame to be drawn (otherwise back buffer is empty)
Draw(new GameTime());
//pull the picture from the buffer
int[] backBuffer = new int[w * h];
GraphicsDevice.GetBackBufferData(backBuffer);
//copy into a texture
Texture2D texture = new Texture2D(GraphicsDevice, w, h, false, GraphicsDevice.PresentationParameters.BackBufferFormat);
texture.SetData(backBuffer);
//save to disk
Stream stream = File.OpenWrite(counter + ".jpg");
texture.SaveAsJpeg(stream, w, h);
stream.Flush();
stream.Close();
texture.Dispose();
}
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
background = Content.Load<Texture2D>("Background");
mainFrame = new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
font = Content.Load<SpriteFont>("font");
}
protected override void UnloadContent()
{
}
int count = 0;
protected override void Update(GameTime gameTime)
{
//if (Keyboard.GetState().IsKeyDown(Keys.Escape))
//this.Exit();
foreach (Unit enemy in navigation.players.enemies.Values)
{
enemy.EnemyAI(navigation.aiCollision);
}
navigation.input.UpdateKeyboard();
navigation.networking.Receive();
navigation.players.SpotEnemy();
navigation.input.UpdateMouse();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
try
{
base.Draw(gameTime);
spriteBatch.Begin();
spriteBatch.Draw(background, mainFrame, Color.White);
spriteBatch.DrawString(font, "X: " + navigation.players.server.pos.X.ToString() + "\nY: " + navigation.players.server.pos.Y.ToString(), new Vector2(22, 22), Color.White);
spriteBatch.End();
navigation.players.server.LoadContent(Content);
navigation.players.server.Draw(spriteBatch, Color.Transparent);
foreach (MainObject map in navigation.players.map)
{
map.LoadContent(Content);
map.Draw(spriteBatch);
}
foreach (Unit enemy in navigation.players.enemies.Values)
{
if (navigation.controls.cbxShowEnemies.Checked || enemy.visible == true)
{
enemy.LoadContent(Content);
enemy.Draw(spriteBatch, Color.Red);
}
}
foreach (Unit unit in navigation.players.players.Values)
{
if (unit != null && unit.visible)
{
unit.LoadContent(Content);
unit.Draw(spriteBatch, Color.White);
}
}
}
catch (Exception )
{ }
}
}
}
答案 0 :(得分:3)
如果你能够画一次游戏并登上游戏,你肯定可以再玩一次。您所要做的就是存储每个单元所做的动作,然后重播。
如果您尝试将其保存到avi文件,请考虑将每个帧写入硬盘而不是将其保存在内存中。
答案 1 :(得分:1)
如果您将所有场景帧存储到RAM中,您可能很快就会结束记忆,请尝试进行此计算:
number_of_frame_stored * frame_height* frame_width * 32 = ....
因此,请定期将存储的帧转储到磁盘,并确保释放先前分配的内存(垃圾回收)。
我在你的代码中看到了另一个问题:你在主Draw方法中做了几个LoadContent。磁盘访问可能是一个瓶颈,因此请尝试加载游戏启动时所需的所有内容。