There is a problem “out of memory exception” when exucuting this code. The code takes rapid photos of the main board and stores it to be recompiled into a movie later.
If there is another way to make a replay of the field it would be much appreciated as now I have to take pictures of the board then recompile it into a 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 )
{ }
}
}
}
If you where able to draw the game and board once, surely you could do it another time. All you have to do is store the moves made by each unit, and just replay that.
If you are trying to save it to an avi file consider writing each frame to the harddisk instead of saving them in memory.