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

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

35.2. Пример приложения

Реализуем в новом окружении пример, аналогичный проекту P5_1, который мы рассматривали на пятом практическом занятии. Здесь игровой объект перемещался по экрану в позицию касания экрана.

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

На странице MainPage.xaml изменим заголовок страницы на "ПЕРВАЯ ИГРА", поменяем подпись к кнопке на "Играть!". В листинге 35.7. приведен измененный код измененной страницы.

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" Margin="0,410,0,129" />
            
        </Grid>
    </Grid>
  
</phone:PhoneApplicationPage>
Листинг 35.7. Файл MainPage.xaml

Теперь добавим в проект P28_2LibContent изображение для визуализации. Делается это командой контекстного меню проекта Добавить > Существующий элемент. В итоге наш проект будет выглядеть следующим образом, рис. 35.4.

Игровой ресурс, добавленный в проект Content

Рис. 35.4. Игровой ресурс, добавленный в проект Content

Вся остальная работа над игрой ведется в файле GamePage.xaml.cs. В листинге 35.8 приведен его полный код.

using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;

namespace P28_2
{
    public partial class GamePage : PhoneApplicationPage
    {
        // Менеджер контента
        ContentManager contentManager;
        // Таймер для организации игрового цикла
        GameTimer timer;
        // Объект для вывода 2D-графики
        SpriteBatch spriteBatch;
        // Текстура для хранения изображения
        private Texture2D mySprite;
        //Позиция вывода изображения
        private Vector2 position = new Vector2(0, 200);

        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);

            // Загружаем игровой контент
            mySprite = contentManager.Load<Texture2D>("ball");

            // Запуск таймера
            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)
        {
            //Получаем коллекцию объектов, содержащих информацию о касаниях экрана
            TouchCollection touchLocations = TouchPanel.GetState();
            //Перебираем коллекцию, присваивая объекту координаты касания
            foreach (TouchLocation touchLocation in touchLocations)
            {
                if (touchLocation.State == TouchLocationState.Pressed)
                {
                    position = touchLocation.Position;
                }
            }
        }

        /// <summary>
        /// Разрешает автоматическую прорисовку страницы.
        /// </summary>
        private void OnDraw(object sender, GameTimerEventArgs e)
        {
            // Очищаем экран
            SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue);
            // Выводим изображение
            spriteBatch.Begin();
                spriteBatch.Draw(mySprite, position, Color.White);
            spriteBatch.End();
        }
    }
}
Листинг 35.8. Файл GamePage.xaml.cs

Обратите внимание на то, что для работы с сенсорным вводом нам понадобилось подключить пространство имён Microsoft.Xna.Framework.Input.Touch.

Если сопоставить этот код с кодом на XNA, выполняющим схожую функциональность, то окажется, что в данном случае иначе выглядит лишь код загрузки игрового ресурса (всё дело лишь в другом имени объекта):

mySprite = contentManager.Load<Texture2D>("ball");
Листинг 35..

В целом же наш простой пример в модификации практически не нуждался (если не учитывать необходимость располагать соответствующий код в методах, выполняющих ту же функциональность, что и в XNA, но с другими именами). В итоге мы получили следующее, рис. 35.5.

Игровой экран проекта

Рис. 35.5. Игровой экран проекта

Обратите внимание на то, что начало координат расположено в левом верхнем углу экрана, экран по умолчанию расположен в портретной ориентации.

35.3. Выводы

В данной лабораторной работе мы рассмотрели шаблон Приложение Silverlignt и XNA для Windows Phone. Он позволяет объединять в одном приложении возможности XNA и Silverlight.

35.4. Задание

Выберите один из проектов, которыми мы занимались ранее, изучая построение приложений для XNA, реализуйте его с помощью шаблона Приложение Silverlignt и XNA для Windows Phone.

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