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

Введение в XNA, знакомство с проектом, первое приложение

7.2. Разбор кода стандартного игрового проекта

В листинге 7.1 приведено содержимое файла Program.cs.

using System;

namespace P2_1
{
#if WINDOWS || XBOX
    static class Program
    {
        /// <summary>
        /// Главная точка входа приложения.
        /// </summary>
        static void Main(string[] args)
        {
            using (Game1 game = new Game1())
            {
                game.Run()>;
            }
        }
    }
#endif
}
Листинг 7.1. Код файла Program.cs

Этот файл применяется для запуска игры в том случае, если она разрабатывается для платформ Xbox или Windows, при запуске на Windows Phone данный файл не используется.

Второй программный файл, Game1.cs, представляет собой игровой проект, который и содержит все то, что используется при создании игры. Естественно, в сложных игровых проектах основная часть кода выносится за пределы данного файла, но он, в любом случае, является центром игры.

Упрощенно структуру игрового проекта можно представить так (Табл. 7.1.).

Таблица 7.1. Структура игрового проекта
Название Описание
Инициализация На этапе инициализации проекта проводится инициализация графической и звуковых подсистем, системы ввода данных.
Загрузка ресурсов Здесь загружаются игровые ресурсы, такие, как текстуры и трехмерные модели, звуки, шрифты
Начало игрового цикла Основные действия, которые выполняются при работе игры, организованы в виде игрового цикла. Фактически, игровой цикл – это обязательный элемент любой игры.
Считывание данных пользовательского ввода Пользователь управляет игрой с помощью различных устройств ввода данных. В нашем случае это – сенсорный экран смартфона и различные датчики.
Игровые вычисления Игровые вычисления включают в себя все вычисления, которые необходимы для организации игрового процесса. В частности, здесь обсчитываются позиции игровых объектов, проводятся вычисления, связанные с работой искусственного интеллекта, вычисления, связанные с проверкой столкновений игровых объектов, игровая физика, подсчет очков, набранных игроком и так далее. Если речь идет об оптимизации быстродействия игры, то такая оптимизация обычно касается именно игровых вычислений, так как на них тратится большая часть времени выполнения игрового цикла.
Проверка критерия прекращения игры Игровой цикл продолжается до тех пор, пока игра не будет прекращена. Например, критерием останова может быть истечение времени, выделенного игроку на выполнение игровой задачи, набор определенного количества очков, какое-то событие, произошедшее в процессе игры, принудительная остановка игры, если пользователь решил прекратить играть и так далее.
Вывод изображений, проигрывание звуков После завершения этапа игровых вычислений в программе имеются данные для визуализации. В частности, имеются данные о новых позициях объектов, о сообщениях, которые нужно вывести на игровое поле, о звуках, которые нужно воспроизвести. На данном этапе проводится перемещение объектов по игровому полю, вывод сообщений, проигрывание звука.
Конец игрового цикла Игровой цикл заканчивается после выполнения условия останова игры
Освобождение ресурсов На последнем этапе работы игры проводится освобождение системных ресурсов, занятых игрой и выход из игры.

В стандартном игровом проекте все эти этапы представлены с помощью специальных методов. Эти методы унаследованы созданным игровым проектом от класса Game, который служит основой для проекта. Итак, это следующие методы (табл. 7.2.).

Таблица 7.2. Методы стандартного игрового проекта
Название Описание
Game() Общая инициализация. Game() – это конструктор класса Game.
Initialize() Инициализация игры
LoadContent() Загрузка игровых ресурсов
Update() Игровой цикл в стандартном проекте состоит из двух методов. Первый из них – это метод Update(), в котором выполняется прием пользовательского ввода, все необходимые вычисления, проверка критериев останова игры.
Draw() Второй метод игрового цикла – это метод Draw(), который содержит код для визуализации игровой графики
UnloadContent() По окончании игрового цикла этот метод освобождает системные ресурсы.

Теперь, когда мы ознакомились с типичной структурой игры и назначением стандартных методов, рассмотрим код класса Game (Листинг 1.2). Помимо программного кода здесь приведены комментарии, включаемые в код автоматически.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace P2_1
{
    /// <summary>
    /// Это главный тип игры
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Дополнительный заряд аккумулятора заблокирован.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

        /// <summary>
        /// Позволяет игре выполнить инициализацию, необходимую перед запуском.
        /// Здесь можно запросить нужные службы и загрузить неграфический
        /// контент.  Вызов base.Initialize приведет к перебору всех компонентов и
        /// их инициализации.
        /// </summary>
        protected override void Initialize()
        {
            // ЗАДАЧА: добавьте здесь логику инициализации

            base.Initialize();
        }

        /// <summary>
        /// LoadContent будет вызываться в игре один раз; здесь загружается
        /// весь контент.
        /// </summary>
        protected override void LoadContent()
        {
            // Создайте новый SpriteBatch, который можно использовать для отрисовки текстур.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // ЗАДАЧА: используйте здесь this.Content для загрузки контента игры
        }

        /// <summary>
        /// UnloadContent будет вызываться в игре один раз; здесь выгружается
        /// весь контент.
        /// </summary>
        protected override void UnloadContent()
        {
            // ЗАДАЧА: выгрузите здесь весь контент, не относящийся к ContentManager
        }

        /// <summary>
        /// Позволяет игре запускать логику обновления мира,
        /// проверки столкновений, получения ввода и воспроизведения звуков.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Update(GameTime gameTime)
        {
            // Позволяет выйти из игры
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // ЗАДАЧА: добавьте здесь логику обновления

            base.Update(gameTime);
        }

        /// <summary>
        /// Вызывается, когда игра отрисовывается.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // ЗАДАЧА: добавьте здесь код отрисовки

            base.Draw(gameTime);
        }
    }
}
Листинг 7.2. Код файла Game1.cs

Рассмотрим каждый из приведенных выше методов. В листинге 7.3. приведен код метода Game1().

public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        
	public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Дополнительный заряд аккумулятора заблокирован.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }
Листинг 7.3. Код метода Game1()

В классе Game есть, по умолчанию, два поля. Это поле graphics, которое имеет тип GraphicsDeviceManager и представляет графические элементы, и поле spriteBatch с типом SpristeBatch, представляющее пакет спрайтов (изображений).

Метод Game() – это конструктор класса Game. Команда graphics = new GraphicsDeviceManager(this);

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

Команда Content.RootDirectory = "Content"; позволяет указать место (в нашем случае – это проект P2_1Content, или просто Content), где хранятся игровые ресурсы. Content.RootDirectory следует понимать как свойство Content (Содержимое) типа ContentManager (Диспетчер содержимого), RootDirectory (Корневой каталог) – это свойство данного класса.

Команда TargetElapsedTime = TimeSpan.FromTicks(333333); задает время игрового цикла, ориентируясь на частоту обновления экрана в устройствах на Windows Phone. Это – 30 кадров в секунду. Наш игровой цикл, таким образом, будет выполняться 30 раз в секунду.

Помимо описанных команд, автоматически включаемых в стандартный игровой проект, конструктор может содержать и другие команды. Например, команды дополнительной настройки объекта graphics.

После того, как создан экземпляр класса Game, вызывается метод этого класса Run, после чего выполняется инициализация игры, загрузка контента, запускается игровой цикл.

В листинге 7.4. приведен код метода Initialise().

protected override void Initialize()
        {
            // ЗАДАЧА: добавьте здесь логику инициализации

            base.Initialize();
        }
Листинг 7.4. Код метода initialise()

Команда base.Initialize(); вызывает метод Initialise() базового класса. Сюда же добавляют команды для инициализации звуковой подсистемы игры, здесь же выполняются игровые настройки. Надо отметить, что в этом методе инициализируется все, кроме графических ресурсов игры. Для них существует метод LoadContent(), листинг 7.5.

>protected override void LoadContent()
        {
            // Создайте новый SpriteBatch, который можно использовать для отрисовки текстур.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // ЗАДАЧА: используйте здесь this.Content для загрузки контента игры
        }
Листинг 7.5. Код метода LoadContent()

SpriteBatch – это класс, который позволяет выводить изображения на устройство, задаваемое параметром GraphicsDevice. В этот же метод добавляют команды для загрузки графических ресурсов, шрифтов. Метод UnloadContent() (листинг 7.6.) предназначен для освобождения системных ресурсов.

protected override void UnloadContent()
        {
            // ЗАДАЧА: выгрузите здесь весь контент, не относящийся к ContentManager
        }
Листинг 7.6. Код метода UnloadContent()

Здесь размещают команды для выгрузки игровых ресурсов. В частности, в данном методе можно использовать команду base.UnloadContent(); - это метод базового класса, выгружающий ресурсы. Так же в этот метод добавляют команды для выгрузки шрифтов и других ресурсов.

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