Опубликован: 12.02.2013 | Доступ: свободный | Студентов: 791 / 47 | Длительность: 17:51:00
Специальности: Программист
Лекция 8:

Создание приложений XNA

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

Можно создать решение Visual Studio, содержащее и приложение Silverlight, и компонент игры XNA. Эту возможность удобно использовать, например, для создания игровых меню, или можно добавить элементы 3D графики в приложение Silverlight.

Для этого нужно создать решение Visual Studio, используя шаблон Приложение Silverlight и XNA для Windows Phone. Новое решение содержит три проекта.

Главным проектом будет приложение Silverlight, которое является начальным проектом. Второй проект содержит набор необходимых библиотек. Третий предназначен для хранения контента XNA для игровой части решения.

При создании объединённого приложения также будет создана новая страница Silverlight, которая будет содержать игру XNA. Игровой процесс XNA размещается на странице GamePage.

Создание игровой среды XNA в Silverlight

При запуске игры XNA вызывается набор методов для инициализации игры, загрузки игрового контента и периодического выполнения обновления игрового мира и его перерисовки на экране. Когда игра работает на странице Silverlight, необходимо обеспечить выполнение этих действий.

protected override void OnNavigatedTo(NavigationEventArgs e) 
protected override void OnNavigatedFrom(NavigationEventArgs e)
private void OnUpdate(object sender, GameTimerEventArgs e)
private void OnDraw(object sender, GameTimerEventArgs e)

Эти методы находятся на странице игры, и их необходимо заполнить. Метод OnNavigatedTo выполняет функции методов Initialise и LoadContent, а методы OnUpdate и OnDraw выполняют функции методов Update и Draw соответственно. Метод OnNavigatedTo всегда вызывается, когда пользователь переходит на страницу, и здесь игра должна загрузить контент и начать выполнение. Этот метод также создаёт таймер, который выполняет вызовы методов OnUpdate и OnDraw во время работы игры.

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

Чтобы запустить игру при нажатии на кнопку, в обработчик нажатия на кнопку нужно добавить следующий код:

private void Button_Click(object sender, RoutedEventArgs e)
{  
    NavigationService.Navigate(new Uri("/GamePage.xaml", UriKind.Relative));
}

Если во время работы игры нажать кнопку телефона Назад, то произойдёт переход к предыдущей странице, и игра закроется. Обратите внимание, что игра перезапускается каждый раз при переходе на страницу. При этом, игра перезагружает все текстуры и игровые ресурсы. Было бы разумно сохранить текстуры и состояние игры в отдельном классе и кэшировать данные, чтобы пользователь мог вернуться на то место в игре, на котором он закончил её в прошлый раз.

Взаимодействие XNA и Silverlight

Существует возможность наложить визуальные элементы Silverlight поверх игры XNA. Это позволяет легко добавить к игре кнопки и текст, используя элементы Button и TextBlock. Для добавления элементов Silverlight на экран игры сначала нужно создать элементы и добавить их в файл GamePage.xaml:

<Grid x:Name="LayoutRoot">
    <StackPanel>
        <TextBlock x:Name="ScoreTextBlock" Text="0:0" TextAlignment="Center"
            Style="{StaticResource PhoneTextTitle1Style}" />
        <Button Content="Quit" Name="quitButton" Width="480"
            Click="quitButton_Click" />
    </StackPanel>
</Grid>

Этот код создаёт элемент StackPanel с кнопкой и блоком текста. Кнопка будет завершать игру, а в текстовом блоке будет отображаться счёт игры.

Теперь эти элементы нужно вывести на экран. Рендеринг элементов Silverlight выполняется в классе UIElementRenderer. Экземпляр этого класса создаётся при загрузке страницы:

UIElementRenderer elementRenderer;

if (elementRenderer == null)
{
    elementRenderer = new UIElementRenderer(this, (int)ActualWidth,
        (int)ActualHeight);
}

Этот код проверяет, существует ли elementRenderer, и если нет — создаёт его. Обратите внимание, конструктор этого элемента принимает в качестве параметров ссылку на используемую страницу, ширину и высота области для отрисовки.

Теперь этот объект можно использовать его в методе OnDraw для создания элементов Silverlight:

private void OnDraw(object sender, GameTimerEventArgs e)
{

    // рендеринг элементов Silverlight с помощью объекта UIElementRenderer
    elementRenderer.Render();

    SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin();

    spriteBatch.Draw(ballTexture, ballRectangle, Color.White);
    
    ...

    spriteBatch.Draw(elementRenderer.Texture, Vector2.Zero, Color.White);

    spriteBatch.End();
}

Элементы Silverlight будут выводиться поверх игровых объектов. Если нужно использовать элементы Silverlight в качестве фона для игры, их нужно выводить первыми. Во время работы игры XNA элементы Silverlight отвечают на действия пользователя, и их можно связать с обработчиками событий. Обработчики событий элементов можно использовать даже если элементы не выводятся на экран.

Краткие итоги

  1. XNA предоставляет среду для создания 2D и 3D игр для компьютеров под управлением Windows, Xbox 360 или Windows Phone.
  2. Принцип работа игр XNA существенно отличается от приложений Silverlight. Игра XNA содержит методы для загрузки контента, обновления и отрисовки игрового мира, которые вызывает XNA во время работы игры.
  3. При создании нового проекта игры XNA в Visual Studio создаётся класс, содержащий пустые методы LoadContent, Update и Draw, в которые нужно добавить код игры. Метод LoadContent должен загружать весь необходимый игровой контент. Метод Update вызывается с частотой 30 раз в секунду для обновления игрового контента, а метод Draw вызывается для отрисовки игры на экране.
  4. Любым контентом (например, изображения или звуки), добавленным к игре XNA, управляет контент-менеджер, который использует фильтры для различных типов файлов и процессоры вывода, которые готовят контент к развертыванию на целевом устройстве. В пределах игры XNA способ загрузки и использования контента одинаков независимо от целевых аппаратных средств.
  5. Спрайт состоит из текстуры, которая определяет внешний вид объекта, и положения, которое определяет, где будет отрисован элемент и его размер. XNA предоставляет объекты для хранения этой информации.
  6. При отрисовке двумерных изображений в системе XNA начало координат находится в левом верхнем углу экрана.
  7. Сенсорный экран Windows Phone предоставляет низкоуровневый массив, в котором хранится информация о сенсорном вводе, которая может содержать детали, по крайней мере, 4 точек касания.
  8. Игры XNA могут выводить на экран текст с помощью шрифтов спрайта, сделанных на основе шрифтов системы Windows для компьютеров.
  9. Программы XNA и Silverlight могут воспроизводить звуковые эффекты. Для управления воспроизведением звуковых эффектов в программе можно создать экземпляр класса SoundEffectInstance, который является дескриптором звука игры.
  10. Программы XNA для Windows Phone могут задавать разрешение и ориентацию экрана. Если будет выбрано разрешение ниже, чем поддерживаемое экраном телефона, то графический процессор будет автоматически масштабировать выбранный размер под экран устройства.
  11. В программах XNA для Windows Phone могут отключать строку состояния в верхней части экрана, чтобы использовать область экрана целиком. Также можно отключать экранную заставку.
  12. XNA и Silverlight можно совместно использовать в одном решении. Игра XNA может запускаться на странице приложения Silverlight и может содержать компоненты Silverlight.
  13. Страница XNA не содержит файла с кодом XAML, поскольку элементы Silverlight преобразуются в текстуру XNA.
  14. Для вывода на экран элементов Silverlight используется класс UIElementRenderer.

Вопросы

  1. Для чего предназначена технология XNA?
  2. В чём отличие решений XNA от Silverlight?
  3. Какие действия выполняются при загрузке игр XNA?
  4. Как в программе используется контент-менеджер?
  5. Как в программе создать и вывести на экран графический объект?
  6. Как можно использовать сенсорный экран для управления игровыми объектами?
  7. Какие действия необходимо выполнить для вывода текста на экран приложения?
  8. Каково назначение и принцип работы акселерометра?
  9. Как использовать акселерометр в приложениях для Windows Phone?
  10. Какие классы XNA используются для воспроизведения звуков в игре?
  11. Как управлять воспроизведением звука в игре?
  12. Как воспроизводить звук в программе Silverlight?
  13. Как в приложении можно управлять настройками экрана?
  14. Каким образом можно совместно использовать технологии Silverlight и XNA в одном приложении?

Упражнения

Для выполнения этих упражнений рекомендуется использовать физическое устройство Windows Phone для возможности мультисенсорного ввода и использования акселерометра.

Упражнение 1. Создание многопользовательской игры

В этом упражнении вы доработаете созданную на лекции игру.

Ограничение движения игрового объекта

На текущий момент левая платформа может перемещаться за пределы экрана. Необходимо предотвратить такую возможность.

  1. Откройте в Visual Studio проект PongGame в папке Lab7 PongGame.
  2. Добавьте в метод Draw следующий код, который не позволит левой платформе уйти за пределы экрана:
    if (lPaddleY < 0)
    {
        lPaddleY = 0;
    }
    
    if (lPaddleY + lPaddleRectangle.Height > GraphicsDevice.Viewport.Height)
    {
        lPaddleY = GraphicsDevice.Viewport.Height - lPaddleRectangle.Height;
    }
    
  3. Добавьте аналогичный код для правой платформы.
  4. Запустите игру и проверьте правильность её работы.

Добавление возможности играть вдвоём

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

  1. Измените код для управления движением платформы следующим кодом для обработки нескольких одновременных касаний экрана:
    TouchCollection touches = TouchPanel.GetState();
    
    foreach (TouchLocation touch in touches)
    {
        if (touch.Position.Y > GraphicsDevice.Viewport.Height / 2)
        {
            lPaddleY = lPaddleY + lPaddleSpeed;
        }
        else
        {
            lPaddleY = lPaddleY - lPaddleSpeed;
        }
    }
    
  2. Запустите программу и убедитесь в том, что управление платформой работает правильно.

    Теперь нужно изменить программный код для управления правой платформой, чтобы ей мог управлять второй игрок. Для этого экран можно поделить на четыре части. При обнаружении касания в каждой из областей определяется направление перемещения соответствующей платформы. Условия принадлежности касания соответствующей области показаны на рисунке:


  3. Измените код программы, чтобы управление обеими платформами осуществлялось с сенсорного экрана. (Решите эту задачу самостоятельно.)
  4. Удалите из программы код, который автоматически управляет правой платформой.
  5. Запустите игру и проверьте правильность её работы.

Упражнение 2. Использование акселерометра для управления в игре

В этом упражнении вы создадите приложение, которое использует акселерометр Windows Phone для определения положения телефона в пространстве. Существующая программа выводит на экран зелёный шарик, расположенный над красной точкой, которая расположена в центре экрана. Шарик должен управляться с помощью акселерометра.

  1. Откройте в Visual Studio проект Level в папке Lab7 Level.
  2. Откройте файл Game1.cs.
  3. Добавьте следующий код в конструктор класса Game1 для указания поддерживаемой в приложении ориентации телефона, размеров экрана и задания полноэкранного режима.
    graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
    graphics.PreferredBackBufferWidth = 480;
    graphics.PreferredBackBufferHeight = 800;
    graphics.IsFullScreen = true;
    
  4. Добавьте в проект ссылку на библиотеку Microsoft.Devices.Sensors.
  5. Добавьте в файл Game1.cs ссылку на пространство имён Microsoft.Devices.Sensors.
  6. Добавьте в метод Initialise метод следующий код для создания и запуска объекта для работы с акселерометром:
    Accelerometer acc = new Accelerometer();
    
    acc.ReadingChanged +=
        new EventHandler<AccelerometerReadingEventArgs>(acc_ReadingChanged);
    
    acc.Start();
    
  7. Добавьте сразу после метода Initialise следующий код для определения обработчика события акселерометра:
    Vector3 accVector = Vector3.Zero;
    
    void acc_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
    {
        accVector.X = (float)e.X;
        accVector.Y = (float)e.Y;
        accVector.Z = (float)e.Z;
    }
    
    Для управления движением шарика можно использовать значения, получаемые от акселерометра и сохраняемые в переменную accVector. Переменные bubbleX и bubbleY содержат координаты шарика, когда он находится в центре экрана.
  8. В методе Update удалите следующие строки кода:
    bubbleRectangle.X = (int)(bubbleX + 0.5f);
    bubbleRectangle.Y = (int)(bubbleY + 0.5f);
    
    и добавьте код для вычисления новых координат шарика, в которые он будет перемещаться:
    float accBubbleX = bubbleX - (accVector.X * 200);
    float accBubbleY = bubbleY + (accVector.Y * 200);
    
    bubbleRectangle.X = (int)(accBubbleX + 0.5f);
    bubbleRectangle.Y = (int)(accBubbleY + 0.5f);
    
  9. Запустите программу и проверьте правильность её работы.