| Невозможно пройти тесты, в окне с вопросами пусто |
Совместное использование 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. Он предназначен для отрисовки игровых объектов. По умолчанию здесь присутствует лишь команда очистки экрана.
Посмотрим теперь, как пользоваться вышеописанными механизмами на практике.
