Успешные приложения липкие; они заставляют нас хотеть возвращаться снова и снова, будь то регистрация на Foursquare, отправка твита или быстрый ответ от ChaCha. Игры из всех типов приложений могут быть самыми липкими — Angry Birds кто-нибудь? или в моем случае Wordament ! Отличная идея и реализация — очевидные составляющие успеха, но вы также хотите воспользоваться возможностями, позволяющими вовлечь пользователей, когда они не запускают ваше приложение или игру.
Введите уведомления , которые бывают двух основных видов — плитки и тосты — и самое замечательное, что ваше приложение не должно быть запущено для их получения! Плитка может обновляться с регулярным интервалом , а внешняя служба может в любое время передавать информацию пользователям через плитку или запускать всплывающее уведомление. Чем более привлекательным и динамичным является тайл вашего приложения, тем больше вероятность, что пользователь перезапустит его с экрана «Пуск». Аналогичным образом, чем более убедительным и персонализированным является тост-сообщение, тем больше вероятность того, что пользователь переключится на ваше приложение с того, что он делает.
Обязательные ресурсы
Создайте приложение для Windows 8 за 30 дней
БЕСПЛАТНАЯ 3-месячная пробная версия Windows Azure
Именно этот последний сценарий мы рассмотрим в этой статье, особенно в контексте игры на HTML5 . Что может быть более сильным призывом к действию, чтобы бросить то, что вы делаете, и переиграть игру, чем просто быть информированным, что кто-то выбил вас из верхней позиции в таблице лидеров!
В течение этого поста я расскажу о четырех основных темах с дополнительными материалами, доступными на правой боковой панели:
- Подключение к облаку — настройка мобильной службы Windows Azure
- Настройка примера игры HTML 5 — изменение примера игры для использования мобильного сервиса
- Добавление списка лидеров — создание очень элементарной таблицы лидеров в мобильном сервисе
- Запуск уведомления — запуск всплывающего уведомления для пользователя, который был вытеснен с первого места
Подключение к облаку
Неудивительно, что вам понадобится какой-то централизованный репозиторий для управления игровыми активами, которые являются общими для всех пользователей, например таблица лидеров. Облако, в частности Windows Azure , является отличным местом для размещения общих данных без малейших усилий с вашей стороны: облачный провайдер, в данном случае Microsoft, управляет всеми аппаратными ресурсами и обеспечивает гарантированное время безотказной работы, поддерживаемое соглашениями об уровне обслуживания . А с помощью недавно запущенных мобильных служб Windows Azure вы можете настроить возможности хранения и push-уведомлений с минимальным кодированием с вашей стороны, что позволит вам сконцентрироваться на своей игре!
Чтобы воспользоваться преимуществами и изучить возможности, приобретите бесплатную 90-дневную пробную учетную запись Windows Azure и обязательно активируйте функцию мобильных служб Windows Azure, как показано ниже. В настоящее время эта функция находится в режиме предварительного просмотра, поэтому она не отображается автоматически при просмотре различных служб на портале управления.
Я обнаружил, что опция предоставляется почти сразу, поэтому вы сможете сразу создать новую мобильную услугу.
Ключевые элементы, которые необходимо предоставить для создания нового сервиса, выделены на двух экранах мастера ниже. Каждый сервис будет иметь общедоступную конечную точку — моя — simplegame.azure-mobile.net . Существует также база данных Windows Azure SQL, поддерживающая эту службу с помощью предоставленной мной учетной записи администратора. База данных и службы расположены в центре обработки данных в восточной части США, который в настоящее время является единственным центром обработки данных, доступным на данном этапе предварительного просмотра.
После создания службы запишите ключ приложения, который доступен через строку меню в нижней части портала. Это понадобится вам и уникальный URL-адрес конечной точки службы ( * .azure-mobile.net ) позже.
Настройка примера игры HTML 5
Чтобы сосредоточить статью на теме уведомлений, вместо самой игры, я решил начать с образца HTML5-игры JavaScript в Центре разработки Windows 8 . Это довольно просто: вы просто видите, сколько раз вы можете дотронуться до прыгающего мяча до того, как истечет время, и он поддерживает локальную таблицу лидеров, которую мы расширим в облако.
После того, как вы скачали и установили Mobile Services SDK , добавьте ссылку на него в примере приложения.
Вы также захотите вставить ссылку на компонент среды выполнения Windows в файл default.html следующим образом:
<!-- WinJS references --> <link rel="stylesheet" href="//Microsoft.WinJS.1.0/css/ui-dark.css" /> <script src="//Microsoft.WinJS.1.0/js/base.js"></script> <script src="//Microsoft.WinJS.1.0/js/ui.js"></script> <script src="/MobileServicesJavaScriptClient/MobileServices.js"></script> <!-- App references --> <link rel="stylesheet" href="/css/default.css" /> <script src="/js/assetManager.js"></script> <script src="/js/movingAverage.js"></script>
Пример реализации игры использует игровой JavaScript-шаблон, который вы также можете адаптировать для своих игр. Ключевым компонентом шаблона является класс GameManager , объявленный в конце файла default.js . Это удобный одноэлементный объект, к которому можно добавить ссылку клиента на мобильные службы Windows Azure, как показано ниже:
WinJS.Namespace.define(<span class="str">"GameManager"</span>, { navigateHome: navigateHome, navigateGame: navigateGame, navigateRules: navigateRules, navigateScores: navigateScores, navigateCredits: navigateCredits, showPreferences: showPreferences, onBeforeShow: onBeforeShow, onAfterHide: onAfterHide, game: game, state: state, assetManager: assetManager, scoreHelper: scoreHelper, gameId: gameId, touchPanel: touchPanel, <font style="background-color: rgb(255, 255, 0);">mobileService: <span class="kwrd">new</span> Microsoft.WindowsAzure.MobileServices.MobileServiceClient</font> <font style="background-color: rgb(255, 255, 0);">(<span class="str">"https://simplegame.azure-mobile.net/"</span>, “<<<---- REDACTED ---->>><span class="str">"</span>)</font> });
Добавление таблицы лидеров
Предпосылка уведомления, которое я хочу реализовать, заключается в том, что когда вы выбиваете из первого места в таблице лидеров другого игрока, будет инициировано уведомление, информирующее вас и побуждающее вас занять свою позицию наверху. Для этого необходимо внедрить хотя бы элементарную таблицу лидеров, поэтому для этого я буду использовать функцию данных в мобильных службах Windows Azure . На портале управления Windows Azure будет настроен серверный компонент, а в существующий пример приложения будет добавлен некоторый код.
Серверный компонент
Этот список лидеров довольно прост и отслеживает только имя игрока, счет и уровень. В этой игре нет системы регистрации игроков, поэтому игроки будут идентифицироваться по имени, указанному в разделе «Параметры игры» во всплывающем окне «Настройки» (см. Справа).
Вы можете решить включить собственную систему регистрации игроков или подключиться к существующим поставщикам удостоверений, таким как учетные записи Microsoft, Facebook или Twitter, чтобы подтвердить подлинность личности игрока. Службы Windows Azure Mobile также могут помочь с этим, но это тема для другого поста!
Чтобы сохранить результаты, я создал таблицу в своем мобильном сервисе, которая называется таблицей лидеров . Я не предоставил схему, потому что по умолчанию схема будет создаваться динамически, когда я добавляю данные в таблицу; однако для меня генерируется уникальный столбец кластерного индекса с именем id . В производственной среде вы бы отключили функцию динамической схемы (через вкладку КОНФИГУРАЦИЯ мобильного сервиса), но пока это довольно удобно.
На вкладке DATA мобильного сервиса я создал таблицу с именем лидеров . Вы заметите, что есть опции для контроля прав доступа для различных операций CRUD ; Здесь вы можете заблокировать доступ только для аутентифицированных пользователей или даже разрешить доступ, например, к списку лидеров из других приложений. Как упоминалось ранее, для этого сценария доступ к данным таблицы осуществляется через ключ приложения, который ранее использовался для инициализации клиента мобильной службы в классе GameManager .
Я также создал вторую таблицу с именем users, которая будет содержать дополнительную информацию, необходимую для реализации push-уведомлений, как вы увидите позже.
Клиентский компонент
После установки таблицы сервера мне просто нужно было подключить код клиента, чтобы добавить новую запись в базу данных каждый раз, когда игра завершена. В примере кода уже есть несколько хуков для локальной таблицы лидеров, поэтому я добавляю немного кода в Scores.js, чтобы добавить новую запись в таблицу списка лидеров. Метод вставки здесь асинхронный, и я не предоставил подпрограмму обратного вызова, поэтому фактическая таблица лидеров, отображаемая в игре, продолжит функционировать, как и раньше.
Здесь мне просто было интересно отправить счет на мобильный сервис. Создание пользовательского интерфейса для второй «глобальной» таблицы лидеров выходит за рамки этой статьи, но если вы посмотрите на функциональность примера приложения (в частности, в ScoresPage.js ), вы увидите, что там есть некоторая инфраструктура для нескольких высоких таблицы результатов.
<font class="rem">// Check if a newly achieved score should be added to the score table, ...</font> <font class="rem">// Return value of 0 indicates the submitted score was not good enough to ...</font> newScore: <font class="kwrd">function</font> (score) { <font style="background-color: #ffff00">scoresTable = GameManager.mobileService.getTable(<font class="str">"leaderboard"</font>);</font> <font style="background-color: #ffff00">scoresTable.insert(</font> <font style="background-color: #ffff00">{</font> <font style="background-color: #ffff00">player: score.player,</font> <font style="background-color: #ffff00">score: score.score</font> <font style="background-color: #ffff00">skill: score.skill</font> <font style="background-color: #ffff00">});</font> <font class="kwrd">var</font> newScoreRank = 0; // TODO: Update <font class="kwrd">this</font> <font class="kwrd">function</font> to match the sort of your score table
Если бы вы добавили этот код и играли в игру несколько раз, вы бы увидели новые записи, добавленные в таблицу через меню BROWSE таблицы лидеров, как показано ниже.
Запуск уведомления
В Windows 8 push-уведомления обрабатываются с помощью службы push-уведомлений Windows (WNS), которая размещается и управляется Microsoft. WNS работает в сочетании с клиентской платформой уведомлений, которая является частью операционной системы Windows 8, а также с вашим приложением Windows Store и службой, которую вы поддерживаете в облаке для запуска уведомлений. Процесс запечатлен на изображении ниже, с полным объяснением рабочего процесса, доступным в Центре разработки Windows .
В частности, для нашего игрового сценария рабочий процесс выглядит следующим образом:
Игра запрашивает канал push-уведомлений с клиентской платформы уведомлений на локальном компьютере (1). Платформа клиента уведомлений связывается с WNS (2), который возвращает URI канала уведомления приложению (3). Этот URI уникальным образом идентифицирует устройство и приложение и, таким образом, будет конечной точкой для будущих push-уведомлений. URI непрозрачен и не должен изменяться; более того, срок его действия истекает через 30 дней, поэтому в соответствии с передовой практикой приложение обновляет свой канал при каждом запуске или даже как часть фоновой задачи .
Приложение Магазина Windows отвечает за ведение списка каналов уведомлений, что обычно происходит через облачную службу, которая запускает уведомления в подходящее время и отправляет их уязвимым пользователям приложения. В этой простой игре HTML 5 URI вводятся по имени игрока (4), причем имя каждого игрока связано с устройством, на котором они последний раз играли в игру. Помните, что в настоящее время в игре нет механизма аутентификации, поэтому последний пользователь, претендующий на имя, «выигрывает». Очевидно, что это необходимо исправить для готовой к работе игры, но это не критично для понимания сценария push-уведомлений.
Когда игрок завершает игру, его или ее счет отправляется в облачную службу, которая затем проверяет, является ли новый результат самым высоким. Если это так, служба ищет URI канала уведомлений для игрока, которого только что выгнали, создает всплывающее уведомление и запускает его через WNS (5). В этот момент WNS вступает во владение и доставляет тост соответствующему клиенту (6), где он появляется перед бывшим чемпионом.
Шаги для реализации push-уведомлений включают в себя этап настройки, на котором приложение регистрируется для получения уведомлений, за которым следует бит кодирования как в приложении Магазина Windows, так и в «облачной службе». В этом случае «облачной службой» является мобильная служба Windows Azure , но в целом можно использовать любой доступный по сети сервер, который может проходить проверку подлинности с помощью WNS.
Регистрация уведомлений
Чтобы настроить приложение на получение уведомлений, отображаемое имя пакета и издатель приложения, как показано в Package.appxmanifest , представлены на шаге 2 страницы push-уведомлений Windows и Live Connect :
На шаге 3 страницы Live Connect представлены три значения. Первый, Имя пакета, заменяет имя пакета в Package.appxmanifest в Visual Studio, а два других предоставляются мобильной службе ( вкладка PUSH ) на портале Windows Azure.
Клиентский компонент
Как показано на диаграмме рабочего процесса, процесс начинается с клиентского приложения, защищающего канал уведомления. Приложения запрашивают канал, обычно при запуске, используя асинхронный метод createPushNotificationChannelForApplicationAsync . В default.js , я добавил следующий код , чтобы задать notificationChannel свойства на GameManager когда успех обратного вызова пожаров.
Windows.Networking.PushNotifications.PushNotificationChannelManager. createPushNotificationChannelForApplicationAsync().done( <span class="kwrd">function</span> (c) { GameManager.notificationChannel = c.uri; } );
Поскольку в игре предусмотрена возможность изменения имени игрока, нет смысла записывать канал уведомлений при запуске приложения, потому что никто еще не играл в игру или не зарегистрировался как счет. Фактически, возможно, что несколько игроков могут играть на одном и том же устройстве, поэтому может не быть однозначного соответствия между пользователем и каналом уведомления.
Вместо этого я решил сохранить канал уведомлений с именем игрока, когда игрок заканчивает игру. Поскольку я установил простое правило, согласно которому пользователь будет уведомлен на последнем устройстве, с которого он или она играл, самый простой способ «обновить» таблицу пользователей — это выполнить удаление с последующей вставкой непосредственно перед кодом, который был добавлен в обновить таблицу лидеров .
if (GameManager.usersSeen[score.player] === undefined) { userList = GameManager.mobileService.getTable(<span class="str">"users"</span>); userList.where({ user: score.player }).read().done( <span class="kwrd">function</span> (results) { <span class="kwrd">for</span> (<span class="kwrd">var</span> i in results) userList.del(results[i]); userList.insert( { user: score.player, uri: GameManager.notificationChannel }); GameManager.usersSeen[score.player] = <span class="kwrd">true</span>; } ); }
UsersSeen ассоциативный массив записей игроков , которые играли во время текущего выполнения приложения, поэтому они не раз зарегистрировано в пользователей таблице каждый раз , когда они заканчивают игру.
Серверный компонент
Ранее в этом посте я показал, как настроить мобильные службы Windows Azure для отправки push-уведомлений в игру HTML 5. Единственный оставленный шаг — активировать эти уведомления (и, конечно, создать какой-нибудь убедительный текст уведомления).
Уведомление должно отправляться предыдущему лучшему бомбардиру всякий раз, когда вновь введенный результат выше. В таком случае проще всего вызвать уведомление в скрипте вставки таблицы лидеров . Каждая из операций CRUD над таблицей данных имеет связанный серверный сценарий , реализованный через node.js, который можно использовать для выполнения настраиваемой бизнес-логики на сервере.
Сценарий вставки по умолчанию (справа) просто выполняет входящий запрос, но можно добавить дополнительную логику, например, чтобы определить, когда был достигнут новый высокий балл, и затем отправить уведомление уволенному игроку. Сценарий, который я использовал для этого, показан ниже, за которым следует строка за строкой:
function insert(item, user, request) { mssql.query("select player, score, uri " + "from leaderboard l, users u " + "where (l.player = u.[user]) and " + "(l.player != ?) and " + "(l.score = (select max(score) from simplegame.leaderboard))", [item.player], { success: function(results) { if (results.length > 0 && results[0].score < item.score) { notify(results, item); } request.execute(); }, error: function(err) { console.log(err); request.execute(); } } ); } function notify(results, item) { for (var i in results) { push.wns.sendToastText02(results[i].uri, { text1: "HTML 5 Sample has a new champ!", text2: "Hey, " + results[i].player + ", " + item.player + " just took high score with " + item.score + " points. " + "Time for revenge?!" }); } }
Строка 1 | Функция вставки принимает три аргумента: элемент для вставки (JSON), идентификатор пользователя, запрашивающий вставку (когда установлена аутентификация), и объект запроса, который выполняет вставку. |
Строки 3 — 7 | Запрос определяется по таблице лидеров и таблицам пользователей . Игроки с наибольшим количеством очков возвращаются вместе со связанными с ними URI канала уведомлений (последние хранятся в таблице пользователей ). |
Линия 8 | Этот массив объектов JavaScript определяет параметры запроса, отмеченные в тексте запроса как «?». Здесь в запросе передается имя игрока, только что завершившего игру. Если этот игрок превысил свой собственный рекорд, не имеет смысла отправлять ей уведомление, отсюда и пункт в строке 6 . |
Строка 10 — 14 | success определяет асинхронный обратный вызов, который происходит после завершения запроса. Если игрок только что набрал высокий балл, объект результатов будет содержать информацию об игроках, которые были выбиты с первого места. Этот объект передается вспомогательной функции notify , определенной позже в скрипте. |
Линия 15 | Первоначальный запрос, а именно добавить счет в таблицу лидеров для только что завершенной игры, выполняется. |
Строка 17-20 | При возникновении проблем с запросом в журнал записывается сообщение, которое можно просмотреть на вкладке LOGS мобильной службы на портале Windows Azure. Первоначальный запрос на добавление счета новой игры в таблицу лидеров все еще выполняется. |
Строка 25-37 | Функция notify вызывается всякий раз, когда достигается новый высокий балл. В функцию передается информация о новом высоком счете ( предмет ) и информация ( результаты ) об игроках, которые ранее занимали верхние позиции. |
Линия 29-25 | Для каждого игрока, который набрал или поделился высоким счетом, на его устройство отправляется уведомление, информирующее его о том, что его правление закончилось! Здесь я использовал тост-уведомление, состоящее из одной смелой строки, за которой следуют две строки переноса текста. Существует восемь различных опций уведомления о тостах , которые могут использоваться с разными характеристиками дисплея, включая поддержку изображений. |
Для Джо это может показаться немного похожим, если предположить, что Джули только что играла в игру на своем планшете с Windows 8, и он был занят анализом электронных таблиц Excel на работе.
Что происходит дальше? Когда Джо нажимает на уведомление, активированное событие запускается, и поэтому он запускает игру HTML 5 в своей заявке, чтобы вернуть себе верхнюю позицию.
Что если Джо уже играет в игру, когда прибывает тост, и он нажимает на него? Ну, ничего в этом случае. Он уже находится в приложении, поэтому нажатие на тост будет проигнорировано (если только нет атрибута запуска , который не был предоставлен в данном случае).
Это действительно поднимает точку пользовательского опыта для рассмотрения: если тост будет отображаться на всех , если пользователь уже работает приложение. В большинстве случаев приложение должно просто воспринимать новую информацию на дисплее без дополнительных фанфар. Подумайте о Outlook, например. Когда вы работаете со своим почтовым ящиком, вам действительно нужно видеть тост-уведомления о новых электронных письмах? Они уже появляются в вашем почтовом ящике, так что тост добавляет мало пользы и даже может раздражать. Если вы хотите по какой-либо причине игнорировать уведомления, подпишитесь на событие pushnotificationreceived и установите для свойства cancel значение true; вы все еще можете анализировать содержимое уведомления и действовать в соответствии с ним.
Вот и все! С помощью небольшого количества кода и некоторой отличной поддержки со стороны мобильных служб Windows Azure мы превратили «социальный» в уединенный ранее и изолированный опыт и, надеюсь, привели еще несколько пользователей к нашей игре!