Игра XNA собрана GC после запуска обновления - PullRequest
0 голосов
/ 10 марта 2012


Я работаю над созданием заставки, которая возвращает игровой режим (int) и IP-адрес (строка). Идея в том, что запускается заставка, принимает пользовательский ввод и затем запускает основную игру с этими опциями. Я использую поток для достижения этой цели - поток опрашивает запрос на выход из заставки, затем извлекает значения в program.cs и вызывает exit () на всплеск.

Основная игра работает сама по себе, без проблем, но с включенным заставкой игра запускается всего на 1 кадр и, по-видимому, удаляется сборщиком мусора после запуска метода обновления. (возвращает DisposedObjectException или что-то в этом роде, если пытается ссылаться на него) После небольшой отладки я обнаружил, что проблема связана с командой exit. Код выглядит следующим образом:

using System;
using System.Threading;

namespace SplashScreen
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            int choice = 0;
            string ip = "";
            bool runSplash = true;
            bool useThreading = true;
            bool ignoreThreadResponse = false;
            // Debug option, toggle running splash screen
            if (runSplash == true)
            {
                bool splashrunning = true;
                using (Splash1 splash = new Splash1())
                {
                    if (useThreading)
                    {
                        // Run a thread to poll whether the splash screen has requested an exit every 0.5 seconds
                        Thread t = new Thread(() =>
                        {
                            while (splashrunning)
                            {
                                // If splash requests exit pull gameMode choice and IP Address before killing it, then quit this thread
                                if (splash.requestingExit)
                                {
                                    choice = splash.choice;
                                    ip = splash.ip;
                                    // The offending piece of code, without this you can simply select an option, force close and second part runs fine
                                    //splash.Exit();
                                    splashrunning = false;
                                }
                                Thread.Sleep(500);
                            }
                        });
                        t.Start();
                    }
                    splash.Run();
                }
            }
            // If splash screen is not running, assign default values
            if(!useThreading || !runSplash || ignoreThreadResponse)
            {
                choice = 2;
                ip = "127.0.0.1";
            }
            if (choice != 0)
            {
                // This game is picked up by garbage collection after running Update once
                using (Game1 game = new Game1(choice, ip))
                {
                    game.Run();
                }
            }
        }
    }
}

Когда вызывается splash.Exit (), происходит сбор игры1 после первого обновления. Если я отключаю работу с потоками, она работает нормально. Если я выйду с помощью X в правом верхнем углу, он работает нормально. Игнорирует ли я ответ потока, игра не запускается, если поток включен, и я вызываю splash.Exit ().

То, что я ищу, это любое из следующего:

  • Причина сбора второй игры.

  • Альтернативный способ выхода из игры или вызова функции «закрыть окно» (большой красный х).

  • Лучший способ реализовать это.

В прошлом я использовал консольный ввод, но я хочу перейти к использованию графического интерфейса вместо уродливой командной строки для пользователя.

Редактировать:
Оказывается, я был почти там. Хотя GSM, вероятно, является правильным способом решения проблемы, для тех, кто просто хочет взять код из вопроса и проявить осторожность, вам просто нужно добавить поток для запуска второй игры.
Я почти уверен, что это не идеально, но в моем случае это намного проще.

Thread gt = new Thread(() =>
{
    using (Game1 game = new Game1(choice, ip))
    {
        game.Run();
    }
});
gt.Start();

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

1 Ответ

1 голос
/ 10 марта 2012

Как выглядит ваш Splash класс?Exit является методом класса Game и выходит из игры.Ваш Splash класс наследует Game?Если это так, то этого не должно быть.

Редактировать:

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

...