Опубликован: 14.08.2012 | Уровень: специалист | Доступ: платный
Самостоятельная работа 28:

Совместное использование Silverlight и XNA

Аннотация: Эта лабораторная работа посвящена разработке приложений на основе шаблона Приложение Silverlight и XNA для Windows Phone.

Цель работы: Научиться разрабатывать приложения с использованием шаблона Приложение Silverlight и XNA для Windows Phone

35.1. Особенности проекта Приложение Silverlight и XNA для Windows Phone

В некоторых из предыдущих проектов мы использовали отдельные библиотеки и объекты XNA в Silverlight-приложениях. Начиная с Windows Phone OS 7.1. при разработке приложений можно в полной мере пользоваться возможностями Silverlight и XNA в одном приложении. Например, можно создать сложный пользовательский интерфейс на Silverlight, и, в то же время, организовать вывод графики с помощью средств XNA. Фактически, такое приложение позволяет взять всё лучшее от обеих технологий.

Рассмотрим особенности таких приложений. Создадим новый проект, в окне создания проекта выберем шаблон Приложение Silverlight и XNA для Windows Phone, рис. 35.1.

Создание проекта

увеличить изображение
Рис. 35.1. Создание проекта

Посмотрим на Обозреватель решений этого проекта, рис. 35.2

Обозреватель решений для проекта P28_1

Рис. 35.2. Обозреватель решений для проекта P28_1

Если рассмотреть это решение в первом приближении, то окажется, что мы имеем Silverlight-проект, в котором есть механизмы для визуализации средствами XNA и страница GamePage.xaml, код которой (GamePage.xaml.cs) представляет собой реализацию игрового цикла XNA. Весь вывод данных на этой странице формируется средствами XNA.

Рассмотрим решение подробнее. Оно состоит из трёх проектов:

  1. Основной проект приложения (P28_1). Это проект приложения, здесь содержатся страницы приложения. Причём, страница MainPage – это обычная Silverlight-страница, которая отображается после запуска приложения, на ней, по умолчанию, расположена кнопка для вызова страницы GamePage.
  2. Проект библиотеки XNA (P28_1Lib). Этот проект напоминает проект XNA, разработкой которых мы занимались ранее в этом курсе. Он имеет ссылку на проект контента. Этот проект представляет собой нечто вроде моста между Silverlight-приложением и хранилищем контента.
  3. Проект контента XNA (P281Lib_Content). Традиционный для XNA-приложений проект, содержащий контент – изображения, звуки, трехмерные модели.

Рассмотрим файлы, которые входят в решение. Начнём с файла App.xaml, листинге 35.1.

<Application 
    x:Class="P28_1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
     xmlns:xna="clr-namespace:Microsoft.Xna.Framework;assembly=Microsoft.Xna.Framework.Interop">

    <!--Ресурсы приложения-->
    <Application.Resources>
    </Application.Resources>

    <Application.ApplicationLifetimeObjects>
        <!--Обязательный объект, обрабатывающий события времени жизни приложения-->
        <shell:PhoneApplicationService 
            Launching="Application_Launching" Closing="Application_Closing" 
            Activated="Application_Activated" Deactivated="Application_Deactivated"/>


    <!--SharedGraphicsDeviceManager используется для отображения с помощью графических API XNA-->
    <xna:SharedGraphicsDeviceManager />
    </Application.ApplicationLifetimeObjects>

</Application>
Листинг 35.1. Файл App.xaml

Этот файл, как и в случае с обычным Silverlight-приложением, определяет обработчики события, касающиеся жизненного цикла приложения, и, кроме того, определяет xna:SharedGraphicsDeviceManagerобъект, который используется для вывода XNA-графики.

В листинге 35.2 приведен файл App.xaml.cs,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace P28_1
{
    public partial class App : Application
    {
        /// <summary>
        /// Обеспечивает быстрый доступ к корневому кадру приложения телефона.
        /// </summary>
        /// <returns>Корневой кадр приложения телефона.</returns>
        public PhoneApplicationFrame RootFrame { get; private set; }

        /// <summary>
        /// Предоставляет приложению доступ к ContentManager.
        /// </summary>
        public ContentManager Content { get; private set; }

        /// <summary>
        /// Предоставляет доступ к GameTimer, настроенному для передачи данных в FrameworkDispatcher.
        /// </summary>
        public GameTimer FrameworkDispatcherTimer { get; private set; }

        /// <summary>
        /// Предоставляет доступ к AppServiceProvider для приложения.
        /// </summary>
        public AppServiceProvider Services { get; private set; }

        /// <summary>
        /// Конструктор объекта приложения.
        /// </summary>
        public App()
        {
            // Глобальный обработчик неперехваченных исключений. 
            UnhandledException += Application_UnhandledException;

            // Стандартная инициализация Silverlight
            InitializeComponent();

            // Инициализация телефона
            InitializePhoneApplication();

            // Инициализация XNA
            InitializeXnaApplication();

            // Отображение сведений о профиле графики во время отладки.
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // Отображение текущих счетчиков частоты смены кадров.
                Application.Current.Host.Settings.EnableFrameRateCounter = true;

                // Отображение областей приложения, перерисовываемых в каждом кадре.
                //Application.Current.Host.Settings.EnableRedrawRegions = true;

                // Включение режима визуализации анализа нерабочего кода 
                // для отображения областей страницы, переданных в GPU, с цветным наложением.
                //Application.Current.Host.Settings.EnableCacheVisualization = true;

                // Отключите обнаружение простоя приложения, установив для свойства UserIdleDetectionMode
                // объекта PhoneApplicationService приложения значение Disabled.
                // Внимание! Используйте только в режиме отладки. Приложение, в котором отключено обнаружение 
                 бездействия пользователя, будет продолжать работать
                // и потреблять энергию батареи, когда телефон не будет использоваться.
                PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
            }
        }

        // Код для выполнения при запуске приложения (например, из меню "Пуск")
        // Этот код не будет выполняться при повторной активации приложения
        private void Application_Launching(object sender, LaunchingEventArgs e)
        {
        }

        // Код для выполнения при активации приложения (переводится в основной режим)
        // Этот код не будет выполняться при первом запуске приложения
        private void Application_Activated(object sender, ActivatedEventArgs e)
        {
        }

        // Код для выполнения при деактивации приложения (отправляется в фоновый режим)
        // Этот код не будет выполняться при закрытии приложения
        private void Application_Deactivated(object sender, DeactivatedEventArgs e)
        {
        }

        // Код для выполнения при закрытии приложения (например, при нажатии пользователем кнопки "Назад")
        // Этот код не будет выполняться при деактивации приложения
        private void Application_Closing(object sender, ClosingEventArgs e)
        {
        }

        // Код для выполнения в случае ошибки навигации
        private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // Ошибка навигации; перейти в отладчик
                System.Diagnostics.Debugger.Break();
            }
        }

        // Код для выполнения на необработанных исключениях
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // Произошло необработанное исключение; перейти в отладчик
                System.Diagnostics.Debugger.Break();
            }
        }

        #region Инициализация приложения телефона

        // Избегайте двойной инициализации
        private bool phoneApplicationInitialized = false;

        // Не добавляйте в этот метод дополнительный код
        private void InitializePhoneApplication()
        {
            if (phoneApplicationInitialized)
                return;

            // Создайте кадр, но не задавайте для него значение RootVisual; это позволит
            // экрану-заставке оставаться активным, пока приложение не будет готово для визуализации.
            RootFrame = new PhoneApplicationFrame();
            RootFrame.Navigated += CompleteInitializePhoneApplication;

            // Обработка сбоев навигации
            RootFrame.NavigationFailed += RootFrame_NavigationFailed;

            // Убедитесь, что инициализация не выполняется повторно
            phoneApplicationInitialized = true;
        }

        // Не добавляйте в этот метод дополнительный код
        private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
        {
            // Задайте корневой визуальный элемент для визуализации приложения
            if (RootVisual != RootFrame)
                RootVisual = RootFrame;

            // Удалите этот обработчик, т.к. он больше не нужен
            RootFrame.Navigated -= CompleteInitializePhoneApplication;
        }

        #endregion

        #region Инициализация приложения XNA

        // Выполняет инициализацию типов XNA, необходимых для приложения.
        private void InitializeXnaApplication()
        {
            // Создание поставщика услуг
            Services = new AppServiceProvider();

            // Добавить SharedGraphicsDeviceManager к службам в качестве IGraphicsDeviceService для приложения
            foreach (object obj in ApplicationLifetimeObjects)
            {
                if (obj is IGraphicsDeviceService)
                    Services.AddService(typeof(IGraphicsDeviceService), obj);
            }

            // Создайте ContentManager для загрузки в приложение предварительно скомпилированных ресурсов
            Content = new ContentManager(Services, "Content");

            // Создайте GameTimer для получения XNA FrameworkDispatcher
            FrameworkDispatcherTimer = new GameTimer();
            FrameworkDispatcherTimer.FrameAction += FrameworkDispatcherFrameAction;
            FrameworkDispatcherTimer.Start();
        }

        // Обработчик событий передает FrameworkDispatcher во все кадры.
        // FrameworkDispatcher требуется для большинства событий XNA и
        // некоторых функций, таких как воспроизведение SoundEffect.
        private void FrameworkDispatcherFrameAction(object sender, EventArgs e)
        {
            FrameworkDispatcher.Update();
        }

        #endregion
    }
}
Листинг 35.2. Файл App.xaml.cs

Это всё тот же App.xaml.cs, которым мы пользовались ранее, однако, здесь производится инициализация механизмов XNA, создается ConetntManager для работы с XNA-контентом, создаётся таймер уровня приложения для FrameworkDispatcher.Update().

Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто
Сашечка Огнев
Сашечка Огнев
Россия, Красноярский край
Андрей Корягин
Андрей Корягин
Россия, Пенза, Вазерская средняя школа, 2001