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

Работа с джойстиком [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)
Просмотров: 40642 | Рейтинг: 3.6/5 |
Вы можете отправить сообщение на e-mail друга:

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

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

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

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

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск информации
Игровые братья
Создание игр, Конструкторы игр, Игровые движки Перевод консольных игр Разработка игр в СНГ Пранк - телефонные шутки
10 новых описаний
Satan Claus [SMD]
Покупка купонов, игровых валют для Nintendo Switch, Twitch и пр.
Краткий обзор популярной онлайн игры Palworld
Увеличьте доходы от рекламы с помощью оптимизации контента
Для чего вам нужен виртуальный номер телефона
Обзор новой экшен РПГ «Zenless Zone Zero» от miHoYo
Игра «Alien Fish Finger» v1.31 на Amiga
Обзор смартфона Xiaomi 14
Игровая индустрия ориентируется уже на всех
Где покупать и/или продавать свои скины CS2, Dota 2, RUST?
Повысьте качество обслуживания пользователей и прибыль
Решающее значение для сайта - Domain Authority (DA)
Компания MAN-MADE показала компьютер, вдохновленный игрой «Метро 2033»
Почему ПО для колл-центров востребовано компаниями
Сколько стоит предметная съёмка товаров для интернет-магазина
Все права сохранены за сайтом GFAQ.ru © 2024. Games Frequently Asked Questions
Полные прохождения, Секреты, Коды, Пароли, Советы, Уловки, Читы, Описания для Компьютерных и Консольных Игр. Хостинг от uCoz
Обращаем особое внимание на то, что при цитировании и размещении данных текстовых материалов, обязательно прикрепляйте ссылку на официальный сайт "GFAQ.ru".