netlib.narod.ru< Назад | Оглавление | Далее >

Создание игровой сессии

Теперь вы начнете добавлять поддержку сети к вашей игре. Сначала создадим всю поддержку сетевой сессии для вашей новой игры, чтобы позже вы могли получать и отправлять данные между клиентом и сервером. Затем вы объявите объект для созданного вами класса NetworkHelper, а также ограничения для максимального количества локальных игроков и для игровой сессии. Добавьте атрибуты к классу Game1:

// Сетевые ресурсы
private readonly NetworkHelper networkHelper;

private const int maxLocalPlayers   = 1;
private const int maxSessionPlayers = 2;

Затем добавьте ссылки на классы поддержки сети:

using Microsoft.Xna.Framework.Net;

Далее инициализируйте объект networkHelper в конструкторе класса. Добавьте его к игровым службам, поскольку различные классы вашей игры будут в дальнейшем использовать его:

networkHelper = new NetworkHelper();
Services.AddService(typeof(NetworkHelper), networkHelper);

Вы уже можете использовать этот класс. Сперва создайте метод, который создает сессию сетевой игры. Этот метод вызывается, когда пользователь выбирает соответствующий вариант в сетевой сцене:

/// <summary>
/// Создание сессии для сервера игры
/// </summary>
private void CreateSession()
{
    networkHelper.NetworkGameSession = NetworkSession.Create(
                                  NetworkSessionType.SystemLink,
                                  maxLocalPlayers, maxSessionPlayers);
    HookSessionEvents();
    networkScene.State = NetworkScene.NetworkGameState.creating;
    networkScene.Message = "Waiting another player...";
}

 

ПРИМЕЧАНИЕ
Эта версия Rock Rain может создавать игры для использования в локальной сети, вызывая SystemLink в XNA. Процедуры для создания игр, использующих сеть Xbox LIVE точно такие же, но требуют, чтобы у обоих игроков была подписка Creator's Club (даже на PC). Это затрудняет их профессиональное использование, поэтому мы не рассматриваем такие типы соединений в этой книге.

Вы создаете сессию, используя метод Create класса NetworkSession, согласно тому, что вы узнали в предыдущей главе. Вы также инициализируете объект сетевой сцены, чтобы отразить только что выполненное действие, устанавливая его состояние в creating и отображая сообщение, что вы ждете подключения к сессии других игроков.

Метод HookSessionEvents выполняет подписку на некоторые события, которые вам надо обрабатывать для управления сессией, также в соответствии с тем, что вы видели в предыдущей главе. В этой версии Rock Rain вы обрабатываете события, которые происходят когда игрок присоединяется к игре и когда игрок прерывает сессию:

/// <summary>
/// После создания игровой сессии или присоединения к ней
/// мы должны подписаться на некоторые события, чтобы нас
/// уведомляли об изменении состояния сессии
/// </summary>
void HookSessionEvents()
{
    networkHelper.NetworkGameSession.GamerJoined +=
                                 GamerJoinedEventHandler;
    networkHelper.NetworkGameSession.SessionEnded +=
                                SessionEndedEventHandler;
}

Итак, когда сессия прерывается, показанный выше код вызывает метод SessionEndedEventHandler, чтобы снова отобразить сцену сетевой игры, показывая сообщение об ошибке, которое было послано как причина завершения сессии (используя атрибут EndReason класса NetworkSessionEndedEventArgs, передаваемого методу как параметр), как показано ниже:

/// <summary>
/// Обработчик события уведомляет нас, когда игровая сессия завершается
/// </summary>
void SessionEndedEventHandler(object sender, NetworkSessionEndedEventArgs e)
{
    networkScene.Message = e.EndReason.ToString();
    networkScene.State   = NetworkScene.NetworkGameState.idle;

    CloseSession();

    if (activeScene != networkScene)
    {
        ShowScene(networkScene);
    }
}

В методе GamerJoinedEventHandler, вызываемом когда игрок (локальный или удаленный) присоединяется к игровой сессии, вы только проверяете все ли игроки (двое) уже присоединились к сессии, чтобы запустить саму игру. В результате активируется сцена игры для обоих игроков и выполняется привязка игрока к соответствующему объекту Player, который вы будете впоследствии использовать чтобы отличить локального игрока от удаленного:

/// <summary>
/// Этот обработчик события будет вызван,
/// когда новый игрок присоединится к сессии
/// </summary>
void GamerJoinedEventHandler(object sender, GamerJoinedEventArgs e)
{
    // Связываем корабль с присоединившимся игроком 
    if (actionScene.Player1.Gamer == null)
    {
        actionScene.Player1.Gamer = e.Gamer;
    }
    else
    {
        actionScene.Player2.Gamer = e.Gamer;
    }

    if (networkHelper.NetworkGameSession.AllGamers.Count ==
                                                maxSessionPlayers)
    {
        actionScene.TwoPlayers = true;
        ShowScene(actionScene);
    }
}

Метод для прерывания игровой сессии просто освобождает объект NetworkSession, таким же образом, как это делалось в предыдущей главе:

/// <summary>
/// Выход из игровой сессии
/// </summary>
private void CloseSession()
{
    networkHelper.NetworkGameSession.Dispose();
    networkHelper.NetworkGameSession = null;
}

Остался только метод для присоединения к игровой сессии. Код практически тот же, что и в предыдущей главе; вы только добавляете сообщения для сетевой сцены, в зависимости от того успешно или нет прошло подключение к игре:

/// <summary>
/// Присоединяемся к существующей сетевой сессии.
/// </summary>
void JoinSession()
{
    networkScene.Message = "Joining a game...";
    networkScene.State = NetworkScene.NetworkGameState.joining;

    try
    {
        // Поиск сессий.
        using (AvailableNetworkSessionCollection availableSessions =
                  NetworkSession.Find(NetworkSessionType.SystemLink,
                                      maxLocalPlayers, null))
        {
            if (availableSessions.Count == 0)
            {
                networkScene.Message = "No network sessions found.";
                networkScene.State = NetworkScene.NetworkGameState.idle;
                return;
            }

            // Присоединение к первой найденной сессии.
            networkHelper.NetworkGameSession = NetworkSession.Join(
                                                  availableSessions[0]);
            HookSessionEvents();
        }
    }
    catch (Exception e)
    {
        networkScene.Message = e.Message;
        networkScene.State = NetworkScene.NetworkGameState.idle;
    }
}

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


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz