Разработка компьютерных игр для Windows Phone 7 с использованием технологий Silverlight и XNA

Озвучивание игр, видео

Разбить на страницы
Показывать лекцию целиком

Цель работы: Научиться озвучивать Silverlight-игры, воспроизводить видео на страницах

33.1. Озвучивание средствами XNA

В Silverlight-приложениях можно использовать библиотеки XNA. В частности, сейчас мы хотим воспользоваться возможностями XNA по работе со звуками. Создадим новый проект, P26_1. Здесь мы собираемся создать макет простой игры, в которой окружность движется по экрану, отскакивая от стенок экрана. В процессе игры звучит музыка, когда воспроизведение заканчивается, оно начинается снова. При прикосновении к окружности она меняет позицию, скорость и направление движения, при прикосновении воспроизводится звук.

Для начала спроектируем внешний вид нашей игры. Мы хотим, чтобы игровой процесс происходил на полном экране, чтобы во время игры на экран не выводилась строка системных значков (System Tray). Игру мы будем реализовывать на странице MainPage. Удалим из XAML-разметки страницы блоки, выводящие название программы и название страницы, установим свойство объекта PhoneAplicationPage SystemTray в значение False.

Таким образом мы получим полный экран размером 800х480, подходящий для реализации нашей игры. Создадим фоновое изображение размером 800х480, выведем его на экран с помощью элемента управления Image. У элемента управления Grid, который содержит наши элементы управления, установим значение Margin в "0,0,0,0", добавим новый эллипс, так же зададим для него Margin, равный "0,0,0,0". Для эллипса создадим обработчик события Tap и опишем трансформацию TranslateTransform – будем с помощью этой трансформации перемещать объект.

В листинге 33.1 вы можете видеть XAML-код страницы.

<phone:PhoneApplicationPage 
    x:Class="P26_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"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Landscape" Orientation="Landscape"
    mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="800"
    shell:SystemTray.IsVisible="False">

    <!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--ContentPanel — поместите здесь дополнительное содержимое-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">
            <Image Height="480" HorizontalAlignment="Left" Name="image1" 
Stretch="Fill" VerticalAlignment="Top" Width="800" 
Source="/P26_1;component/Res/Background.jpg" />
            <Ellipse Height="100" 
                     HorizontalAlignment="Left" 
                     Margin="0,0,0,0" 
                     Name="ellipse1" 
                     Stroke="Black" 
                     StrokeThickness="1" 
                     VerticalAlignment="Top"
                     Width="100" 
                     Fill="#FF00CB00" Tap="ellipse1_Tap">
                <Ellipse.RenderTransform>
                    <TranslateTransform x:Name="translate" />
                </Ellipse.RenderTransform>
            </Ellipse>

        </Grid>
    </Grid>
</phone:PhoneApplicationPage>

Кроме того, в файле App.xaml.cs мы закомментировали код, отвечающий за отображение текущих счетчиков частоты смены кадров.

Так как мы собираемся работать с инструментами XNA, в папку Ссылки нашего проекта мы добавили ссылку на Microsoft.Xna.Framework.

На рис. 33.1 вы можете видеть страницу в процессе разработки

(рис 33.1) Страница MainPage.xaml

На рис. 33.2 показан Обозреватель решений нашего проекта.

(рис 33.2) Обозреватель решений проектаl

Перейдем к коду приложения, к странице MainPage.xaml.cs. В листинге 33.2 приведен её код

using System;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Phone.Controls;
using System.Windows.Resources;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
namespace P26_1
{
    public partial class MainPage : PhoneApplicationPage
    {
        //Для перемещения объекта
        double speedAndDirX = 0;
        double speedAndDirY = 0;
        //Для звуков и музыки
        SoundEffect sound;
        SoundEffect backMusic;
        //Используется для управления проигрыванием
        SoundEffectInstance backMusicInstance;
        public MainPage()
        {
            InitializeComponent();
            //Загружаем звуки
            LoadSound("Res/SoundFx1.wav", out sound);
            LoadSound("Res/Music.wav", out backMusic);
            //Работаем с SoundEffectInstance
            backMusicInstance = backMusic.CreateInstance();
            //Настраиваем параметры воспроизведения музыки
            backMusicInstance.IsLooped = true;
            backMusicInstance.Volume = 0.5f;
            //Запустим проигрывание музыки
            backMusicInstance.Play();
            //Изменим положение и скорость объекта
            ChangeDir();
            //Добавим обработчик события Rendering
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
        }
        //В обработчике события Rendering
        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            //Выполним метод Update для обеспечения работоспособности XNA-механизмов
            FrameworkDispatcher.Update();
            //Изменим позицию объекта
            translate.X += speedAndDirX;
            translate.Y += speedAndDirY;
            //Проверим на столкновение объекта с границами экрана
            CheckBounds();
        }
        //При прикосновении к эллипсу
        private void ellipse1_Tap(object sender, GestureEventArgs e)
        {
            //Поменяем позицию, скорость, направление движения объекта
            ChangeDir();
            //Проиграем звук
            sound.Play();
        }

        void ChangeDir()
        {
            //Для работы со случайными числами
            Random r = new Random();
            //Получим новые значения направления и скорости
            speedAndDirX = r.Next(5) - r.Next(5);
            speedAndDirY = r.Next(5) - r.Next(5);
            //Установим объект в новую позицию на экране, не пересекая границ экрана
            translate.X = r.Next(700);
            translate.Y = r.Next(380);
        }
        //Проверим на столкновение с границами
        void CheckBounds()
        {
            //При пересечении границ инвертируем направление
            if (translate.X < 0 || translate.X > 700)
            {
                speedAndDirX = -speedAndDirX;
            }
            if (translate.Y < 0 || translate.Y > 380)
            {
                speedAndDirY = -speedAndDirY;
            }
        }
        //Загрузка звуковых ресурсов
        void LoadSound(string FilePath, out SoundEffect Sound)
        {
            //Сформируем информацию о потоке
            StreamResourceInfo SoundFileInfo = App.GetResourceStream(new Uri((FilePath), UriKind.Relative));
            //Создаем новый объект SoundEffect из потока
            Sound = SoundEffect.FromStream(SoundFileInfo.Stream);
        }

    }
}

В код мы, во-первых, подключаем пространства имен Microsoft.Xna.Framework и Microsoft.Xna.Framework.Audio. Мы определяем переменные для управления объектом, пару переменных типа SoundEffect для работы со звуками и музыкой и одну переменную SoundEffectInstance, которая используется для настройки параметров воспроизведения фоновой музыки.

Мы создали метод LoadSound, передавая которому адрес, где хранится нужная композиция, мы устанавливаем загруженную композицию в соответствующую переменную. Это мы делаем в конструкторе класса. Здесь же мы создаём из объекта SoundEffect объект SoundEffectInstance, настраиваем его параметры и запускаем воспроизведение фоновой музыки. Далее в конструкторе мы вызываем метод ChangeDir(), который случайным образом, в пределах границ экрана, изменяет положение объекта и задаёт параметры его передвижения. Так же в конструкторе мы запускаем "двигатель" всего нашего проекта – а именно подключаем обработчик события CompositionTarget.Rendering.

Этот обработчик используется для анимации (пример с ним мы рассматривали ранее), и, что очень важно для звуковой составляющей нашей игры, для вызова метода FrameworkDispatcher.Update(). Этот вызов обеспечивает работу механизмов XNA. В XNA-проектах, где реализован класс Game, данный метод вызывается автоматически. Частота, с которой вызывается CompositionTarget.Rendering (каждое обновление экрана, другими словами, то есть – около 30 раз в секунду) вполне достаточна для нормальной работы механизмов XNA.

В том же обработчике мы вызываем метод CheckBounds, который проверяет, не пересечены ли границы экрана, и если это произошло – меняет направление по соответствующей координате на противоположное. Выполнять подобные манипуляции здесь мы можем, так как значения X и Y объекта translate в данном случае соответствуют экранным координатам игрового объекта.

И, наконец, в обработчике прикосновения к эллипсу мы вызываем метод ChangeDir(), объект перемещается в новую экранную позицию и начинает движение в новом направлении с измененной скоростью, и воспроизводим звук, назначенный нами на данное событие.

Рассмотрим еще один пример, касающийся воспроизведения видео и звуков средствами Silverlight.

33.2. Видео и звуки средствами Silverlight

Возможность воспроизведения видео полезна при создании игровых заставок, возможно, какие-то моменты вашей игры так же будут более выразительными, если в них использовать видеофрагменты. Рассмотрим воспроизведение видео в Silverlight-проектах с использованием элемента управления MediaElement. Простейший вариант использования данного объекта заключается в добавлении его на страницу, в настройке свойства Source, которое должно содержать путь к видеофайлу, и в установке свойства AutoPlay – благодаря ему видео начнёт воспроизводиться после отображения страницы с ним на экране.

Для реализации данного примера мы создали новый проект, P26_2, на рис. 33.3 вы можете видеть его Обозреватель ресурсов

(рис 33.3) Обозреватель проекта P26_2, свойства видеофайла

Обратите внимание на то, что у видеофайла (Video.mp4) свойство Действие при построении установлено в значение Resource. Это нужно для правильной работы MediaElement.

В листинге 33.3 вы можете видеть код страницы Video.xaml

<phone:PhoneApplicationPage 
    x:Class="P26_2.Video"
    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="Landscape" Orientation="Landscape"
    mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="728"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <!--ContentPanel — поместите здесь дополнительное содержимое-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <MediaElement Height="360" HorizontalAlignment="Left" Name="mediaElement1" VerticalAlignment="Top" 
            Width="480" Source="Media/Video.mp4" AutoPlay="True" Margin="117,0,0,0" />
            <Button Content="Стоп" Height="72" HorizontalAlignment="Left" Margin="117,385,0,0" 
            Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
            <Button Content="Пауза/Старт" Height="72" HorizontalAlignment="Left" Margin="296,385,0,0" 
            Name="button2" VerticalAlignment="Top" Width="301" Click="button2_Click" />
        </Grid>
    </Grid>
 </phone:PhoneApplicationPage>

Здесь описан MediaElement, принимающий к проигрыванию файл, расположенный по адресу Media/Video.mp4, свойство AutoPlay установлено в True, размеры элемента управления равны размеры видео, при необходимости можно настраивать как размеры, так и особенности размещения контента в элементе.

Кроме того, здесь описаны пара кнопок. Одной из них мы будем останавливать воспроизведение, другой – ставить на паузу и включать воспроизведение. Для этого кнопки имеют обработчики событий Click. Собственно говоря, если бы нам нужно было воспроизвести видеофайл и больше ничего не предпринимать, вышеприведенного описания объекта MediaElement для этого хватило бы. Так как мы собираемся управлять воспроизведением, для этого нам понадобится код в файле Video.xaml.cs, приведенный в листинге 33.4.

using System.Windows;
using System.Windows.Media;
using Microsoft.Phone.Controls;

namespace P26_2
{
    public partial class Video : PhoneApplicationPage
    {
        public Video()
        {
            InitializeComponent();
        }
        //Остановить воспроизведение
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            mediaElement1.Stop();
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            //Если проигрывается
            if (mediaElement1.CurrentState == MediaElementState.Playing)
            {
                //Приостановить
                mediaElement1.Pause();
            }
                //Есл в других состояниях
            else
            {
                //Включить воспроизведение
                mediaElement1.Play();
            }
        }
    }
}

В обработчике для button1 мы используем метод MediaElement Stop() для остановки воспроизведения. В обработчике для button2 мы проверяем состояние объекта. Если видео воспроизводится, мы приостанавливаем воспроизведение. В других случаях – начинаем воспроизведение.

На рис. 33.4 вы можете видеть визуальное представление страницы Video.xaml

(рис 33.4) Страница Video.xaml

В нашем проекте есть еще одна страница, BackMusic.xaml, на которой мы хотим организовать циклическое воспроизведение фоновой музыки. Мы воспользуемся для этого тем же элементом управления MediaElement, однако, зададим в качестве источника MP3-файл (Music.mp3), зададим автоматическое начало проигрывания и обработчик события MediaEnded. Это событие происходит, когда завершается воспроизведение медиафайла. По данному событию будем начинать воспроизведение сначала.

В листинге 33.5 вы можете видеть код описания элемента из XAML-файла

       <MediaElement Height="120" HorizontalAlignment="Left" Margin="143,42,0,0" 
       Name="mediaElement1" VerticalAlignment="Top" Width="160" Source="/Media/Music.mp3" 
       AutoPlay="True" MediaEnded="mediaElement1_MediaEnded" />

Наш элемент ничего не отображает на экране, поэтому важность имеют лишь те его настройки, которые отвечают за воспроизведение звукового файла.

В листинге 33.6 вы можете видеть обработчик события MediaEnded

        void mediaElement1_MediaEnded(object sender, RoutedEventArgs e)
        {
            mediaElement1.Play();
        }

33.3. Выводы

В этой лабораторной работе мы научились использовать библиотеки XNA для озвучивания игр, кроме того, рассмотрели элемент управления MediaElement, который позволяет проигрывать видеофрагменты и музыкальные файлы на страницах Silverlight-приложений

33.4. Задание

Выясните, видеофайлы в каких форматах можно проигрывать с помощью MediaElement. Реализуйте приложение, проигрывающее файлы в различных форматах.

33.5. Дополнительные материалы

К данной лабораторной работе прилагается видеоурок

и демонстрационный проект.

Страницы:

Цель работы: Научиться озвучивать Silverlight-игры, воспроизводить видео на страницах

33.1. Озвучивание средствами XNA

В Silverlight-приложениях можно использовать библиотеки XNA. В частности, сейчас мы хотим воспользоваться возможностями XNA по работе со звуками. Создадим новый проект, P26_1. Здесь мы собираемся создать макет простой игры, в которой окружность движется по экрану, отскакивая от стенок экрана. В процессе игры звучит музыка, когда воспроизведение заканчивается, оно начинается снова. При прикосновении к окружности она меняет позицию, скорость и направление движения, при прикосновении воспроизводится звук.

Для начала спроектируем внешний вид нашей игры. Мы хотим, чтобы игровой процесс происходил на полном экране, чтобы во время игры на экран не выводилась строка системных значков (System Tray). Игру мы будем реализовывать на странице MainPage. Удалим из XAML-разметки страницы блоки, выводящие название программы и название страницы, установим свойство объекта PhoneAplicationPage SystemTray в значение False.

Таким образом мы получим полный экран размером 800х480, подходящий для реализации нашей игры. Создадим фоновое изображение размером 800х480, выведем его на экран с помощью элемента управления Image. У элемента управления Grid, который содержит наши элементы управления, установим значение Margin в "0,0,0,0", добавим новый эллипс, так же зададим для него Margin, равный "0,0,0,0". Для эллипса создадим обработчик события Tap и опишем трансформацию TranslateTransform – будем с помощью этой трансформации перемещать объект.

В листинге 33.1 вы можете видеть XAML-код страницы.

<phone:PhoneApplicationPage 
    x:Class="P26_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"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Landscape" Orientation="Landscape"
    mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="800"
    shell:SystemTray.IsVisible="False">

    <!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--ContentPanel — поместите здесь дополнительное содержимое-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">
            <Image Height="480" HorizontalAlignment="Left" Name="image1" 
Stretch="Fill" VerticalAlignment="Top" Width="800" 
Source="/P26_1;component/Res/Background.jpg" />
            <Ellipse Height="100" 
                     HorizontalAlignment="Left" 
                     Margin="0,0,0,0" 
                     Name="ellipse1" 
                     Stroke="Black" 
                     StrokeThickness="1" 
                     VerticalAlignment="Top"
                     Width="100" 
                     Fill="#FF00CB00" Tap="ellipse1_Tap">
                <Ellipse.RenderTransform>
                    <TranslateTransform x:Name="translate" />
                </Ellipse.RenderTransform>
            </Ellipse>

        </Grid>
    </Grid>
</phone:PhoneApplicationPage>

Кроме того, в файле App.xaml.cs мы закомментировали код, отвечающий за отображение текущих счетчиков частоты смены кадров.

Так как мы собираемся работать с инструментами XNA, в папку Ссылки нашего проекта мы добавили ссылку на Microsoft.Xna.Framework.

На рис. 33.1 вы можете видеть страницу в процессе разработки

(рис 33.1) Страница MainPage.xaml

На рис. 33.2 показан Обозреватель решений нашего проекта.

(рис 33.2) Обозреватель решений проектаl

Перейдем к коду приложения, к странице MainPage.xaml.cs. В листинге 33.2 приведен её код

using System;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Phone.Controls;
using System.Windows.Resources;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
namespace P26_1
{
    public partial class MainPage : PhoneApplicationPage
    {
        //Для перемещения объекта
        double speedAndDirX = 0;
        double speedAndDirY = 0;
        //Для звуков и музыки
        SoundEffect sound;
        SoundEffect backMusic;
        //Используется для управления проигрыванием
        SoundEffectInstance backMusicInstance;
        public MainPage()
        {
            InitializeComponent();
            //Загружаем звуки
            LoadSound("Res/SoundFx1.wav", out sound);
            LoadSound("Res/Music.wav", out backMusic);
            //Работаем с SoundEffectInstance
            backMusicInstance = backMusic.CreateInstance();
            //Настраиваем параметры воспроизведения музыки
            backMusicInstance.IsLooped = true;
            backMusicInstance.Volume = 0.5f;
            //Запустим проигрывание музыки
            backMusicInstance.Play();
            //Изменим положение и скорость объекта
            ChangeDir();
            //Добавим обработчик события Rendering
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
        }
        //В обработчике события Rendering
        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            //Выполним метод Update для обеспечения работоспособности XNA-механизмов
            FrameworkDispatcher.Update();
            //Изменим позицию объекта
            translate.X += speedAndDirX;
            translate.Y += speedAndDirY;
            //Проверим на столкновение объекта с границами экрана
            CheckBounds();
        }
        //При прикосновении к эллипсу
        private void ellipse1_Tap(object sender, GestureEventArgs e)
        {
            //Поменяем позицию, скорость, направление движения объекта
            ChangeDir();
            //Проиграем звук
            sound.Play();
        }

        void ChangeDir()
        {
            //Для работы со случайными числами
            Random r = new Random();
            //Получим новые значения направления и скорости
            speedAndDirX = r.Next(5) - r.Next(5);
            speedAndDirY = r.Next(5) - r.Next(5);
            //Установим объект в новую позицию на экране, не пересекая границ экрана
            translate.X = r.Next(700);
            translate.Y = r.Next(380);
        }
        //Проверим на столкновение с границами
        void CheckBounds()
        {
            //При пересечении границ инвертируем направление
            if (translate.X < 0 || translate.X > 700)
            {
                speedAndDirX = -speedAndDirX;
            }
            if (translate.Y < 0 || translate.Y > 380)
            {
                speedAndDirY = -speedAndDirY;
            }
        }
        //Загрузка звуковых ресурсов
        void LoadSound(string FilePath, out SoundEffect Sound)
        {
            //Сформируем информацию о потоке
            StreamResourceInfo SoundFileInfo = App.GetResourceStream(new Uri((FilePath), UriKind.Relative));
            //Создаем новый объект SoundEffect из потока
            Sound = SoundEffect.FromStream(SoundFileInfo.Stream);
        }

    }
}

В код мы, во-первых, подключаем пространства имен Microsoft.Xna.Framework и Microsoft.Xna.Framework.Audio. Мы определяем переменные для управления объектом, пару переменных типа SoundEffect для работы со звуками и музыкой и одну переменную SoundEffectInstance, которая используется для настройки параметров воспроизведения фоновой музыки.

Мы создали метод LoadSound, передавая которому адрес, где хранится нужная композиция, мы устанавливаем загруженную композицию в соответствующую переменную. Это мы делаем в конструкторе класса. Здесь же мы создаём из объекта SoundEffect объект SoundEffectInstance, настраиваем его параметры и запускаем воспроизведение фоновой музыки. Далее в конструкторе мы вызываем метод ChangeDir(), который случайным образом, в пределах границ экрана, изменяет положение объекта и задаёт параметры его передвижения. Так же в конструкторе мы запускаем "двигатель" всего нашего проекта – а именно подключаем обработчик события CompositionTarget.Rendering.

Этот обработчик используется для анимации (пример с ним мы рассматривали ранее), и, что очень важно для звуковой составляющей нашей игры, для вызова метода FrameworkDispatcher.Update(). Этот вызов обеспечивает работу механизмов XNA. В XNA-проектах, где реализован класс Game, данный метод вызывается автоматически. Частота, с которой вызывается CompositionTarget.Rendering (каждое обновление экрана, другими словами, то есть – около 30 раз в секунду) вполне достаточна для нормальной работы механизмов XNA.

В том же обработчике мы вызываем метод CheckBounds, который проверяет, не пересечены ли границы экрана, и если это произошло – меняет направление по соответствующей координате на противоположное. Выполнять подобные манипуляции здесь мы можем, так как значения X и Y объекта translate в данном случае соответствуют экранным координатам игрового объекта.

И, наконец, в обработчике прикосновения к эллипсу мы вызываем метод ChangeDir(), объект перемещается в новую экранную позицию и начинает движение в новом направлении с измененной скоростью, и воспроизводим звук, назначенный нами на данное событие.

Рассмотрим еще один пример, касающийся воспроизведения видео и звуков средствами Silverlight.

33.2. Видео и звуки средствами Silverlight

Возможность воспроизведения видео полезна при создании игровых заставок, возможно, какие-то моменты вашей игры так же будут более выразительными, если в них использовать видеофрагменты. Рассмотрим воспроизведение видео в Silverlight-проектах с использованием элемента управления MediaElement. Простейший вариант использования данного объекта заключается в добавлении его на страницу, в настройке свойства Source, которое должно содержать путь к видеофайлу, и в установке свойства AutoPlay – благодаря ему видео начнёт воспроизводиться после отображения страницы с ним на экране.

Для реализации данного примера мы создали новый проект, P26_2, на рис. 33.3 вы можете видеть его Обозреватель ресурсов

(рис 33.3) Обозреватель проекта P26_2, свойства видеофайла

Обратите внимание на то, что у видеофайла (Video.mp4) свойство Действие при построении установлено в значение Resource. Это нужно для правильной работы MediaElement.

В листинге 33.3 вы можете видеть код страницы Video.xaml

<phone:PhoneApplicationPage 
    x:Class="P26_2.Video"
    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="Landscape" Orientation="Landscape"
    mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="728"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <!--ContentPanel — поместите здесь дополнительное содержимое-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <MediaElement Height="360" HorizontalAlignment="Left" Name="mediaElement1" VerticalAlignment="Top" 
            Width="480" Source="Media/Video.mp4" AutoPlay="True" Margin="117,0,0,0" />
            <Button Content="Стоп" Height="72" HorizontalAlignment="Left" Margin="117,385,0,0" 
            Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
            <Button Content="Пауза/Старт" Height="72" HorizontalAlignment="Left" Margin="296,385,0,0" 
            Name="button2" VerticalAlignment="Top" Width="301" Click="button2_Click" />
        </Grid>
    </Grid>
 </phone:PhoneApplicationPage>

Здесь описан MediaElement, принимающий к проигрыванию файл, расположенный по адресу Media/Video.mp4, свойство AutoPlay установлено в True, размеры элемента управления равны размеры видео, при необходимости можно настраивать как размеры, так и особенности размещения контента в элементе.

Кроме того, здесь описаны пара кнопок. Одной из них мы будем останавливать воспроизведение, другой – ставить на паузу и включать воспроизведение. Для этого кнопки имеют обработчики событий Click. Собственно говоря, если бы нам нужно было воспроизвести видеофайл и больше ничего не предпринимать, вышеприведенного описания объекта MediaElement для этого хватило бы. Так как мы собираемся управлять воспроизведением, для этого нам понадобится код в файле Video.xaml.cs, приведенный в листинге 33.4.

using System.Windows;
using System.Windows.Media;
using Microsoft.Phone.Controls;

namespace P26_2
{
    public partial class Video : PhoneApplicationPage
    {
        public Video()
        {
            InitializeComponent();
        }
        //Остановить воспроизведение
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            mediaElement1.Stop();
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            //Если проигрывается
            if (mediaElement1.CurrentState == MediaElementState.Playing)
            {
                //Приостановить
                mediaElement1.Pause();
            }
                //Есл в других состояниях
            else
            {
                //Включить воспроизведение
                mediaElement1.Play();
            }
        }
    }
}

В обработчике для button1 мы используем метод MediaElement Stop() для остановки воспроизведения. В обработчике для button2 мы проверяем состояние объекта. Если видео воспроизводится, мы приостанавливаем воспроизведение. В других случаях – начинаем воспроизведение.

На рис. 33.4 вы можете видеть визуальное представление страницы Video.xaml

(рис 33.4) Страница Video.xaml

В нашем проекте есть еще одна страница, BackMusic.xaml, на которой мы хотим организовать циклическое воспроизведение фоновой музыки. Мы воспользуемся для этого тем же элементом управления MediaElement, однако, зададим в качестве источника MP3-файл (Music.mp3), зададим автоматическое начало проигрывания и обработчик события MediaEnded. Это событие происходит, когда завершается воспроизведение медиафайла. По данному событию будем начинать воспроизведение сначала.

В листинге 33.5 вы можете видеть код описания элемента из XAML-файла

       <MediaElement Height="120" HorizontalAlignment="Left" Margin="143,42,0,0" 
       Name="mediaElement1" VerticalAlignment="Top" Width="160" Source="/Media/Music.mp3" 
       AutoPlay="True" MediaEnded="mediaElement1_MediaEnded" />

Наш элемент ничего не отображает на экране, поэтому важность имеют лишь те его настройки, которые отвечают за воспроизведение звукового файла.

В листинге 33.6 вы можете видеть обработчик события MediaEnded

        void mediaElement1_MediaEnded(object sender, RoutedEventArgs e)
        {
            mediaElement1.Play();
        }

33.3. Выводы

В этой лабораторной работе мы научились использовать библиотеки XNA для озвучивания игр, кроме того, рассмотрели элемент управления MediaElement, который позволяет проигрывать видеофрагменты и музыкальные файлы на страницах Silverlight-приложений

33.4. Задание

Выясните, видеофайлы в каких форматах можно проигрывать с помощью MediaElement. Реализуйте приложение, проигрывающее файлы в различных форматах.

33.5. Дополнительные материалы

К данной лабораторной работе прилагается видеоурок

и демонстрационный проект.

Вернуться к учебному плану