Игра на UWP: С чего стоит начать
Привет, Хабр! Сегодня мы запускаем экспериментальную серию статей. Вы погрузитесь в реалити-шоу для программистов-самоучек, в котором Алексей Плотников, один из участников нашего сообщества Microsoft Developer, будет рассказывать о том, как он создаёт игру на UWP. Под катом — первая часть, с описанием идеи проекта и ответом на простой вопрос: «Что нужно заложить с самого начала?» Не забудьте оставить комментарии, вы можете повлиять на ход разработки.
Прежде чем запустить данный
эксперимент, мы проводили опрос на эту тему. С его результатами можно ознакомиться здесь.
Передаю слово автору.
Интро
Начнем, пожалуй, со знакомства. Меня зовут Плотников Алексей и в этом блоге ранее упоминался как «Активный участник сообщества». Это самое емкое представление, так как я не являюсь сотрудником компании и, даже, не являюсь профессиональным разработчиком. Я — программист-самоучка, использующий в качестве языка разработки VB.NET, автор нескольких статей, пары интересных проектов и сотен полезных ответов на форумах MSDN. Однако несмотря на то, что разработка для меня лишь хобби, я обладаю обширным опытом, которым и планирую с вами поделится в данном цикле.
К слову, о контенте. Ориентирован он будет по большей части на новичков в UWP, но опытных в разработке в целом. Этот цикл идеально подойдет для разработчиков WPF и разработчиков других платформ, решивших попробовать себя в разработке UWP/.Net. А с учетом постоянных отсылок к документации и гайдам от MS, цикл, возможно, будет по силам и новичкам, желающим познакомиться с разработкой на .Net, начиная с UWP, и не ленящихся читать не только пошаговые руководства, но и сухую документацию. Впрочем, отдельные темы цикла могут оказаться полезными и для бывалых разработчиков, так как в них планируется затронуть некоторые лайфхаки и даже обход неудачных решений в документации, которые вы почему-то слепо выполняли.
И прежде чем мы приступим к знакомству с будущим проектом, на основе которого будет строиться цикл, хочется уделить пару строк (а может, и пару абзацев) рассуждениям о том, зачем это вообще нужно. Будем честны, разрабатывать для магазина Windows как минимум не модно. Классная идея, реализованная в виде мобильного приложения, принесет кучу денег на iOS и миллионы пользователей на Android.
Поводов изучить разработку на UWP с помощью .Net как минимум несколько. Во-первых, если вы — разработчик WPF, то миграция для вас пройдет максимально гладко и безболезненно. Во-вторых, какими бы классными не были прочие мобильные платформы, они по-прежнему остаются «мобильными»!
Universal Windows Platform в самом своем названии говорит о заложенных в данную платформу возможностях и широте потенциальных устройств, на которых сможет работать ваше приложение. Конечно, вы будете правы, если скажете, что сейчас Windows 10 используется преимущественно на десктопах, но стремительно меняющийся рынок может в два счета изменить расклад сил в пользу Windows 10 как самой популярной ОС на всех возможных устройствах. Так почему же нам не воспользоваться такими «мобильными» удобствами, как автоматизированное распространение, удобная публикация и обновление, на всем спектре устройств, а не только на мобильных?
Наконец, пришло время рассказать о проекте, на основе которого будет построен данный цикл.
Идея проекта возникла на волне популярности криптовалют и представляет из себя довольно простую игру. Называться игра будет «Крипто ферма» и, как вы, вероятно, догадались, игровой процесс будет построен на майнинге криптовалют. Более подробное описание игрового процесса будет рассматриваться по ходу цикла в тех статьях, где это будет необходимо. Важно понимать, что этот цикл о разработке на UWP, а не о данной игре, поэтому она будет лишь опорой для статей, которые я постараюсь сделать максимально абстрактными и применимыми к разным, а не только игровым, сценариям.
В ходе разработки и написания статей я планирую затронуть следующие темы:
- Создание проекта. Что нужно заложить с самого начала, чтобы получить максимальное удобство и расширяемость в будущем.
- Стартовый экран. Более живой и более интересный снаружи, эффективный внутри.
- Многопользовательские элементы. Идентификация пользователя. Как? Где хранить данные? Сколько это стоит?
- Структура приложения. Сколько нужно страниц. Переходы между ними.
- Дизайн и стилизация. Несколько статей посвященных внешнему виду приложения. От подготовки графических материалов, до стилизации элементов управления.
- Создание собственных элементов управления. Когда имеющегося недостаточно и нужно создавать свое.
- Фоновые события. Живые плитки и уведомления. Важные элементы взаимодействия с пользователем, которые должны присутствовать в каждом UWP приложении.
- Монетизация. Виды заработка. Какой способ выбрать и как эффективно интегрировать.
- Отладка на разных устройствах, разрешениях и соотношениях сторон.
- Сборка и публикация приложения.
- Поддержка после публикации. Работа по достижению высоких оценок и положительных отзывов.
Это далеко не полный перечень тем, которые планируется затронуть и, вероятно, многие возникнут благодаря вашим отзывам к статьям по мере их появления. Также несколько статей я планирую посвятить возникающим сложностям и допущенным ошибкам.
Но, пожалуй, хватит предисловий и пора приступать к разработке.
Создание проекта. Что нужно заложить с самого начала?
Если, прочитав заголовок, вы вдруг решили пропустить эту статью, подумав, что уж с созданием проекта UWP трудностей у вас не вызовет, вы будете правы лишь отчасти.
С одной стороны, допустить критические ошибки на столь простом этапе очень сложно. Но с другой — можно существенно облегчить себе жизнь, сделав все правильно с самого начала. Кроме того, в конце статьи я поделюсь личными предпочтениями в вопросах создания проекта, которые могут оказаться полезными бывалым разработчикам.
Создавать свой проект я буду в русскоязычной Visual Studio Professional 2017. Эта редакция является платной, либо предоставляется по подписке (как в моем случае), но для полноценной работы над UWP приложением она необязательна. Вам будет достаточно скачать бесплатную Visual Studio Community на официальном сайте Visual Studio.
По какой-то причине многие начинающие разработчики считают, что приложения, созданные в Community, запрещено публиковать на платной основе или еще каким-то способом, зарабатывать на разработке в данной редакции, но это не соответствует действительности. Пока вы не станете крупной компанией, основным источником миллионных доходов которой является разработка приложений, вы можете смело использовать Community, не боясь претензий со стороны Microsoft.
Итак, запускаем Visual Studio (далее VS) и, если вы ничего не меняли, сразу же видим стартовый экран. Этот экран содержит быстрый доступ к открытию и созданию проектов, а также последние новости для разработчиков. Так как этот экран меняется от версии к версии, я не буду ссылаться на его пункты, а по старинке пойду в меню «Файл > Создать проект…». В открывшемся окне виден отсортированный по типам и языкам программирования список шаблонов всех проектов, которые мы можем создать в данной версии VS.
Нам нужен раздел «Универсальные приложения Windows» и самый верхний шаблон «Пустое приложение (универсальное приложение для Windows)». К слову, если вы разрабатывали приложения для Windows 8/8.1, которые обозначались сокращением WinRT, то помните, что список шаблонов не ограничивался пустым приложением. Присутствовали также дополнительные шаблоны многостраничных приложений, которые подразумевали быстрое создание проекта на основе ваших данных.
Должен признать, что наличие этих «быстрых» шаблонов, по моему мнению, было ошибкой, которая привела к созданию тысяч малопривлекательных и однотипных приложений, заполонивших магазин Windows и это, слегка подпортило его имидж. Хотя с другой стороны, тогда магазин Windows только появился и ему критически не хватало наполнения.
Выбрав нужный шаблон проекта, вам необходимо выбрать его имя, расположение и снова имя, но на этот раз для решения. Решением в VS называется объединение нескольких проектов воедино, о чем я, к слову, отдельно расскажу в одной из следующих статье. В принципе на этапе первоначального создания проекта, его имя и имя решения можно оставить одинаковым. Отдельно стоит сказать об имени проекта на кириллице. В принципе вам никто не запрещает использовать русский текст в названии и даже использовать пробелы, но старые программистские шрамы начинают сильно чесаться от таких действий. Дав имя проекту на латинице и без пробелов, вы точно избавите себя от каких-либо потенциальных проблем с хранением и синхронизацией проекта, поэтому я рекомендую вам поступить именно так.
Также осталось решить, что делать с двумя галочками в правом нижнем углу окна создания проекта. Первая («Создать каталог для решения») поможет вам, если вы выбираете в качестве целевого расположения для проекта некую общую папку, а не подготовленную заранее. Очень удобная функция и совершенно не зря она отмечена по умолчанию. Второй пункт дополнительных параметров, именуемый «Добавить в систему управления версиями», мы оставим неотмеченным, и далее в статье я объясню почему.
Итак, вожделенная кнопка «ОК» нажата и, казалось бы, можно приступать к изучению структуры проекта, но нет. Перед нами еще одно диалоговое окно, предлагающее выбрать целевую и минимальную версии для вашего приложения UWP.
Если вы — разработчик WPF или прочих проектов в VS и уже начали зевать от предыдущих абзацев, то пора просыпаться, так как перед нами стоит очень важный выбор, который существенно влияет на количество потенциальных пользователей, а также трудозатраты при разработке. Должен признаться, я сильно удивлен тому, что в большинстве руководств нам предлагают просто нажать «ОК», ничего не меняя, совершенно не разбираясь в теме. Я же, не столько для читателей, сколько в свое время, для себя, внимательно изучил вопрос и сейчас делюсь своими размышлениями с вами.
Самое очевидное, что приходит в голову, при попытке разобраться в вопросе, это нажать на ссылку в данном окне, которая приведет нас на страницу документации с описанием этих параметров. Довольно полезная страница, которая, к сожалению, практически не отвечает на вопрос «А зачем нам вообще вгонять себя в какие-то рамки?» и не слишком облегчает осознанный выбор этих самых рамок.
Начну с ответа на вопрос, что стало причиной появления этих рамок. Все дело в маркетологах Microsoft, которые сказали, что компании нужно выпустить ОС с одним названием, а потом дополнять и улучшать ее, приписывая лишь номера версии. А номера эти должны отображаться лишь в сведениях о системе и особо не выпячиваться. В итоге все, что знает рядовой пользователь, это то, что на его компьютере (или ином поддерживаемом устройстве) установлена Windows 10, которая периодически зачем-то обновляется. Это очень умное решение, так как даже самая первая и почти забытая сборка Windows 10 все еще остается Windows 10 и работает на пользу общей статистике. И нам, как разработчикам, это тоже крайне выгодно, ведь со временем армия потенциальных пользователей нашего приложения будет только расти.
К сожалению, плата за такой подход заключается в том, что нам нужно тщательно контролировать использование новых функций в приложении, чтобы обеспечить его максимальную совместимость на большем спектре сборок Windows 10, ведь, как вы понимаете, функции, доступные только в сборке 16299, не будут работать у пользователя сборки 10240.
Но я так и не ответил, зачем нам нужен диапазон версий. Выбор минимальной и целевой версии обусловлен возможностью сделать наше приложение адаптивным к разным сборкам Windows 10 с минимальными жертвами. Нам не нужно жертвовать функционалом в угоду максимальному охвату, либо, напротив, охватом — в угоду новым функциям. Нам предлагают выбрать, насколько мы готовы пожертвовать каждым отдельным пунктом, а жертвовать в любом случае придется. Даже если выбрать максимальный диапазон — от самой ранней до самой поздней версии — и получить максимальный охват и полный спектр функций, нам придется много времени уделять адаптации кода, что существенно растянет и усложнит процесс разработки.
На заметку! Адаптивный код — это специальные условия в программе, определяющие, доступна ли нам та или иная функция. Такое условие позволяет, с одной стороны, использовать новые функции там, где они доступны, а с другой — позволить приложению без ошибок работать в тех версиях Windows, где этих функций еще нет. Примеры адаптивного кода будут появляться в дальнейших статьях этого цикла.
Итак, что же в итоге выбрать в качестве целевой и минимальной версии? Для целевой версии я рекомендую выбрать максимально возможное значение. Важно понимать, что с каждым обновлением Windows 10, не только появляются новые функции, но и улучшаются старые. Тогда как приложения, нацеленные на ранние сборки, будут использовать именно API той сборки, на которую нацелены. Поэтому, выбирая в качестве целевой самую последнюю версию, мы получаем не только новые функции, но и более качественные и осовремененные старые. Зная это, мы также можем решить, когда нужно выбирать более раннюю сборку в качестве целевой. А нужно это только в том случае, если механизмы, которые мы планируем использовать, перестали работать в последних сборках.
Например, это может произойти в случае переноса приложения с другой платформы или просто при использовании «костылей», опирающихся на устаревшие особенности API. На всякий случай добавлю, что целевая версия не должна восприниматься вами как максимальная. Само собой, ваше приложение продолжит исправно работать в следующих версиях Windows, но при этом обращаться будет к той версии API, на которую оно нацелено.
Перейдем к минимальной версии. Ее я рекомендую ставить равной той версии Windows, что на данный момент является статистически самой популярной версией. Так мы получим максимум пользователей, лишив себя лишних хлопот по проверке совместимости кода для той или иной версии. Естественно, если уверены, что ваш пользователь застрял на более ранней сборке, то вы должны выбрать в качестве минимальной ее. А вот выбирать для целевой и минимальной версии одинаковую — идея не самая удачная. Обновление Windows проходит мало того что не быстро, так и в итоге охватывает не все старые компьютеры, поэтому загонять приложение в рамки единственной сборки — решение ничем неоправданное.
Наконец, все прелюдии пройдены и можно приступить к изучению содержимого созданного проекта. Изучить его файлы и папки можно в окне «Обозреватель решений».
Давайте разберемся:
- Папка Assets. В данной папке по задумке вы должны хранить ресурсы вашего приложения, такие как, например, картинки. По умолчанию, данная папка содержит обязательные картинки-заплатки, выступающие в роли логотипа, и о них я еще поговорю подробнее в одной из статей данного цикла. К слову, вам не обязательно хранить эти и другие ресурсы в этой папке. Как, собственно, у вас нет ограничений по количеству папок и подпапок с ресурсами.
- Файл App.xaml и связанный с ним App.xaml.cs/vb выполняют практически ту же функцию, что и Application в WPF. В App.xaml вы можете прописать ресурсы приложения, а также указать предпочтительную тему (светлая или темная) в свойстве RequestedTheme. В файле кода вы можете управлять жизненным циклом приложения. Тема жизненного цикла приложений UWP довольно обширна и подробнее о том, что это такое, можно почитать здесь. Также файл App.xaml.cs/vb можно использовать для размещения глобальных переменных приложения, но это уже зависит от шаблона программирования, который вы решите использовать. Например, для UWP больше походит MVVM, который я использовать не буду, но опытным разработчикам крайне рекомендую.
- Файл App1_TemporaryKey.pfx является временным сертификатом, подписывающим ваше приложение, и нужным, чтобы оно могло запускаться на устройстве. Больше знать нам о нем ничего не нужно. Работать с ним нам не придется.
- Файл MainPage.xaml и связанный с ним MainPage.xaml.cs/vb это основная страница приложения. Отличие от приложений WPF заключается в том, что здесь мы работаем не с окнами, а со страницами. Окно у приложения UWP чаще всего одно, и в нем загружаются страницы приложения, между которыми вы переключаетесь, подобно переходу по страницам сайта в браузере. Подробнее о страницах и навигации в UWP я расскажу в одной из ближайших статей.
- И последний, автоматически созданный фал проекта, — это файл Package.appxmanifest. Это, как вы поняли, манифест проекта, который содержит основные объявления. Этот файл имеет удобный редактор, который вызывается двойным щелчком мыши. В данном редакторе можно выставить важные параметры приложения, задать расположения логотипов, задать возможности приложения и объявить контракты, которые оно будет использовать. По ходу этого цикла я регулярно буду обращаться к разным настройкам манифеста и более подробно их рассматривать. Также замечу, что в документации часто встречается указание, в каких параметрах манифеста какие ключи должны быть отмечены. В этих случаях документация ссылается на текстовую версию манифеста. Открыть ее можно, если нажать правой кнопкой мыши на файл манифеста и выбрать пункт «Открыть с помощью…» и далее — «Редактор (текстовый) XML».
Вновь созданный проект полностью работоспособен, и вы можете запустить его, нажав «F5». После запуска приложения оно появится в списке установленных приложений в меню «Пуск», откуда его также можно запускать.
И последнее, что я хочу упомянуть, это добавление проекта в систему управления версий. Существует несколько популярных систем управления версий (далее Git), но для начинающего разработчика лучше всего подойдет Team Services. Это бесплатный инструмент для публикации приложения в удаленном хранилище, а также для командной разработки. Даже если вам не понадобятся такие мощные возможности, как совместная работа над проектом, создание веток кода и отдельных билдов, то возможность синхронизации и резервного копирования недооценить очень сложно.
Итак, опубликуем вновь созданное приложение в Team Services. Для этого в правом нижнем углу VS необходимо нажать на надпись «Добавить в систему управления версиями > Git». В открывшемся окне «Team Explorer — Синхронизация» нажимаем на «Опубликовать репозиторий Git».
Для того чтобы последующие манипуляции прошли гладко, вы должны быть зарегистрированы на сайте Team Services и иметь собственный домен в данной системе. Делается это довольно просто. В главном окне синхронизации нажмите ссылку «Learn more», которая отправит вас на сайт Team Services. На данном сайте выбираем «Начать работу бесплатно» и следуем инструкциям. После создания вашего домена он станет вашим хабом, в котором можно отслеживать проекты, просматривать историю изменений, назначать команду и многое другое, но сейчас мы просто закрываем сайт и возвращаемся в VS.
После подготовительных работ выбираем «Опубликовать репозиторий Git», и теперь останется лишь выбрать ваш аккаунт, имя домена и опубликовать проект. Если все прошло хорошо, то окно синхронизации отобразит вам список действий, которые вы можете осуществлять непосредственно из VS. Нас больше всего интересуют пункты «Изменения» и «Синхронизация».
По факту мы все еще не загрузили весь проект в Git. Сначала нам нужно зафиксировать все внесенные в проект изменения, к которым относится и создание проекта. Для этого переходим в раздел «Изменения», заполняем описание внесенных изменений, а затем нажимаем на «Зафиксировать все». Team Services позволяет отслеживать историю вносимых в проект изменений, и — если это необходимо — вернуться к ранней точке, либо просто посмотреть, что и когда мы добавляли, поэтому выбирайте наглядное описание, которое в будущем поможет быстро найти нужную точку в процессе разработки. Например, сейчас мы можем указать в описании фиксации: «Создание проекта».
После того, как все изменения зафиксированы, их нужно синхронизировать с Git. Для этого переходим в раздел «Синхронизация» и выбираем соответствующую ссылку. Синхронизация работает в обе стороны, и, если вы зафиксировали и выгрузили изменения на другом компьютере, то в момент синхронизации они загрузятся на этом. Также это удобно, если вы потеряли файлы проекта, которые ранее выгружали в Git. Просто синхронизируйте проект без локальной фиксации, и они вернутся.
На этом тему создания проекта UWP можно считать закрытой, однако, так как этот цикл статей пишется параллельно с разработкой живого проекта, я решил дополнить эту статью личным рекомендациями по стартовой настройке проекта, которые я выработал в процессе работы с UWP.
Информация ниже направлена на разработчиков WPF, является личным опытом и не должна восприниматься как эталон.
На самом деле, я не зря рекомендовал проигнорировать галочку «Добавить в систему управления версиями» в самом начале создания проекта, хотя затем описал этот процесс, ничего не меняя в проекте. Сам я выполняю публикацию только после добавления в проект некоторых, основанных на опыте, дополнительных элементов.
Во-первых, в проект добавляется папка ConvertersAndStyle, в которую я помещаю файлы с конвертерами и словарями ресурсов:
- Файл Converters.cs/vb — это обычный файл «класс», в котором потом помещаются конвертеры, используемые в приложении.
- Файл ConverterDictionary.xaml — это файл типа «Словарь ресурсов», в котором мы будем записывать ссылки на наши конвертеры. Так как большая часть конвертеров будет использоваться во всем приложении, то и определять их лучше в одном файле, а не в ресурсах каждой отдельной страницы.
- Файл ApplicationStyle.xaml также является словарем ресурсов, и в нем мы будем определять все ресурсы, связанные со стилем приложения.
Как вы наверняка поняли, имена папок и файлов я выбрал исходя из их функций. Вы можете дать им любые удобные для вас имена.
После добавления файлов ресурсов нам нужно добавить указание на них в файле App.xaml:
Теперь мы можем обращаться к ресурсам из этих файлов в любой точке приложения.
Второе, что я хочу отметить, это выделение отдельной папки под изображения. Так как пути к картинкам я часто пишу вручную, то использую более простые и интуитивные имена папок и файлов. Основная папка для хранения изображений в моих проектах носит имя Images, а папку Assets я использую только для логотипов — тех, что показываются на плитке, в списке приложений и в магазине.
Далее стоит подготовить наше приложение для локализации. Для этого создаем как минимум две папки. Первая для родного языка (в нашем случае русский) и должна называться «ru», а вторая для международного — «en». В данном случае имена папок играют важную роль и называть их по-другому не нужно. Также можно добавить папки для дополнительных языков, если вы планируете локализовать приложение на несколько языков. Полный список доступных имен папок для разных языков можно посмотреть здесь.
В каждую из папок нужно добавить файл типа «Файл ресурсов (.resw)», оставив его имя по умолчанию. Более подробно о локализации приложения и о том, что потом делать с этими файлами, я расскажу в отдельной статье цикла.
И вот после всех этих манипуляций можно публиковать приложение в систему управления версий, после чего проект полностью готов к непосредственной работе.
Следующая статья цикла будет посвящена созданию собственного стартового экрана, и, надеюсь, привнесет что-то новое на фоне уже имеющихся статей на эту тему.