• Games
  • TMNT
  • Игры
  • Игры
Главная
Всё для геймера: Обзоры игр, Игровые новости, Читы, Советы и пр.
Всё о компьютерных и консольных играх.
Приветствую Вас Гость
Меню геймера
Разделы каталога
Общие игровые статьи [16]
Игровая аналитика, обзоры серий игр с разных платформ, анализ игр, игровой индустрии и т.д.
Онлайн игры [59]
Статьи и обзоры онлайновых клиентских и браузерных игр
Флэш игры/Flash [11]
2D/3D игры любого жанра на технологии Adobe Flash для игры в плеере или в браузере.
Браузерные онлайн-игры [53]
Браузере игры разных жанров и типов, индивидуальные, а также для социальных сетей и пр.
Разработка игр [41]
Создание игр, программирование, игровые движки, Языки программирования
Моддинг [1]
Модификация игр, перевод, локализация, русификация, ромхакинг
Эмуляция [3]
Эмуляторы и эмуляция компьютеров, консолей, игровых автоматов и прочих систем
Игровые фанфики [1]
Художественная игровая литература, творчество поклонников игр, игровых систем и платформ.
Настольные игры и игрушки [4]
Настольные игры, карточные игры, игрушки и сувениры
Опрос геймеров
Сколько часов в сутки вы играете в игры?
Всего ответов: 13941
Главная » Статьи » Игровые статьи » Разработка игр

Работа с джойстиком [Xbox 360]
Работа с джойстиком

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

К Xbox 360 можно подключить клавиатуру, а в играх есть возможность использовать соответствующий код, но вряд ли пользователь захочет играть в игру на клавиатуре вместо джойстика.

В первом разделе этой главы мы отвлечемся от создания игры и остановимся на изучении работы с джойстиком. В двух оставшихся разделах главы рассматриваются два проекта – Platform и PauseGame. В первом проекте под названием Platform в игру добавится ковер-самолет, который будет ловить объекты, падающие с неба. Для движения ковра-самолета влево или вправо используется джойстик. Само название проекта Platform было взято из второй (или первой) книги по XNA Game Studio Express.
Второй проект этой главы PauseGame реализует механизм паузы в игре. Требования к этому механизму чрезвычайно просты: необходимо по нажатии одной из кнопок джойстика сначала остановить работу игры, а потом по нажатии все той же кнопки запустить игру вновь. При этом игра должна продолжать работать именно с того места, на котором была остановлена.

9.1. Кнопки и рычаги джойстика

На джойстике приставки Xbox 360 имеется определенный набор кнопок и рычажков. Посмотрите на рис. 9.1, на котором представлена передняя часть джойстика.
С правой стороны джойстика располагаются четыре кнопки с буквами A, B, X, Y. Эти кнопки с буквами используются для назначения на них различных команд.
Например, кнопка с буквой А очень часто выполняет роль компьютерной клави ши Enter. Все четыре кнопки можно использовать в меню игры, где вы можете арисовать красочное руководство пользователя и написать игроку, например, следующее:

Рис. 9.1. Передняя часть джойстика

Для возврата в главное меню нажмите кнопку B

или

Нажмите кнопку А для начала игры

За годы существования приставок Xbox и Xbox 360 выработались определенные правила, которые в какой-то мере регулируют назначение тех или иных кнопок на определенные команды. Если вы позапускаете на приставке несколько различных игр, то поймете, о чем идет речь.
Кроме четырех кнопок с буквами, джойстик имеет кнопки Back, Start и так называемую кнопку Xbox Guide (большая круглая кнопка в центре джойстика с цифрами 1, 2, 3 и 4). Кнопки Back и Start могут назначаться соответственно на возврат в предыдущее окно программы и для старта игры. Кнопка Xbox Guide вызывает основное меню приставки, а также запускает или выключает консоль.
Вам как программисту эта кнопка не доступна для назначения на нее различных команд.
На джойстике также располагаются два рычажка и большая круглая полукнопка-полурычажок, которая в чем-то аналогична клавишам компьютерной клавиатуры со стрелочками, или командами Вверх, Вниз, Влево и Вправо. Два рычага применяются для управления главным персонажем игры, или если это меню, то возможно их использование в переходе по командам меню. В меню также можно использовать тот самый полурычажок-полукнопку.
Два рычажка при управлении главным персонажем игры делят между собой две функции. Рычаг на джойстике, который находится с левой стороны (он и называется левым рычагом), служит для передвижения героя по игровой местности.
Рычажок, который находится на джойстике несколько правее относительно первого рычага, чаще всего представляет в играх камеру или глаза, голову главного героя, которая поворачивается и смотрит в разные стороны (вверх, вниз, влево, вправо…).
Дополнительно у джойстика имеются еще четыре кнопки, на рис. 9.1 они не попадают в наше поле зрения. На назначении этих кнопок мы остановимся подробнее в конце этого раздела. Как видите, кнопок и рычагов на джойстике хватает. Чтобы программисту было легче работать с имеющимися элементами управления, все кнопки и рычаги джойстика были рассортированы по категориям. Посмотрите на рис. 9.2, где показано устройство джойстика с точки зрения программиста.


Рис. 9.2. Устройство джойстика с точки зрения программиста

Названия на рис. 9.2, приведенные для кнопок и рычагов, – это на самом деле названия структур в XNA Framework, с помощью которых программист должен управлять работой джойстика. Как видно из этого рисунка, в XNA Faramework имеются следующие структуры:
* GamePadButtons – большинство кнопок джойстика попадают в юрисдикцию этой структуры. С помощью этой структуры можно определять нажатие и отпускание одной из кнопок джойстика;
* GamePadDPad – это та самая полукнопка-полурычажок;
* GamePadTriggers – две кнопки (левая и правая), похожие на спусковой механизм оружия, которые, как правило, для этих и подобных целей и используются;
* GamePadThumbSticks – это два рычажка (левый и правый) для управления движением главного героя и камерой.
Очевидно, что для получения событий с джойстика нам необходимо его постоянно опрашивать, или следить за тем, что пользователь делает с элементами управления. Для этих целей в XNA используется следующая конструкция кода, которая должна прямо или косвенно вызываться в игровом цикле.

GamePadState currentState = GamePad.GetState(PlayerIndex.One);

В этой строке кода создается объект currentState структуры GamePadState, который в каждый такт игры обновляет свое состояние с помощью метода GetState() класса GamePad. Таким образом, мы получаем возможность постоянно следить за всеми элементами управления джойстика непосредственно в игровом цикле или каждую долю секунды игры.
В методе GetState() используется параметр PlayerIndex.One. Этот параметр
назначает, к какому именно из джойстиков принадлежит объект currentState или какой из джойстиков в данный момент мы контролируем. В Xbox 360 вы можете одновременно подключить до четырех джойстиков, то есть одновременно в игре могут участвовать сразу четыре игрока. Соответственно в коде нам необходим механизм прослушивания каждого из четырех джойстиков.
Если вы хотите создать в игре механизм прослушивания четырех джойстиков, то можно записать следующий блок кода:

GamePadState currentState1 = GamePad.GetState(PlayerIndex.One);
GamePadState currentState2 = GamePad.GetState(PlayerIndex.Two);
GamePadState currentState3 = GamePad.GetState(PlayerIndex.Thre);
GamePadState currentState4 = GamePad.GetState(PlayerIndex.Four);

Думается, тут все ясно: PlayerIndex в каждом новом вызове имеет новый индекс, который соответствует англоязычному исчислению; один, два, три и четыре. Если вы в игре используете только один джойстик, то всегда необходимо начинать с первого индекса. Нельзя вызывать второй или третий джойстик без вызова первого, а точнее можно, но если к приставке подключен только один джойстик, то он по умолчанию PlayerIndex.One.
В следующих подразделах рассматриваются способы работы с элементами управления джойстика. На диске в папке Chapter9\GamePadControl вы найдете проект, который показывает на практике работу всех кнопок и рычажков джойстика. В этом проекте я вывел на экран телевизора пять спрайтов. Каждый спрайт выполнен в виде таблички с названием той или иной структуры. Нажимая кнопки или двигая рычаги джойстика, вы в программе по экрану этими действиями будете перемещать таблички с соответствующими названиями. Изучите следующие четыре подраздела, а потом запустите этот проект на приставке.

9.1.1. GamePadButtons

Структура GamePadButtons позволяет определить, нажата кнопка или опущена. Если вы хотите определить, нажата кнопка или нет, то используется следующая запись:

if(currentState.Buttons.A == ButtonState.Pressed)
// заданные события

Эта строка кода предназначена для кнопки с буквой А. Если вам нужно опре-
делить, отпущена ранее нажатая кнопка А или нет, то необходимо использовать
другую конструкцию кода:

if(currentState.Buttons.A == ButtonState.Released)
// заданные события

В этой строке происходит уже проверка на отпускание нажатой ранее кнопки.
Далее перечислены все имеющиеся кнопки структуры GamePadButton. Запус-
тите с диска проект GamePadControl и убедитесь, что вы понимаете, о каких
именно кнопках идет речь.

if(currentState.Buttons.A == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.B == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.X == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.Y == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.Back == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.Start == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.LeftShoulder == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.RightShoulder == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.LeftStick == ButtonState.Pressed)
// заданные события
if(currentState.Buttons.RightStick == ButtonState.Pressed)
// заданные события

9.1.2. GamePadDPad
Часто структуру GamePadDPad используют для перехода по меню или для других
подобных операций. Как и в предыдущем разделе, вы можете определять для
GamePadDPad как нажатие в одну из сторон, так и отпускание нажатия.
В GamePadDPad всего имеются четыре направления: влево, вправо, вверх и вниз,
которые соответствуют одноименным английским командам.

if(currentState.DPad.Left == ButtonState.Pressed)
// заданные события
if(currentState.DPad.Right == ButtonState.Pressed)
// заданные события
if(currentState.DPad.Up == ButtonState.Pressed)
// заданные события
if(currentState.DPad.Down == ButtonState.Pressed)
// заданные события

9.1.3. GamePadTriggers

Структура GamePadTriggers представляет две кнопки (левую и правую), похожие на спусковой механизм оружия (рис. 9.2). Механизм получения событий с этих двух кнопок может на первый взгляд показаться необычным. Посмотрите на блок кода, приведенный ниже.

if(currentState.Triggers.Left > 0.1f)
// заданные события
if(currentState.Triggers.Right > 0.9f)
// заданные события

Все станет на свои места, когда вы поймете механизм работы этих кнопок. Возьмем, к примеру, игру Need for Speed. В этой игре на правую кнопку Triggers.Right назначен акселератор, или, как мы говорим, педаль газа в машине. В машине степень нажатия на эту педаль может определять степень разгона или текущую скорость машины на дороге. Более того, у каждой машины свои возможности при разгоне. Одна машина может стартовать быстрее и за несколько секунд набрать большую скорость, другая, наоборот, набирает скорость медленнее. Так вот, принцип работы этих двух кнопок джойстика сводится к определению степени нажатия на эту самую кнопку. Для сравнения степени нажатия используются значения в пределах от –1.0f до 1.0f.
В блоке кода в первой строке для левой кнопки Triggers.Left было определено значение больше 0.1 f. В этом случае малейшее прикосновение к этой кнопке инициирует действия, которые заданы на выполнение этой команды. Во втором случае, где

if (currentState.Triggers.Right > 0.9f)

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

9.1.4. GamePadThumbSticks

Структура GamePadThumbSticks основана на том же принципе работы, что и рассмотренная выше структура GamePadTriggers, с той лишь разницей, что используются не кнопки джойстика, а рычаги. Поскольку у джойстика два рычага, то имеются два способа записи – ThumbSticks.Left и ThumbSticks.Right.
Дополнительно вы можете определять, в какую из сторон, или в какую часть плоскости координатной системы, перемещать своего главного героя, например ThumbSticks.Left.X или ThumbSticks.Left.Y.
Для рычажков степень нажатия в одну из сторон – не менее важная часть, как и для кнопок. Если, например, назначить на вращение камеры значение 0.99f, то камера будет медленно и несколько заторможенно реагировать на нажатие рычага джойстика. Если назначить значение 0.1f, то скорость реакции будет очень быстрой.
В следующем примере дается блок кода для левого рычага ThumbSticks.Left.

if(currentState.ThumbSticks.Left.X < -0.3f)
// заданные события
if(currentState.ThumbSticks.Left.X > 0.3f)
// заданные события
if(currentState.ThumbSticks.Left.Y > 0.3f)
// заданные события
if(currentState.ThumbSticks.Left.Y < -0.3f)
// заданные события

Для правого рычажка джойстика ThumbSticks.Right конструкция кода
аналогична.

if(currentState.ThumbSticks.Right.X < -0.9f)
// заданные события
if(currentState.ThumbSticks.Right.X > 0.9f)
// заданные события
if(currentState.ThumbSticks.Right.Y > 0.9f)
// заданные события
if(currentState.ThumbSticks.Right.Y < -0.9f)
// заданные события

Заметьте, что для определения степени нажатия правого рычажка используется значение 0.9f, которое в три раза больше, чем значение 0.3f для левого рычага.
Сделано это было специально. Запустите с диска пример GamePadControl и посмотрите, как отличаются между собой в управлении два рычага по степени нажатия и реакции на действия пользователя.
В играх, где очень важно быстро реагировать на изменение игровых событий, нельзя выбирать слишком большие значения для сравнения степени нажатия рычагов. Но, с другой стороны, слишком маленькое значение может помешать установить точно, например, прицел на врага. К выбору сравниваемых значений нужно подходить очень осторожно!

9.2. Проект Platform

По задумке, в нашей игре мы обязаны ловить всех людей, падающих с неба в пропасть, с помощью ковра-самолета. Дополнительно с неба, кроме людей, также падают различные запчасти сгоревшего самолета, и от этих частей нам необходимо уворачиваться. Ковер-самолет находится в нижней части экрана и парит горизонтально на одном уровне. Чтобы управлять ковром-самолетом, нам необходимо использовать джойстик приставки Xbox 360.
Изображение ковра-самолета состоит из одного фрейма, а это значит, что применяется неанимированный спрайт (рис. 9.3). Сам рисунок располагается в рабочем каталоге проекта в папках Content\Textures, а механизм добавления графического изображения в проект остается прежним.

Рис. 9.3. Ковер/самолет

Начнем работу над проектом Platform и добавим в исходный код класса Game1 в область глобальных переменных объявление нового объекта platform класса Sprite.

Sprite platform;

Объект platform не будет анимированным, поэтому при создании объекта используется неанимированный конструктор класса Sprite.

platform = new Sprite();

Затем в методе LoadGraphicsContent() класса Sprite происходит загрузка изображения ковра-самолета в игру.

platform.Load(content, «Content\\Textures\\platform»);

Далее ковру-самолету в методе Initialize() класса Sprite задается позиция на экране телевизора.

platform.spritePosition = new Vector2(screenWidth / 2, screenHeight - 90);

По осям X и Y выбирается место примерно посередине экрана и в его нижней части, но в целом это положение по оси Х может быть любым.
Для реализации движения ковра-самолета на экране в классе Game1 создается метод MovePlatform(), код которого выглядит следующим образом:

public void MovePlatform()
{
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
if (currentState.IsConnected)
{
if (currentState.ThumbSticks.Left.X < -0.5f)
platform.spritePosition.X -= 15;
else if (currentState.ThumbSticks.Left.X > 0.5f)
platform.spritePosition.X += 15;
if (platform.spritePosition.X < 30)
platform.spritePosition.X = 30;
else if (platform.spritePosition.X > screenWidth –
platform.spriteTexture.Width -30)
platform.spritePosition.X = screenWidth –
platform.spriteTexture.Width – 30;}
}

В начале исходного кода метода MovePlatform() мы создаем новый объект currentState структуры GamePadState для получения текущего состояния джойстика. Метод GetState() в качестве параметра получает значение PlayerIndex.One, что означает получение событий с одного, а точнее с первого подключенного джойстика к приставке. Как вы помните, к приставке можно подключить одновременно четыре джойстика, но какой бы по счету лично для вас джойстик ни был, всегда первый подключенный джойстик к приставке идет под индексом PlayerIndex.One, второй – под индексом PlayerIndex.Two, третий – PlayerIndex.Three и четвертый – PlayerIndex.Four. Здесь важна очередность подключения джойстиков к приставке.
Затем в методе MovePlatform() следует строка кода.

if(currentState.IsConnected)

Эта простейшая конструкция кода позволяет определить, подключен джойстик к приставке или нет. Своего рода подстраховка для системы, на случай если джойстик по каким-то причинам отключится от приставки, но код будет работать и без этой проверочной строки.
Оставшаяся часть кода метода MovePlatform() состоит из двух независимых блоков исходного кода. В первом блоке происходит обработка нажатий левого рычажка GamePadThumbSticks.Left влево и вправо. Для обработки получаемых событий используется конструкция кода if/else. В переводе на русский язык эта конструкция кода обозначает следующее:

Если GamePadThumbSticks.Left нажат в левую сторону, то:
Позиция ковра-самолета по оси Х уменьшается на 10 пикселей
А если GamePadThumbSticks.Left нажат в правую сторону, то:
Позиция ковра-самолета по оси Х увеличивается на 10 пикселей

Уменьшение или увеличение позиции по оси X приводит к движению коврасамолета по горизонтали влево и вправо. Заданная скорость в размере 10 пикселей за один кадр тестировалась много раз и оказалась наиболее удачным значением.
Второй блок исходного кода обрабатывает ситуацию выхода ковра-самолета за пределы экрана с левой и правой сторон. Если такое условие имеет место, то по оси X спрайту присваивается значение, равное соответственно левой или правой кромке экрана + 30 пикселей (для красоты). В этом случае спрайт при столкновении с двумя крайними точками экрана остается на месте без движения. Делается это для того, чтобы ковер не уезжал из нашей области видимости и все время оставался на экране.
Метод MovePlatform() вызывается в методе Update() класса Game1, где происходит постоянное обновление состояния игры. В конце исходного кода класса Game1 в методе Draw() ковер-самолет рисуется на экране. Полный исходный код класса Game1 представлен в листинге 9.1. На компакт-диске рассмотренный пример находится в папке Code\Chapter9\ Platform.

//=========================================================================
///


/// Листинг 9.1
/// «Программирование игр для приставки Xbox 360 в XNA Game Studio Express»
/// Автор книги: Горнаков С. Г.
/// Глава 9
/// Проект: Platform
/// Класс: Game1
/// Добавляем ковер-самолет
///

//=========================================================================
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
namespace Platform
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;
SpriteBatch spriteBatch;
Sprite[] sprite = new Sprite[5];
private Texture2D background;
Random rand = new Random();
int screenWidth, screenHeight;
int j = 0;
Sprite platform;
///

/// Конструктор
///

public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
screenWidth = graphics.PreferredBackBufferWidth;
screenHeight = graphics.PreferredBackBufferHeight;
for (int i = 0; sprite.Length > i; i++)
{
sprite[i] = new Sprite(12, 10);
}
platform = new Sprite();
}
///

/// Инициализация
///

protected override void Initialize()
{
j = 0;
for (int i = 0; sprite.Length > i; i++)
{
sprite[i].spritePosition = new Vector2(rand.Next(10, screenWidth - 150),
j = j - 300);
}
platform.spritePosition = new Vector2(screenWidth / 2, screenHeight - 90);
base.Initialize();
}
///

/// Загрузка компонентов игры
///

protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
background = content.Load(«Content\\Textures\\background»);
platform.Load(content, «Content\\Textures\\platform»);
sprite[0].Load(content, «Content\\Textures\\0»);
sprite[1].Load(content, «Content\\Textures\\1»);
sprite[2].Load(content, «Content\\Textures\\2»);
sprite[3].Load(content, «Content\\Textures\\3»);
sprite[4].Load(content, «Content\\Textures\\4»);
}
}
///

/// Освобождаем ресурсы
///
protected override void UnloadGraphicsContent(bool unloadAllContent)
{

}
///
/// Обновляем состояние игры
///
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
double elapsed = gameTime.ElapsedGameTime.TotalSeconds;
for (int i = 0; sprite.Length > i; i++)
{
sprite[i].UpdateFrame(elapsed);
}
MovePlatform();
MoveSprite();
base.Update(gameTime);
}
///
/// Движение спрайта по вертикали
///
public void MoveSprite()
{
for (int i = 0; sprite.Length > i; i++)
{
sprite[i].spritePosition += sprite[i].speedSprite;
if (sprite[i].spritePosition.Y > screenHeight)
{
sprite[i].spritePosition = new Vector2(rand.Next(50,
screenWidth -
sprite[i].spriteTexture.Width / 12 - 50), -500);
}
}
}
///
/// Движение ковра-самолета по экрану
///
public void MovePlatform()
{
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
if (currentState.IsConnected)
{
if (currentState.ThumbSticks.Left.X < -0.5f)
platform.spritePosition.X -= 15;
else if (currentState.ThumbSticks.Left.X > 0.5f)
platform.spritePosition.X += 15;
if (platform.spritePosition.X < 30)
platform.spritePosition.X = 30;
else if (platform.spritePosition.X > screenWidth –
platform.spriteTexture.Width -30)
platform.spritePosition.X = screenWidth –
platform.spriteTexture.Width – 30;
}
}
///
/// Рисуем на экране
///
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(background, new Vector2(0, 0), Color.White);
for (int i = 0; sprite.Length > i; i++)
{
sprite[i].DrawAnimationSprite(spriteBatch);
}
platform.DrawSprite(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}

После того как вы откомпилируете и запустите проект Platform на приставке, вы увидите в нижней части экрана телевизора или монитора ковер-самолет, который с помощью джойстика можно передвигать влево или вправо (рис. 9.4). С неба будут падать различные предметы и люди, которые вы должны ловить ковром, но на этом этапе, естественно, поймать вам ничего и никого не удастся, поскольку в игре еще не описан механизм игровых столкновений. Этим мы займемся в следующей главе, а в этой главе добавим еще несколько строк кода для того, чтобы реализовать в игре режим паузы.

9.3. Проект PauseGame

Вводим в проект PauseGame две новые булевы переменные, объявление которых происходит в области глобальных переменных, чтобы переменные были доступны на любом участке исходного кода класса Game1.

Рис. 9.4. Движение ковра/самолета в игре

private bool paused = false;
private bool pauseKeyDown = false;

Эти две переменные будут отражать соответственно состояние паузы в игровом процессе и состояние нажатия заданной кнопки джойстика. На каждой новой итерации игрового цикла (метод Update()) мы будем опрашивать джойстик и узнавать, нажата определенная кнопка или нет. Для паузы избрана стандартная в этом случае кнопка с адписью «Start». Чаще всего в консольных играх на эту кнопку назначают паузу, после чего появляется дополнительное меню, через которое можно выйти в меню игры, настроить опции игры или вернуться снова в игровой процесс.
Если кнопка с надписью «Start» нажата, то в исходном коде переменной paused присваивается значение true. В этом случае создается код на проверку условия, чему именно равна переменная paused, и если ее значение равно true, то, значит, выполнение игрового цикла пропускается, если false – то игра продолжает свою работу (рис. 9.5). Посмотрите на исходный код класса Game1 проекта PauseGame в листинге 9.2.


Рис. 9.5. Схема работы паузы в игре

//=========================================================================
///


/// Листинг 9.2
/// Исходный код к книге:
/// «Программирование игр для приставки Xbox 360 в XNA Game Studio Express»
/// Автор книги: Горнаков С. Г.
/// Глава 9
/// Проект: PauseGame
/// Класс: Game1
/// Пауза в игре
///

//=========================================================================
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
namespace PauseGame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;
SpriteBatch spriteBatch;
Sprite[] sprite = new Sprite[5];
private Texture2D background;
Random rand = new Random();
int screenWidth, screenHeight;
int j = 0;
Sprite platform;
private bool paused = false;
private bool pauseKeyDown = false;
///

/// Конструктор
///

public Game1()
{

}
///

/// Инициализация
///
protected override void Initialize()
{

}
///

/// Загрузка компонентов игры
///

protected override void LoadGraphicsContent(bool loadAllContent)
{

}
///

/// Освобождаем ресурсы
///
protected override void UnloadGraphicsContent(bool unloadAllContent)
{

}
///
/// Обновляем состояние игры
///
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
Pause();
if (paused == false)
{
double elapsed = gameTime.ElapsedGameTime.TotalSeconds;
for (int i = 0; sprite.Length > i; i++)
{
sprite[i].UpdateFrame(elapsed);
}
MoveSprite();
MovePlatform();
}
base.Update(gameTime);
}
///
/// Движение спрайта по вертикали
///
public void MoveSprite()
{

}
///
/// Движение платформы по экрану
///
public void MovePlatform()
{

}
///
/// Пауза в игре
///
public void Pause()
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Start == ButtonState.Pressed)
{
pauseKeyDown = true;
}
else if (pauseKeyDown)
{
pauseKeyDown = false;
paused = !paused;
}
}
///
/// Рисуем на экране
///
protected override void Draw(GameTime gameTime)
{

}

Из блока кода, направленного на обработку паузы в состоянии игры, видно, что мы сначала определяем состояние переменной paused, и если ее значение равно false (нет паузы), то выполняется содержимое блока if. Если состояние булевой переменной paused изменилось на true (пауза в игре), то выполнение блока if пропускается, что равносильно необновлению состояния игры, то есть игра замирает.
Чтобы выйти из этого состояния, достаточно второй раз нажать кнопку «Start» и в соответствии с исходным кодом метода Pause() значение булевой переменной paused изменяется на противоположное значение. Заметьте, что вызов метода Pause() в методе Update() совершается до строки кода выхода из программы.

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

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

Категория: Разработка игр | Добавил: G-GURU (22.04.2011)
Просмотров: 33172 | Рейтинг: 3.6/5 |
Вы можете отправить сообщение на e-mail друга:

Интересное геймерам:

Смотрите другие материалы по темам: C++, C#, XNA, Xbox, game, Разработка игр, 360, Xbox 360, XNA Game Studio, joypad.

Также вам предлагаются схожие с «Работа с джойстиком [Xbox 360]» материалы:

Если понравился материал «Работа с джойстиком [Xbox 360]» и вы можете обсудить его ниже.

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск информации
Игровые братья
Создание игр, Конструкторы игр, Игровые движки Перевод консольных игр Скачать файлы: софт, видео Игорный бизнес в России Разработка игр в СНГ Пранк - телефонные шутки
10 новых описаний
Hello, Neighbour
Как провести время на конференции наиболее эффективно
WarCraft Adventures: Lord of the Clans
Во что я люблю играть – гоняю эмуляторы!
Империю Онлайн 2: Халифат
Купля-продажа аккаунтов MMOG
Инди-игрострой почти мёртв
Hearthstone - игра от создателей легендарного Warcraft
Моё знакомство с играми в жанре квест
Картридж 500 in 1 для Dendy / Famicom
Все права сохранены за сайтом GFAQ.ru © 2016. Games Frequently Asked Questions
Полные прохождения, Секреты, Коды, Пароли, Советы, Уловки, Читы, Описания для Компьютерных и Консольных Игр. Хостинг от uCoz
Обращаем особое внимание на то, что при цитировании и размещении данных текстовых материалов, обязательно прикрепляйте ссылку на официальный сайт "GFAQ.ru".