Разработка игр для Windows 8 с использованием MonoGame: поддержка сенсорных экранов

в 15:11, , рубрики: game development, monogame, Windows 8, Блог компании Microsoft, метки: ,

В предыдущей заметке было рассказано о основных моментах связанных с разработкой игр для Windows 8 и MonoGame. Несмотря на то что игра уже запускается, в ней не хватает важных функций которые необходимы при реализации приложения для Windows 8. Это поддержка прикосновений и обязательный экран privacy policy.

Реализация поддержки прикосновений

ОС Windows 8 может запускаться на самом различном спектре устройств, в том числе на планшетах у которых отсутствует клавиатура. Наша игра является классическим платформером, для управления персонажем в игре реализована только поддержка геймпада и клавиатуры. Для поддержки устройств без клавиатуры но с сенсорным экраном необходимы дополнения в коде.

Текущая реализация MonoGame для Windows 8 позволяет опрашивать состояние сенсора экрана с помощью класса TouchPanel из области видимости Xna.Framework.Input.Touch. Поддерживаются жесты, и комбинированное взаимодействие с мышью. В простейшем случае, для того чтобы выяснить, есть ли нажатие на экран достаточно вызвать метод GetState() который вернет список точек к которым на данный момент осуществлено касание:

            foreach (TouchLocation location in TouchPanel.GetState())
            {
                switch (location.State)
                {
                    case TouchLocationState.Moved:
                        // location.Position.X;
                        // location.Position.Y;
                        // location.Pressure
                        // location.Id
                        break;
                    case TouchLocationState.Pressed:
                        break;
                    case TouchLocationState.Released:
                        break;
                    case TouchLocationState.Invalid:
                        break;
                }
            }

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

Для поддержки касаний мы реализуем стандартный, принятый во многих играх подход – просто будем рисовать на экране изображение клавиш курсора и кнопку прыжка. Далее останется только вычислить координаты областей касаний, и опрашивать их на факт нажатия.

В самой игре CastleX обработка событий управления реализована двумя способами. Основное меню обратабывает события с помощью класса InputState в каждом методе Update() (перед вызовом Draw). При этом класс InputState помнит о предыдущем состоянии нажатия клавиш. Дополнительно, для управления игроком используется прямой опрос состояния клавиатуры. Эти стандартные обработчики требуется модифицировать.

Первое что нам нужно сделать это создать изображения курсорных клавиш и кнопки прыжка. Используя Paint.NET были созданы два PNG файла с прозрачностью:
Разработка игр для Windows 8 с использованием MonoGame: поддержка сенсорных экранов
Разработка игр для Windows 8 с использованием MonoGame: поддержка сенсорных экранов

Далее эти файлы нужно поместить в каталог Assets/GameContent. В принципе у нас даже нет необходимости создавать XNB файл, подсистема контента в MonoGame может прочитать файлы PNG напрямую.
Разработка игр для Windows 8 с использованием MonoGame: поддержка сенсорных экранов

В качестве примера клавиши курсора будут отображаться в менеджере экранов, а кнопка Jump только в экране игры.

Загружаем файл текстуры в методе LoadContent():

arrowkeys_texture = Content.Load<Texture2D>(@"transparent_arrow_keys");

И отображаем на экране в методе Draw()

              SpriteBatch.Begin();
              SpriteBatch.Draw(arrowkeys_texture, drawPos, new Color(0, 0, 0));
              SpriteBatch.End();

При этом будет учтен альфаканал в PNG файле и в результате на экране отобразятся полупрозрачные изображения курсорных клавиш и кнопки:
Разработка игр для Windows 8 с использованием MonoGame: поддержка сенсорных экранов

Но пока это просто статичные изображения и необходимо обрабатывать события нажатия в этой области.

Для этого будет использоваться простой способ – просто зададим координаты области нажатия и будем проверять эту координату на состояние TouchLocationState.Moved

Так же хотелось бы сохранить текущую инфраструктуру обработки событий от клавиатуры и геймпада реализованную в классе InputState.

В специальном методе AddTouchKey(Keys key, Rectangle rect) будет задаваться координата ассоциированная с клавишей, и помимо опроса состояния клавиатуры так же будет вызван метод UpdateTouchKeys()

        internal bool UpdateTouchPos(Dictionary<Keys, bool> key_states )
        {
            bool touched = false;

            foreach (Keys key in _touchKeys.Keys)
                key_states.Add(key,false);

            foreach (TouchLocation location in TouchPanel.GetState())
            {
                touched = true;
                foreach (var k in _touchKeys.Keys)
                {
                    if (location.State == TouchLocationState.Moved)
                    {
                        if (_touchKeys[k].Contains((int)location.Position.X, (int)location.Position.Y))
                        {
                            key_states[k] = true;
                        }
                    }
                }
            }

            return touched;

        }

Этот метод опрашивает все нажатые координаты, и если они входят в список областей нажатия ассоциированных с клавишами, эта кнопка вносится в список нажатых клавиш для дальнейшего использования в методах IsKeyDown() и IsKeyUp()

        public bool IsKeyDown(Keys key)
        {
            if (touchKeys.ContainsKey(key) && isTouched)
                return touchKeys[key];
            else
                return orig_key_state.IsKeyDown(key);
        }

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

     Input.AddTouchKey(Keys.Down, hitPosDown);
     Input.AddTouchKey(Keys.Up, hitPosUp);
     Input.AddTouchKey(Keys.Left, hitPosLeft);
     Input.AddTouchKey(Keys.Right, hitPosRight);


     Input.Update();

Добавляем в игру соглашение о приватности

Одним из важных условий прохождения сертификации при публикации приложений является наличие соглашение о приватности (privacy policy).
Разработка игр для Windows 8 с использованием MonoGame: поддержка сенсорных экранов

Для приложений на MonoGame такой экран реализуется простым способом, в методе Init основгого класса игры производится подписка на события вызова свойств приложения и задается обработчик:

        protected override void Initialize()
        {

            base.Initialize();

            SettingsPane.GetForCurrentView().CommandsRequested += PaneRequest;
        }

        void PaneRequest(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
        {
            UICommandInvokedHandler handler = new UICommandInvokedHandler(onPrivacyPolicyCommand);

            var privPolicyCmd = new SettingsCommand("PrivacyPolicyId", "Privacy Policy", handler);

            args.Request.ApplicationCommands.Add(privPolicyCmd);
        }

        void onPrivacyPolicyCommand(IUICommand command)
        {
            Launcher.LaunchUriAsync(new Uri("http://wincommunity.ru/baller/privacy.html"));
        }

Загрузить исходный проект этими изменениями вы можете по адресу aka.ms/cgt2fr

Автор: dmandreev

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js