XNA "memory exception". Create a play option

The output of this code raises a memory exception problem. The code takes quick photos of the main board and saves them for later recompilation into a movie.

If there is another way to repeat the field, this would be very useful, since now I need to photograph the board, and then recompile it into an avi movie. Any help please.

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 ) { } } } 

}

+4
source share
2 answers

If you can draw a game and play one time, you can do it another time. All you have to do is save the movements made by each device and just play it back.

If you are trying to save it in an avi file, consider writing each frame to your hard drive rather than saving it in memory.

+3
source

If you save all your scene frames in RAM, most likely you will finish your memory soon, try this calculation:

 number_of_frame_stored * frame_height* frame_width * 32 = .... 

Therefore, periodically unload the saved frames to disk and make sure that the previously allocated memory will be freed (garbage collection).

I see one more problem in your code: you are executing several LoadContent inside the main Draw method. Disk access can be a bottleneck, so try to download all the content you need when your game starts.

+1
source

Source: https://habr.com/ru/post/1380359/


All Articles