| netlib.narod.ru | < Назад | Оглавление | Далее > |
Все сцены созданы, и теперь нам надо только показывать их в соответствии с пожеланиями пользователя. Через меню в начальной сцене пользователь может посмотреть сцену помощи, сцену игры (с одним или двумя игроками), или просто покинуть игру. Здесь вы будете использовать технику в которой концентрируете весь ввод, относящийся к навигации или управлению состоянием сцен в одном классе. В данном случае вы используете класс Game1, чтобы у вас была центральная точка, где вы запускаете сцены и управляете состоянием класса Game1. Добавьте в класс Game1 следующий код:
private readonly GraphicsDeviceManager graphics; private SpriteBatch spriteBatch; // Текстуры protected Texture2D helpBackgroundTexture, helpForegroundTexture; protected Texture2D startBackgroundTexture, startElementsTexture; protected Texture2D actionElementsTexture, actionBackgroundTexture; // Игровые сцены protected HelpScene helpScene; protected StartScene startScene; protected ActionScene actionScene; protected GameScene activeScene; // Звуковые ресурсы private AudioComponent audioComponent; // Шрифты private SpriteFont smallFont, largeFont, scoreFont; // Используется для обработки ввода protected KeyboardState oldKeyboardState; protected GamePadState oldGamePadState;
В метод LoadContent добавьте код для создания и загрузки содержимого для объекта ActionScene:
// Создание сцены игры
actionElementsTexture = Content.Load<Texture2D>("rockrainenhanced");
actionBackgroundTexture = Content.Load<Texture2D>("SpaceBackground");
scoreFont = Content.Load<SpriteFont>("score");
actionScene = new ActionScene(this, actionElementsTexture,
actionBackgroundTexture, scoreFont);
Components.Add(actionScene);
// Запуск игры с начальной сцены :)
startScene.Show();
activeScene = startScene;
И снова в этом классе вы загружаете все игровые ресурсы и инициализируете все сцены, делая StartScene сценой, открываемой изначально.
Метод Update обрабатывает весь пользовательский ввод для каждой сцены и, если необходимо, меняет активную сцену:
/// <summary>
/// Позволяет игре выполнять логику, такую как обновление мира,
/// проверка столкновений, сбор ввода и воспроизведение звука
/// </summary>
/// <param name="gameTime">Предоставляет снимок значения таймера</param>
protected override void Update(GameTime gameTime)
{
// Обработка игрового ввода
HandleScenesInput();
base.Update(gameTime);
}
HandleScenesInput просто вызывает обработчик активной сцены игры:
/// <summary>
/// Обработка ввода всех игровых сцен
/// </summary>
private void HandleScenesInput()
{
// Обработка ввода начальной сцены
if (activeScene == startScene)
{
HandleStartSceneInput();
}
// Обработка ввода сцены помощи
else if (activeScene == helpScene)
{
if (CheckEnterA())
{
ShowScene(startScene);
}
}
// Обработка ввода для сцены игры
else if (activeScene == actionScene)
{
HandleActionInput();
}
}
Метод CheckEnterA содержит простой код для проверки нажатия клавиши Enter или кнопки A на игровом пульте Xbox 360:
/// <summary>
/// Проверка нажатия клавиши Enter или кнопки A
/// </summary>
/// <returns>true, если нажата клавиша Enter или кнопка A</returns>
private bool CheckEnterA()
{
// Получаем состояние клавиатуры и игрового пульта
GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
KeyboardState keyboardState = Keyboard.GetState();
bool result = (oldKeyboardState.IsKeyDown(Keys.Enter) &&
(keyboardState.IsKeyUp(Keys.Enter)));
result |= (oldGamePadState.Buttons.A == ButtonState.Pressed) &&
(gamepadState.Buttons.A == ButtonState.Released);
oldKeyboardState = keyboardState;
oldGamePadState = gamepadState;
return result;
}
HandleStartSceneInput показывает требуемую сцену в соответствии с выбранным пользователем пунктом меню. Если выбрана игра для двух игроков, вы просто делаете атрибут TwoPlayers в actionScene равным true:
/// <summary>
/// Обработка кнопок и клавиатуры в начальной сцене
/// </summary>
private void HandleStartSceneInput()
{
if (CheckEnterA())
{
audioComponent.PlayCue("menu_select3");
switch (startScene.SelectedMenuIndex)
{
case 0:
actionScene.TwoPlayers = false;
ShowScene(actionScene);
break;
case 1:
actionScene.TwoPlayers = true;
ShowScene(actionScene);
break;
case 2:
ShowScene(helpScene);
break;
case 3:
Exit();
break;
}
}
}
HandleActionInput обрабатывает ввод в сцене игры для приостановки и прекращения игры с использованием клавиатуры или игрового пульта Xbox 360:
/// <summary>
/// Проверяем нажатие клавиши Enter или кнопки A
/// </summary>
/// <returns>true, если нажата клавиша Enter или кнопка A</returns>
private void HandleActionInput()
{
// Получаем сосотояние клавиатуры и игрового пульта
GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
KeyboardState keyboardState = Keyboard.GetState();
bool backKey = (oldKeyboardState.IsKeyDown(Keys.Escape) &&
(keyboardState.IsKeyUp(Keys.Escape)));
backKey |= (oldGamePadState.Buttons.Back == ButtonState.Pressed) &&
(gamepadState.Buttons.Back == ButtonState.Released);
bool enterKey = (oldKeyboardState.IsKeyDown(Keys.Enter) &&
(keyboardState.IsKeyUp(Keys.Enter)));
enterKey |= (oldGamePadState.Buttons.A == ButtonState.Pressed) &&
(gamepadState.Buttons.A == ButtonState.Released);
oldKeyboardState = keyboardState;
oldGamePadState = gamepadState;
if (enterKey)
{
if (actionScene.GameOver)
{
ShowScene(startScene);
}
else
{
audioComponent.PlayCue("menu_back");
actionScene.Paused = !actionScene.Paused;
}
}
if (backKey)
{
ShowScene(startScene);
}
}
Метод ShowScene является вспомогательным для вызова Show новой сцены и Hide предыдущей, как показано ниже:
/// <summary>
/// Открывает новую сцену
/// </summary>
/// <param name="scene">Открываемая сцена</param>
protected void ShowScene(GameScene scene)
{
activeScene.Hide();
activeScene = scene;
scene.Show();
}
А что насчет метода Draw? Сейчас все элементы вашей игры являются GameComponent, так что просто позвольте XNA выполнять его работу:
/// <summary>
/// Вызывается, когда игра должна нарисовать себя
/// </summary>
/// <param name="gameTime">Предоставляет снимок значения таймера</param>
protected override void Draw(GameTime gameTime)
{
// Начинаем
spriteBatch.Begin();
// Рисуем все GameComponent
base.Draw(gameTime);
// Заканчиваем
spriteBatch.End();
}
Вот так. Скомпилируйте и запустите игру, чтобы увидеть финальный результат. Архитектура получилась гибкой и к вашей игре легко добавить новые возможности, что вы и увидите в следующей главе. Попробуйте, например, добавить новые типы астероидов или новые способы получения энергии. Вы начнете понимать как игры «собираются» из GameComponent.
| netlib.narod.ru | < Назад | Оглавление | Далее > |