Невозможно пройти тесты, в окне с вопросами пусто |
Совместное использование Silverlight и XNA
Страница MainPage.xaml – это обычная стартовая страница Silverlight-приложения, рис. 35.3.
Здесь располагается кнопка "Изменить на страницу игры". Правильнее будет подписать её как "Перейти на страницу игры", так как именно эту функцию она и выполняет. В листинге 35.3 приведен её код.
<phone:PhoneApplicationPage x:Class="P28_1.MainPage" 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:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="False"> <!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel содержит имя приложения и заголовок страницы--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="МОЕ ПРИЛОЖЕНИЕ" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="имя страницы" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel — поместите здесь дополнительное содержимое--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <!--Создание одной кнопки для перехода ко второй странице, визуализация которой выполнена XNA Framework--> <Button Height="100" Content="Изменить на страницу игры" Click="Button_Click" /> </Grid> </Grid> <!--Пример кода, иллюстрирующий использование ApplicationBar--> <!--<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"> <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Кнопка 1"/> <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Кнопка 2"/> <shell:ApplicationBar.MenuItems> <shell:ApplicationBarMenuItem Text="Элемент меню 1"/> <shell:ApplicationBarMenuItem Text="Элемент меню 2"/> </shell:ApplicationBar.MenuItems> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>--> </phone:PhoneApplicationPage>Листинг 35.3. Файл MainPage.xaml
Страница стандартна, она по умолчанию содержит настройку, скрывающую системные значки, что приводит к отображению страницы на полный экран. В её CS-файле, листинг 35.4., содержится обработчик нажатия на кнопку, открывающий страницу GamePage.
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.Shapes; using Microsoft.Phone.Controls; namespace P28_1 { public partial class MainPage : PhoneApplicationPage { // Конструктор public MainPage() { InitializeComponent(); } // Простая кнопка Щелкните обработчик событий, чтобы перейти на вторую страницу private void Button_Click(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/GamePage.xaml", UriKind.Relative)); } } }Листинг 35.4. Файл MainPage.xaml.cs
Собственно говоря, мы можем пользоваться всем арсеналом инструментов и приёмов Silverlight, работая со страницей MainPage и с другими Silverlight—страницами проекта.
XAML-код страницы GamePage, листинг 35.5., задаёт лишь свойства PhoneApplicationPage. В частности, по умолчанию игровой экран будет выводиться в портретной ориентации.
<phone:PhoneApplicationPage x:Class="P28_1.GamePage" 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:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="480" shell:SystemTray.IsVisible="False"> <!--Содержимое XAML не требуется, поскольку полная визуализация страницы выполнена XNA Framework--> </phone:PhoneApplicationPage>Листинг 35.5. Файл GamePage.xaml
Другой нагрузки он, в шаблоне проекта, не несет, так как вся работа по созданию игры ведется в файле GamePage.xaml.cs. Если мы соберемся использовать Silverlight-элементы на XNA-странице, нам придется описывать их визуализацию в GamePage.xaml.cs. В этом файле нас ждёт самое интересное – реализация механизмов XNA.
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.Navigation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; namespace P28_1 { public partial class GamePage : PhoneApplicationPage { ContentManager contentManager; GameTimer timer; SpriteBatch spriteBatch; public GamePage() { InitializeComponent(); // Получить диспетчер содержимого из приложения contentManager = (Application.Current as App).Content; // Создайте таймер для этой страницы timer = new GameTimer(); timer.UpdateInterval = TimeSpan.FromTicks(333333); timer.Update += OnUpdate; timer.Draw += OnDraw; } protected override void OnNavigatedTo(NavigationEventArgs e) { // В графическом устройстве включите визуализацию XNA для режима совместного использования SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true); // Создание нового SpriteBatch, который может использоваться для рисования текстур. spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice); // TODO: загрузите сюда содержимое игры с помощью this.content // Запуск таймера timer.Start(); base.OnNavigatedTo(e); } protected override void OnNavigatedFrom(NavigationEventArgs e) { // Остановка таймера timer.Stop(); // В графическом устройстве выключите визуализацию XNA для режима совместного использования SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(false); base.OnNavigatedFrom(e); } /// <summary> /// Позволяет странице выполнять логику, такую как обновление окружения, /// поиск конфликтов, сбор входных данных и воспроизведение звука. /// </summary> private void OnUpdate(object sender, GameTimerEventArgs e) { // TODO: добавьте здесь логику обновления } /// <summary> /// Разрешает автоматическую прорисовку страницы. /// </summary> private void OnDraw(object sender, GameTimerEventArgs e) { SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: добавьте здесь свой код прорисовки } } }Листинг 35.6. Файл GamePage.xaml.cs
В конструкторе (GamePage) мы получаем диспетчер содержимого, что позволяет нам работать с контентом, кроме того, в классе определено несколько переменных. Это – вышеупомянутый ContentManager, это timer – объект типа GameTimer, на основе которого на странице работают методы, аналогичные методам Update и Draw в обычных XNA-проектах. Это хорошо знакомый вам по XNA-проектам объект типа SpriteBatch, который используется для визуализации двумерных графических объектов.
В конструкторе, кроме того, мы создаём игровой таймер, назначаем интервал срабатывания таймера, соответствующий времени обновления экрана (как в XNA-проектах, другими словами) и определяем обработчики для его событий Update и Draw – то есть – готовим всё для работы игрового цикла XNA.
В методе OnNavigatedTo, выполняющемся при переходе на страницу, мы запускаем XNA-визуализацию, создаём новый SpriteBatch, и, кроме того, здесь мы будем загружать ресурсы игры. Здесь же мы запускаем таймер.
Когда мы уходим со страницы, игровой таймер останавливается.
Метод OnUpdate – это аналог метода Update из XNA. Здесь мы будем реализовывать игровую логику. Метод OnDraw – аналог метода Draw. Он предназначен для отрисовки игровых объектов. По умолчанию здесь присутствует лишь команда очистки экрана.
Посмотрим теперь, как пользоваться вышеописанными механизмами на практике.