Статьи

Учебник: как создавать приложения HTML5 на Windows Phone благодаря PhoneGap

Сначала мы увидим в этой статье, каковы дополнительные значения PhoneGap для приложений HTML5. Затем мы узнаем, как создать наш самый первый проект, в котором мы получим значения акселерометра из нашего кода JavaScript. Наконец, мы рассмотрим полный пример игрового HTML5, почти полностью перенесенный в PhoneGap, чтобы использовать акселерометр, доступный на телефонах Windows.  

  1. Вступление
  2. PhoneGap: рамки, заполняющие пробел
  3. Давайте создадим наш первый проект PhoneGap
  4. Получение значений акселерометра из JavaScript
  5. Обзор полного примера с игрой HTML5 Platformer
    1. Форсировать альбомную ориентацию
    2. Обработка различных разрешений
    3. Загрузка уровней с вызовами в файловую систему вместо использования XHR
    4. Модификация игрового процесса для использования акселерометра
    5. Скриншоты результата и FPS на некоторых телефонах
    6. Полное решение Visual Studio для загрузки
  6. Вывод

Вступление

образ

Обновление Mango для Windows Phone пришло с поддержкой HTML5 благодаря встроенному браузеру IE9 . Как и настольная версия, мобильная версия IE9 обеспечивает аппаратное ускорение с помощью графического процессора вашего Windows Phone. Таким образом, в сочетании с JavaScript IE9 теперь может служить основой для интересного пользовательского опыта, обычно зарезервированного для «нативного кода».

Преимущества использования HTML5 в качестве платформы разработки — это относительное обещание легко повторно использовать части кода на других совместимых платформах, таких как Android или iOS. В последние месяцы HTML5 вызвал много интереса в экосистеме разработчиков мобильных устройств.

Тем не менее, даже если спецификации HTML5 / CSS3 / SVG и JavaScript сильно изменились за последние месяцы, им все еще не хватает некоторых основных функций для создания мобильных приложений . Действительно, телефон или планшет обладает такими специфическими возможностями, как: GPS, акселерометр, камера, отправка SMS, доступ к контактам и т. Д.

Чтобы получить доступ к этим возможностям из кода JavaScript, W3C уже некоторое время работает над тем, что мы называем « Device APIs » или DAP . К сожалению, мы можем считать, что в настоящее время не существует реализации этих спецификаций, так как этот документ, кажется, подтверждает: Стандарты для веб-приложений на мобильных устройствах: текущее состояние в ноябре 2011 года и план действий . Mozilla начала интересную работу с более или менее разветвления этих спецификаций через то, что они называют веб-API для поддержки Boot To Geckoпроект. Тогда это хорошая новость, так как форма реализации, кажется, начинается с продолжающихся дискуссий с W3C. Однако, даже если дела начнут развиваться медленно, нам, вероятно, придется подождать несколько лет, прежде чем стабильная официальная спецификация W3C будет широко внедрена на всех платформах.

Итак, вопрос в том, что мы должны делать в это время? Может ли HTML5 действительно удовлетворить эти сценарии?

PhoneGap: рамки, заполняющие пробел

В ожидании реальных стандартизированных спецификаций у нас нет выбора: нам нужно создать мосты между JavaScript и нативным кодом целевой платформы, чтобы иметь доступ к ее возможностям. Идея заключается в следующем: взять родные языки каждой платформы (C #, Objective-C и Java) и создать платформу с этими языками, которая предоставит интерфейсы разработчику JavaScript.

Это именно то, что делает PhoneGap . Давайте возьмем случай с Windows Phone, который является основной темой этой статьи. Проект PhoneGap в Windows Phone — это просто приложение Silverlight, содержащее элемент управления WebBrowser (и, следовательно, IE9), а также сборку Silverlight, написанную на C #, которая выполняет работу по доступу к акселерометру, GPS, контактам, камере и т. Д. Таким образом, как разработчик JavaScript, вы будете использовать DLL с именем WP7GapClassLib.dll (время выполнения ядра PhoneGap), даже не зная об этом, используя код, встроенный в phonegap-1.3.0.js.файл. Эта DLL содержит некоторый код C #, который выполняет вызовы среды выполнения Silverlight, доступной на телефоне. Поскольку среда выполнения имеет доступ ко всем возможностям телефона, JavaScript также подойдет. В этом случае библиотека JavaScript будет действовать в качестве шлюза между обоими мирами. Более того, хорошая польза от использования этой библиотеки в том, что ваш код будет работать в большинстве случаев как есть на версиях PhoneGap для Android или iOS. PhoneGap предлагает интересную форму переносимости.

Обратите внимание на то, что поддержка PhoneGap для Windows Phone теперь полностью завершена с последней версии 1.3.0:

Наконец, PhoneGap предлагает еще один интересный сервис. Он встраивает ваши ресурсы .js, .css, .html, .png в свои проекты, чтобы упаковать его как классическое приложение. Таким образом, вы можете использовать PhoneGap для упаковки вашего приложения HTML5 для магазинов различных приложений. Это, например, случай приложения SujiQ для Windows Phone, созданного с использованием этого подхода.

Давайте создадим наш первый проект PhoneGap

Предпосылки

Вот самые первые шаги, которые вы должны выполнить:

  1. Загрузить Windows Phone SDK: Windows Phone SDK
  2. Загрузите последнюю версию телефона (1.3.0 сегодня) на их сайте: http://phonegap.com/
  3. Распакуйте загруженный файл 
  4. Скопируйте файлы PhoneGapStarter.zip и PhoneGapCustom.zip в \ Documents \ Visual Studio 2010 \ Templates \ ProjectTemplates

Файл-> Новый проект

Как только предыдущие шаги будут выполнены, вы сможете создать свой первый проект PhoneGap. Запустите Visual Studio 2010, выберите шаблоны «Visual C #» и отфильтруйте их с помощью ключевого слова «Gap». Затем вы должны увидеть новый тип проекта с именем PhoneGapStarter :

образ

Назовите свой проект « MyFirstPhoneGapProject ». После этого вы найдете файлы, о которых я говорил ранее, в обозревателе решений:

образ

Вам только сейчас нужно вставить свое приложение HTML5 в каталог «www».

Вот несколько советов, которыми я хотел бы поделиться с вами об этом шаблоне проекта по умолчанию:

никогда не трогайте  файл phonegap-1.3.0.js, если вы хотите сохранить переносимый код в других версиях PhoneGap
— все файлы, которые вы добавите в каталог «www», должны быть установлены как « Content » в свойствах окно 
— вместо двоичного файла WP7GapClassLib.dll вы можете добавить ссылку на проект C7 WP7GapClassLib.csproj, доступный в каталоге « Windows Phone \ framework » загруженного архива PhoneGap. Это поможет вам отладить или обнаружить собственный код библиотеки PhoneGap, если это необходимо.

Хорошо, теперь давайте начнем с того, что обычно делаем по умолчанию с IE9 Mango: доступ к значениям акселерометра из JavaScript.

Получение значений акселерометра из JavaScript

Здесь мы увидим, как получить значения, отправленные обратно акселерометром (эмулятора или реального устройства) очень простым способом.

Откройте страницу « index.html » и измените ее тело по умолчанию следующим образом:

<body>
    <h1>Accelerometer sample</h1>
    <div id="valueX"></div>
    <div id="valueY"></div>
    <div id="valueZ"></div>
</body>

Мы просто будем использовать 3 тега <div> для отображения текущих значений X, Y и Z акселерометра.

Следующий шаг — изменить последний блок <script> по умолчанию следующим образом:

<script type="text/javascript">
    document.addEventListener("deviceready", onDeviceReady, false);

    // variable to output the current x, y & z values of the accelerometer
    var valueX;
    var valueY;
    var valueZ;

    // when PhoneGap tells us everything is ready, start watching the accelerometer
    function onDeviceReady() {
        valueX = document.getElementById("valueX");
        valueY = document.getElementById("valueY");
        valueZ = document.getElementById("valueZ");
        startWatch();
    }

    // start monitoring the state of the accelerometer
    function startWatch() {
        var options = { frequency: 500 };
        navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
    }

    // if the z-axis has moved outside of our sensitivity threshold, move the aarvark's head in the appropriate direction
    function onSuccess(acceleration) {
        valueX.innerHTML = "X: " + acceleration.x;
        valueY.innerHTML = "Y: " + acceleration.y;
        valueZ.innerHTML = "Z: " + acceleration.z;
    }

    function onError() {
        alert('onError!');
    }
</script>

Ну, код, по-моему, достаточно самоочевиден Первое, на что следует обратить внимание, это то, что вам нужно подождать, пока событие « deviceready », вызванное PhoneGap, не будет стабильным. Затем вам нужно подписаться на это событие. В нашем случае мы будем вызываться в функцию OnDeviceReady () . Эта функция получает ссылки на 3 тега <div>, а затем запрашивает уведомление о любых изменениях внутри акселерометра каждые 500 мс с помощью функции startWatch () . Уведомления будут отправлены в функцию onSuccess (), которая будет иметь доступ к объекту ускорения, содержащему значения x, y & z. Вы найдете полную документацию на сайте PhoneGap:Документация PhoneGap — Справочник по API — Акселерометр

Это все, что вам нужно сделать на стороне JavaScript. Однако, чтобы это работало, вам нужно указать в свойствах проекта, что вы хотите запросить доступ к датчику устройства . Возможности, необходимые для правильного выполнения нашего приложения, перечислены в файле WMAppManifest.xml, доступном в каталоге « Properties ». По умолчанию, начиная с 1.3.0, PhoneGap перечисляет строгие минимальные возможности:

<Capabilities>
  <Capability Name="ID_CAP_IDENTITY_DEVICE" />
  <Capability Name="ID_CAP_IDENTITY_USER" />
  <Capability Name="ID_CAP_LOCATION" />
  <Capability Name="ID_CAP_NETWORKING" />
  <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
</Capabilities>

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

<Capability Name="ID_CAP_SENSORS" />

Должен быть разрешен доступ к акселерометру. Вы найдете полный список всех доступных возможностей здесь:  Файл манифеста приложения для Windows Phone

Хорошо, мы логически готовы проверить это внутри эмулятора на первом этапе. Нажмите на волшебную клавишу «F5» и давайте посмотрим на результат:

образ

Перемещая виртуальный телефон в эмуляторе справа, вы должны увидеть обновленные значения акселерометра. Поздравляем!

Вы можете скачать полный исходный код этого первого решения здесь : http://david.blob.core.windows.net/html5/MyFirstPhoneGapProject.zip

Проблемы с телефонами, использующими французский язык

Если вы тестируете тот же код на своем телефоне, настроенном на использование французского языка (как, например, мой! Clignement d'œil), У вас будет ощущение, что приложение вообще не работает… что действительно так. Затем я потратил некоторое время на отладку кода и обнаружил следующее исключение в phonegap-1.3.0.js :

«Ошибка при успешном обратном вызове: акселерометр = синтаксическая ошибка»

После сброса значений я увидел, что ошибка произошла из-за предварительной десериализации следующей плохо отформатированной строки JSON:

«{\» x \ «: 0,00472, \» y \ «: — 0,19879, \» z \ «: — 0,98115}», тогда как правильный EN-US следующий: «{\» х \ «: 0,00472, \» у \ «: — 0,19879, \» г \ «: — 0,98115}»

Да, мы используем кому во Франции как числовой разделитель. Clignement d'œil

2 решения для решения этой проблемы:

1 — Ленивый: переключите свой телефон на EN-US (я знаю, это не решение!)
2 — Исправьте проблему, которая исходит из кода C #. Для этого замените следующий код из Accelometer.cs файле WP7GalClassLib библиотеки:

/// <summary>
/// Formats current coordinates into JSON format
/// </summary>
/// <returns>Coordinates in JSON format</returns>
private string GetCurrentAccelerationFormatted()
{
    string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
                    accelerometer.CurrentValue.Acceleration.X.ToString("0.00000"),
                    accelerometer.CurrentValue.Acceleration.Y.ToString("0.00000"),
                    accelerometer.CurrentValue.Acceleration.Z.ToString("0.00000"));
    resultCoordinates = "{" + resultCoordinates + "}";
    return resultCoordinates;
}

Этим:

private string GetCurrentAccelerationFormatted()
{
    string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
             accelerometer.CurrentValue.Acceleration.X.ToString("0.00000", CultureInfo.InvariantCulture),
             accelerometer.CurrentValue.Acceleration.Y.ToString("0.00000", CultureInfo.InvariantCulture),
             accelerometer.CurrentValue.Acceleration.Z.ToString("0.00000", CultureInfo.InvariantCulture));
    resultCoordinates = "{" + resultCoordinates + "}";
    return resultCoordinates;
}

И образец теперь будет работать со всеми локалями. Я заполнил ошибку по этой теме здесь: https://issues.apache.org/jira/browse/CB-141, предлагая то же решение, которое обычно поставляется в следующей версии (2.0.0).

Кстати, вы, возможно, задаетесь вопросом, как мне удалось отладить часть JavaScript моего проекта PhoneGap? Ну, вы можете просто использовать замечательный проект jsConsole . Если вы хотите узнать больше об этом, прочитайте одну из статей моего коллеги: удаленная отладка jsConsole в IE9 в Windows Phone Mango

Обзор полного примера с игрой HTML5 Platformer

Давайте теперь рассмотрим более сложный образец. Моя идея состояла в том, чтобы начать с игры, которую я написал раньше. Он представлен в этой статье: HTML5 Platformer: полный порт игры XNA для <canvas> с EaselJS . Я хотел посмотреть, что я должен сделать, чтобы это работало на телефоне.

Первый шаг — просто скопировать / вставить различные файлы .js, .png, .css в каталог «www» и пометить их как « Содержимое ». Вот другие шаги, чтобы следовать.

Форсировать альбомную ориентацию

В игру нужно играть в ландшафтном режиме. Я тогда заставил эту ориентацию. Я также удалил информационную панель сбоку (системный трей). Для этого вам нужно открыть файл MainPage.xaml и изменить эти свойства:

SupportedOrientations="Landscape" Orientation="Landscape" shell:SystemTray.IsVisible="False"

Обработка различных разрешений

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

Для этого я немного изменил исходный код Platformer, который вы можете скачать в другой статье . Теперь игра может работать при любом разрешении, применяя коэффициент масштабирования к изображениям и спрайтам для рисования. Все перерисовывается на основе определенного соотношения, полученного от Windows Phone (800×480), которое является соотношением 100%. Вы можете протестировать эту версию в вашем настольном браузере здесь: HTML5 Platformer ReScale и попытаться динамически изменить размер окна браузера. Более того, если ваше разрешение экрана имеет соотношение сторон 16/9, нажмите клавишу F11, чтобы играть в полноэкранном режиме! Опыт в этом режиме действительно крут, как вы можете видеть на этом скриншоте:

образ

Мы позволяем браузеру позаботиться о сглаживании во время этой операции масштабирования. В зависимости от используемого вами браузера вы также заметите, что производительность может сильно зависеть от размера окна, которое у вас будет. На моей машине IE9 / IE10 кажется относительно безразличным к полноэкранному режиму или небольшим разрешениям, поддерживая стабильную частоту кадров 60 кадров в секунду.

Загрузка уровней с вызовами в файловую систему вместо использования XHR

В исходном коде файлы .TXT, связанные с каждым уровнем, сохранялись на веб-сервере и загружались с помощью вызовов XmlHttpRequest. Поскольку сейчас мы выполняем все на стороне клиента в автономном режиме, локальные вызовы XHR не очень подходят. Затем я заменил исходный код функции PlatformerGame.prototype.LoadNextLevel следующим:

PlatformerGame.prototype.LoadNextLevel = function () {
    this.levelIndex = (this.levelIndex + 1) % numberOfLevels;

    // Searching where we are currently hosted
    var nextFileName = "app/www/assets/levels/" + this.levelIndex + ".txt";
    try {
        var instance = this;
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);

        function gotFS(fileSystem) {
            fileSystem.root.getFile(nextFileName, null, gotFileEntry, fail);
        }

        function gotFileEntry(fileEntry) {
            fileEntry.file(gotFile, fail);
        }

        function gotFile(file) {
            readAsText(file);
        }

        function readAsText(file) {
            var reader = new FileReader();
            reader.onloadend = function (evt) {
                instance.LoadThisTextLevel(evt.target.result.replace(/[\n\r\t]/g, ''));
            };
            reader.readAsText(file);
        }

        function fail(evt) {
            console.log(evt.target.error.code);
        }
    }
    catch (e) {
        console.log("Error loading level: " + e.message);
        // Probably an access denied if you try to run from the file:// context
        // Loading the hard coded error level to have at least something to play with
        this.LoadThisTextLevel(hardcodedErrorTextLevel);
    }
};

Я только что повторно использовал код, доступный в документации PhoneGap: FileReader . Как видите, у вас есть полный доступ к файловой системе Windows Phone из JavaScript с PhoneGap.

Полезный совет: чтобы помочь вам отладить то, что действительно хранится в изолированном хранилище телефона или нет, вы должны взглянуть на этот замечательный инструмент: IsoStoreSpy, написанный Сэмюэлем Бланшаром.

Модификация игрового процесса для использования акселерометра

Ну, а последняя часть — просто смешать все части этой статьи, чтобы получить окончательный результат. Для этого я добавил следующий код в конструктор объекта Player в файле Player.js :

var options = { frequency: 500 };
var that = this;

navigator.accelerometer.watchAcceleration(
    function (accelerometer) { that.moveDirectionAccel(accelerometer); },
    function () { console.log("Error with accelerometer"); }, 
    options);

Вот функция, которая будет вызываться при изменениях акселерометра:

Player.prototype.moveDirectionAccel = function(acceleration) {
    var accelValue = -acceleration.y;

    // Move the player with accelerometer
    if (Math.abs(accelValue) > 0.15) {
        // set our movement speed
        this.direction = Math.clamp(accelValue * this.AccelerometerScale, -1, 1);
    }
    else {
        this.direction = 0;
    }
};

Я также добавил обработчик для события « onmousedown » на холсте, чтобы переходить, когда пользователь нажимает на экран.

Скриншоты результата и FPS на некоторых телефонах

Сначала рассмотрим результат в эмуляторе Windows Phone:

образ

У нас есть частота кадров от 54 до 60 кадров в секунду на моей машине. На реальном устройстве частота кадров логически отличается между моделями. Давайте возьмем первый игровой уровень. На LG E900 частота кадров составляет около 22 кадров в секунду . На HTC Radar скорость составляет около 31 кадра в секунду . На Nokia Lumia 800 он составляет около 42 кадров в секунду .

DSCF4677

Игровой процесс может быть не очень убедительным в большинстве случаев. Действительно, я использую полноэкранный холст, чтобы нарисовать всю игру. Это не очень хорошая идея для мобильного процессора с ограниченной мощностью, даже если Nokia кажется достаточно мощной, чтобы справиться с этим подходом. Лучшая методология могла бы заключаться в том, чтобы разрезать экранную сцену на различные маленькие холсты, которые затем будут перемещены путем изменения свойств CSS на них. Это то, что было сделано для HTML5-версии Angry Birds, например. Некоторые игровые платформы JS начинают задумываться о том, как справиться с этой сложностью. Идея заключалась бы в том, чтобы один раз кодировать игру с помощью API высокого уровня, и среда могла переключаться между полнокадровым холстом или различным небольшим холстом, перемещаемым через CSS, в зависимости от производительности.

Well, you’ll get it: the HTML5 gaming experience on mobile is currently just at its beginning. But its future looks very promising!

Complete Visual Studio Solution to download

You’ll find the complete source code of the HTML5 Platformer for PhoneGap here: HTML5GapPlatformer.zip

Other useful resources

Conclusion

PhoneGap offers interesting perspectives to help you writing applications on the phone. It lets you using your existing skills in JavaScript, HTML and CSS. PhoneGap won’t necessary cover all the scenarios currently available with the native development stack (Silverlight or XNA). But this could be something to have a look to if you’d like to capitalize on the HTML skills of one of your team. You will have to pay attention to properly identify the kind of project to work on.

You can also think about mixing both environments to create hybrid experiences: the main branch would be written using “HTML5” and some specific parts into native code. Using this idea, some plug-ins have been created to push a bit further the integration into the Metro UI: PhoneGap Plug-ins for Windows Phone . You’ll find for instance one of them allowing a JavaScript code to update the Tiles.

At last, PhoneGap and HTML5 could allow a relative portability to other platforms… with some limitations. But this is a vast subject with passionate debates that would need a complete dedicated article.

David

 

Source: http://blogs.msdn.com/b/davrous/archive/2011/12/23/tutorial-how-to-create-html5-applications-on-windows-phone-thanks-to-phonegap.aspx