XNA "исключение из памяти" Разработка опции воспроизведения - PullRequest
4 голосов
/ 09 ноября 2011

При выполнении этого кода возникла проблема «исключение нехватки памяти».Код делает быстрые фотографии основной платы и сохраняет их для последующей перекомпиляции в фильм.

Если есть другой способ воспроизвести поле, это будет очень ценно, так как теперь я должен делать снимкидоски затем перекомпилируйте его в 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 )
        { }

    }
}

}

Ответы [ 2 ]

3 голосов
/ 09 ноября 2011

Если вы когда-нибудь могли нарисовать игру и настольную доску один раз, то наверняка вы могли бы сделать это в другой раз. Все, что вам нужно сделать, это сохранить ходы, сделанные каждым отрядом, и просто воспроизвести это.

Если вы пытаетесь сохранить его в avi-файл, попробуйте записать каждый кадр на жесткий диск, а не сохранять его в памяти.

1 голос
/ 09 ноября 2011

Если вы сохраняете в ОЗУ все свои кадры сцены, то, скорее всего, вы скоро закончите работу с памятью, попробуйте выполнить следующие вычисления:

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

Так что периодически сохраняйте сохраненные кадры на диске и убедитесь, чторанее выделенная память будет освобождена (сборщик мусора).

Я вижу еще одну проблему в вашем коде: вы выполняете несколько LoadContent внутри основного метода Draw.Доступ к диску может быть узким местом, поэтому постарайтесь загрузить все необходимое содержимое при запуске игры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...