Elite Games - Свобода среди звезд!

Уроки для программистов - Классы Game и GraphicsDeviceManager

Так... На чём мы остановились? Ну да, ну да... На GraphicsDevice.

Ну вроде бы пора делать первые свершения, ну там, с 3d побаловаться... Но нет. Рано ещё! Наберитесь терпения.

Прежде чем заниматься серьёзными делами, нужно оглянуться назад и посмотреть на то, что уже сделано.

И что же сделано? В предыдущем уроке мы создали окно при загрузке которого инициализируется графическое устройство, а рендеринг идёт в обработчике события Paint. Не слишком ли приметивно? Нет, ну так оставлять — это свинство. Какой выход? Можно, конечно написать свои классы организации игрового цикла, но зачем? Ведь есть класс...

Game

Находится в пространстве имён Microsoft.XNA.Framework Основная задача этого класса — облегчить нам жизнь. Сам класс Game в чистом виде не может нам чем-либо помочь. Но вот если мы унаследуем свой класс от класса Game...

Что бы разобраться в использовании класса Game нужно сначала разобраться в его возможностях.

И так... Что нам даёт наследование своего класса от класса Game. Всё довольно просто. У нас появляется возможность перекрыть ряд защищённых методов, которые будут нам очень полезны.

Если кому-то что-то не понятно из терминологии программирования, то извините — я пока не пишу статьи по ООП и C#. Базовые знания по этим двум темам у вас должны быть в обязательном порядка, если вы, конечно, хотите что-либо понять.

Так вот... Приведу эти полезные методы в таблице

Initialize()Метод вызывается автоматически после создания экземпляра класса (нашего класса) и графического устройства, но до загрузки контента. Как можно судить по названию, предназначен для инициализации игры, её параметров и всего что нужно инициализировать до начала игры и загрузки контента (модели, текустуры и тд. и тп.)
Draw(GameTime gameTime)Как видно из названия, этот метод вызывается при необходимости прорисовки изображения, при этом вызывается метод автоматически. То есть нам не нужно самим организовывать игровой цикл. Определённое количество раз в секунду (зависит от быстродействия машины и текущих настроек) просто будет вызываться метод Draw, а наша задача лишь написать что будет при этом происходить. А главное это справедливо как для тетриса, так и для игры с графикой уровня Crysis. И ещё одно... Вы заметили входной параметр метода? gameTime содержит информацию о том сколько времени прошло с момента последнего вызова метода Draw. Чем не хорошее подспорье для счётчика кадров?
Update(GameTime gameTime)Та же самая ситуация, что и с Draw... Но теперь метод предназначен для обновления состояния игры. Если приводить примеры, то это может быть просчёт физики, взаимодействие с пользователем (обработка устройств ввода), просчёт ИИ и тд.


Пока остановимся на этих трёх методах. Хотя ещё стоит упомянуть вскользь такие методы, как LoadContent, UnLoadContent и другие. Они тоже очень полезны, но не всё сразу. Они буду рассмотрены по мере надобности.

Так же стоит обратить внимания на события, доступные в классе Game

ActivatedСобытие, возникающее при переходе фокуса на игры (например, игрок перешёл игру после сворачивания последней. Можно отключить паузу и дать игроку наслаждаться вашим шедевром дальше
DeactivatedСобытие, возникающее при потери фокуса игрой (например, игрок свернул приложение). Отличный способ поставить паузу
ExitingПо названию понятно, что это событие возникает при попытке выйти из игры. Это даёт возможность уладить все дела игре (написать завещание, например)


Что ж, разобрались с необходимыми возможностями. Пора бы и переделать пример из предыдущего урока.

Инициализацию устройства переносим в метод Initialize
Прорисовку переносим в метод Draw
А вот в метод Update запишем изменение цвета окна.

Color color;

protected override void Update(GameTime gameTime)
{
Random rand = new Random();
color = new Color((byte)rand.Next(255), (byte)rand.Next(255), (byte)rand.Next(255));
}


Всё хорошо и красиво, но как запустить игру?

И опять всё элементарно вызов матода Run() класса Game, а точнее нашего класса, наследованного от Game.

Ну вот... Все цвета радуги.

Но это ещё не всё...

Инициализировать GrapicsDevice напрямую покажется не всем хорошей затеей. И действительно, попробуйте установить какое-то совершенно не подходящее разрешение (1023х769, например). Приехали... Вылетело исключение. К тому же изменение настроек на лету — тоже не самая тривиальная задача.

На этот случай имеется класс GraphicsDeviceManager

Для чего служит этот класс. Всё опять не сложно. При создании экземпляра этого класса мы указываем каким классом, наследованным от Game будет опекаться менеджер

new GraphicsDeviceManager(Game game);

После этого мы задаём желаемые настройки. После чего вызываем метод ApplyChanges(). В случае, если эти настройки могут быть применимы — они вступают в силу, иначе подбираются максимально близкие по значению настройки системы и применяются именно они. И вот вместо исключения мы получаем всего лишь немного отличный от желаемого режим работы.

Мы ещё не раз вернёмся к этим двум классам в следующих уроках.

А пока всё. Исходники примера к этому уроку можно найти тут.
Lefi Mind
К началу раздела | Наверх страницы Сообщить об ошибке
Уроки для программистов - Классы Game и GraphicsDeviceManager
Все документы раздела: Для тех, кто хочет писать игры | Движок на OpenGL | Создание игр в Game Maker | Bump mapping | Использование Direct Input | XNA framework |


Дизайн Elite Games V5 beta.18
EGM Elite Games Manager v5.17 02.05.2010