Разработка игры для Windows Phone 7.5-8.1

    Некоторое время ранее я писал о разработке судоку для Windows Phone. По некоторым данным пользователей на Windows Phone 7.1 не так уж и мало, чтобы ими пренебрегать. Также в статье будет рассмотрен момент публикации в обновленный магазин Windows Phone.

    image



    По данным статистики уже работающего приложения за последний месяц:

    Статистика Windows phone 7

    Видно, что 7-я версия занимает 30% от общего числа установок. Идея — разработать для обучения приложение, которое будет доступно и для 7.1+ версии. 
    Решено сделать игру Точки. 
    Вы начинаете игру с одной точки. На каждом уровне выбираете новую точку. Если выберете старую точку — проиграете. 

    Полученная за день статистика разработанного и выложенного в магазин приложения:
    Статистика распределения Windows Phone

    Разработка


    Важно отметить, что разработка приложений для Windows Phone 7 происходит исключительно в Visual Studio 2012. Верстка макетов в Blend 2012. При открытии проекта в 13 версии студии происходит принудительная конверстация проекта в новую версию и нет возможности публиковать приложение для старых версий.
    Всего в игре 3 экрана: Стартовый (он же экран между уровнями), экран уровня и экран конца игры. В этом приложении в отличии от Судоку добавлен рейтинг игроков (количество точек). Рейтин реализован в виде API (без какой-либо серьезной защиты). Кроме того, что хочется посоревноваться в офисе — хочется также узнать кто сильнее в мире. Понятное дело что фотоаппарат решает, но без него интереснее. Правда!

    Async


    В Windows Phone 7 нет встроенной поддержки async await. Также нет некоторых элементов управления, упрощающих разработку. Вот мой список используемых packages из nuget.

    Список Packages
    <packages>
      <package id="Coding4Fun.Toolkit.Controls" version="2.0.7" targetFramework="wp71" />
      <package id="GoogleAnalyticsSDK" version="1.2.01" targetFramework="wp71" />
      <package id="Microsoft.Bcl" version="1.1.7" targetFramework="wp71" />
      <package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="wp71" />
      <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="wp71" />
      <package id="Microsoft.Net.Http" version="2.1.10" targetFramework="wp71" />
      <package id="Newtonsoft.Json" version="5.0.7" targetFramework="wp71" />
      <package id="WPtoolkit" version="4.2013.08.16" targetFramework="wp71" />
    </packages>
    


    Для взаимодействия с API был разработан generic класс (httpclient), который кочует из проекта в проект. Примерный код класса представлен ниже.

    Http Client (async await)
    using (HttpClientHandler handler = new HttpClientHandler())
    {
    	using (HttpClient httpClient = new HttpClient(handler))
    	{
    		using (HttpRequestMessage message = new HttpRequestMessage())
    		{
    			message.RequestUri = new Uri(url);
    			message.Method = postData == null ? HttpMethod.Get : HttpMethod.Post;
    
    			if (postData != null)
    			{				
    				message.Content = new StringContent(JsonConvert.SerializeObject(postData));
    				message.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
    			}
    
    			HttpResponseMessage response = await httpClient.SendAsync(message).ConfigureAwait(false);
    			string data = await response.Content.ReadAsStringAsync();
    			return data;
    		}
    	}
    }
    


    Рисование точек происходит в объекте Canvas. Каждая точка это Button со стилем. Генерация точек и цветов абсолютно случайная (иногда попадается 4-5 точек одного цвета очень близко, приходится ориентироваться по относительному положених их друг друга. Код генерации показан ниже. Кроме того, учитываются пересечения точек. Генерация происходит до тех пор, пока не найдется такое местое, где не будет пересечения с другими точками (или кончится цикл, тогда будет в случайном месте)

    Генерация точек
    DotInfo dot = new DotInfo();
    dot.Color = Colors[Rand.Next(Colors.Count)];
    
    int testX = 0, testY = 0;
    bool testOk = true;
    
    for (int i = 0; i < 10000; i++)
    {
    	testX = Rand.Next(Width - ButtonSize);
    	testY = Rand.Next(Heigth - ButtonSize);
    
    	testOk = true;
    
    	foreach (DotInfo dotInfo in _dots)
    	{
    		Rectangle intersect =
    			Rectangle.Intersect(new Rectangle(dotInfo.X, dotInfo.Y, ButtonSize, ButtonSize),
    				new Rectangle(testX, testY, ButtonSize, ButtonSize));
    
    		if (intersect != Rectangle.Empty)
    			testOk = false;
    	}
    
    	if (testOk)
    	{
    		dot.X = testX;
    		dot.Y = testY;
    		break;
    	}
    }
    
    if (!testOk)
    {
    	dot.X = Rand.Next(Width - ButtonSize);
    	dot.Y = Rand.Next(Heigth - ButtonSize);
    }
    


    Имя игрока запрашивается элементом управления от издателя Coding4Fun. Кстати очень интересные контролы, советую посмотреть. (Coding4Fun Toolkit)

    Диалоговое окно ввода
    InputPrompt input = new InputPrompt();
    input.Completed += UserNameInputOK;
    input.Title = "Введите имя";
    input.Value = UserSettings.Value.UserName;
    if (string.IsNullOrEmpty(input.Value))
    	input.Value = "Игрок " + randName.Next(Int32.MaxValue / 2);
    
    
    input.Show();
    


    Взаимодействие с настройками пользователей и сохраняемыми данными реализовано по рекомендации «Introduction and best practices for IsolatedStorageSettings» от Nokia. Решение оказалось интересным и очень удобным. http://developer.nokia.com/community/wiki/Introduction_and_best_practices_for_IsolatedStorageSettings

    Публикация в обновленный магазин


    Практически сразу после конференции Build обновился магазин приложений (как на клиенсткой части, так и для разработчиков)

    Магазин Windows Phone

    Добавился пункт об изменениях в новой версии (чтобы не изменять описание самого приложение) и не захламлять его.
    описание приложения
    Добавилось резервирование имени приложения для Windows Phone приложений (в довесок в Windows Store)
    резервирование имени
    Приложения, которые используют одно имя для обоих платформ появился значек:

    имя в приложения

    В общей сложности на написание этого приложения + небольшой серверной части ушло 20 часов. Стоит заметить, что публикация приложения в магазин стала космически быстрой (всего 30 минут). Дополнительные ошибки получил при интеграции async-await в приложение Windows Phone 7.5. Падала странная ошибка FileNotFound. Думаю, что решилось недавним обновление BCL библиотек Microsoft.

    P.S. мой рекорд 24 точки, а у вас? (можно в имя добавить Habr, чтобы узнать у кого память лучше на хабре)

    Рекорд точек

    Буду рад комментариям, предложениям и хорошим оценкам в магазине.

    • +18
    • 13,8k
    • 6
    Поделиться публикацией

    Комментарии 6

      0
      Не удобно, что бэк в таблице рейтов закрывает приложение, а не (ожидаемо) возвращает на предыдущий экран.
        0
        Согласен. Предыдущий экран — экран уровня, где произошел фейл. Думаю можно как-то обрабатывать событие, но еще не искал как.
          0
          Ещё было бы удобно нумерацию в топе (: чтобы видеть на каком ты месте.
          Например, «вхожу в 10ку» — уже мотивирует, а «какой-то там» — не очень.
            0
            А это — пожалуйста. Готово! Проверяйте, и без перевыпуска приложения :)
            Правда все равно кое-что отвалилось… но это поправим =)
        0
        Вы использовали систему для метрик или вручную собирали версии ОС?
          0
          Статистику собираю с помощью Google Analytics (встроить ее в приложение довольно просто). Опубликовал первые данные за неделю работы.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое