Для организации вспомогательных подсистем игры важно уметь работать с текстами. В XNA можно использовать несколько подходов к выводу текстовых сообщений. Во-первых – можно воспользоваться стандартными средствами вывода текста одним из шрифтов, установленных в системе. Таким способом удобно выводить на экран большие объемы текстов.
Во-вторых – можно создать нужные надписи в виде изображений и выводить их как обычные спрайты. Этот подход удобен при создании системы меню и других надписей, которые нет необходимости модифицировать в ходе работы игровой программы. Причем, такие надписи можно анимировать теми же способами, которые используются для анимации спрайтов. Обычно системы меню в компьютерных играх создаются именно таким способом.
Третий способ вывода текста – это создать нечто вроде алфавита – спрайта, содержащего изображения букв и, разработав систему вывода нужных участков этого спрайта с необходимыми символами, выводить любые тексты таким способом.
Рассмотрим способ вывода обычного текста в XNA. Создадим новый проект P9_1. Прежде чем заниматься выводом текста, нужно создать ресурс типа .SPRITEFONT. Это – XML-файл, который содержит параметры шрифта, используемого для вывода. Для того, чтобы создать этот файл, выполните следующие действия.
Этот файл состоит из множества документированных разделов, которые позволяют настраивать свойства шрифта. В частности, по умолчанию параметр Style установлен в Regular. Для шрифта
Теперь все готово для использования шрифта в программе. Ниже, в листинге 13.1. приведен код класса Game1, реализующий вывод на экран строки текста.
using System;
using System.Collections.Generic;
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.Net;
using Microsoft.Xna.Framework.Storage;
namespace P9_1
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//Для хранения шрифта
SpriteFont MyFont;
//Для хранения позиции вывода текста
Vector2 StringPosition;
//Строка для вывода
string OutString;
//Для нахождения центра строки
Vector2 StringOrigin;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
OutString = "Score: 12345";
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
//Загружаем шрифт
MyFont = Content.Load<SpriteFont>("Monotype Corsiva");
//Устанавливаем позицию вывода шрифта в центре экрана
StringPosition = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2,
graphics.GraphicsDevice.Viewport.Height / 2);
//Находим центр строки
StringOrigin = MyFont.MeasureString(OutString) / 2;
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
//Выводим строку
spriteBatch.DrawString(MyFont , OutString , StringPosition, Color.Red,
0, StringOrigin, 1.0f, SpriteEffects.None, 0.5f);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Как видите, вывод текста очень похож на вывод изображений. Для хранения шрифта используется переменная типа SpriteFont, метод DrawString объекта типа SpriteBatch отвечает за прорисовку текста на игровом экране:
spriteBatch.DrawString(MyFont, OutString, StringPosition, Color.Red, 0, StringOrigin, 1.0f, SpriteEffects.None, 0.5f);
Рассмотрим параметры вызова этого метода в табл. 13.1.
| Параметр вызова метода | Описание параметра |
|---|---|
MyFont |
Переменная типа SpriteFont – шрифт, которым выводится текст |
OutString |
Переменная типа String – текст для вывода |
StringPosition |
Переменная типа Vector2 – позиция текста |
Color.Red |
Цвет текста |
| 0 | Поворот текста в радианах относительно точки привязки координат текста |
StringOrigin |
Переменная типа Vector2 – точка привязки координат объекта |
1.0f |
Коэффициент масштабирования объекта |
SpriteEffects.None |
Эффект спрайта |
0.5f |
Глубина текста – положение относительно других графических объектов |
На рис. 13.3. вы можете видеть игровой экран проекта P9_1.
(рис 13.3) Экран проекта P9_1Создадим новый проект P9_2. На его примере рассмотрим приемы работы, освоение которых вынесено в задачи данной работы.
Задача оформления игры сводится к созданию нескольких игровых экранов с определенной функциональностью и к разработке системы перемещения между этими экранами.
На рис. 13.4. вы можете видеть окно Project Explorer проекта P9_2.
(рис 13.4) Окно Project Explorer проекта P9_2В листинге 13.2. приведен код класса Game1.
using System;
using System.Collections.Generic;
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.Net;
using Microsoft.Xna.Framework.Storage;
namespace P9_2
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//Экран справки
HelpScreen help;
Texture2D helpBack;
Texture2D helpText;
//Экран меню
MenuScreen menu;
Texture2D menuBack;
Texture2D menuGameName;
Texture2D menuTxtStartGame;
Texture2D menuTxtHelp;
Texture2D menuTxtExit;
//Текущий элемент меню
int currentItem;
//Интервал задержки переключения между элементами меню
int interval;
//Игровой экран
GameScreen newGame;
Texture2D gameBat;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
//При запуске игры активным устанавливается первый элемент меню
currentItem = 1;
interval = 0;
base.Initialize();
}
protected override void LoadContent()
{
//Загружаем элементы игры и создаем игровые экраны
spriteBatch = new SpriteBatch(GraphicsDevice);
Services.AddService(typeof(SpriteBatch), spriteBatch);
helpBack = Content.Load<Texture2D>("helpBack");
helpText = Content.Load<Texture2D>("helpText");
help = new HelpScreen(this, helpBack, helpText,
new Rectangle(0, 0, this.Window.ClientBounds.Width, this.Window.ClientBounds.Height),
new Rectangle((this.Window.ClientBounds.Width - helpText.Width)/2,
(this.Window.ClientBounds.Height - helpText.Height)/2,
helpText .Width , helpText .Height ));
Components.Add(help);
gameBat = Content.Load<Texture2D>("BallandBats");
newGame = new GameScreen(this, ref gameBat, new Rectangle(18, 9, 17, 88),
new Vector2(100, 100));
Components.Add(newGame);
menuBack = Content.Load<Texture2D>("menuBack");
menuGameName = Content.Load<Texture2D>("menuGameName");
menuTxtStartGame = Content.Load<Texture2D>("menuTxtStartGame");
menuTxtHelp = Content.Load<Texture2D>("menuTxtHelp");
menuTxtExit = Content.Load<Texture2D>("menuTxtExit");
menu = new MenuScreen(this, menuBack, menuGameName, menuTxtStartGame, menuTxtHelp,
menuTxtExit, new Rectangle(100, 300, 400, 50), new Rectangle(100, 350, 400, 50),
new Rectangle(100, 400, 400, 50));
Components.Add(menu);
//Отображаем меню, остальные элементы скрыты
menu.Show();
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
//Обработка нажатий на клавиши
void KeyboardHandle()
{
//считаем состояние клавиатуры
KeyboardState kbState = Keyboard.GetState();
//Если прошло 4 игровых цикла
interval ++;
if (interval >=4)
{
//Обнуляем счетичик
interval = 0;
//Если выбран экран меню
if (menu.Enabled)
{
//Если нажата клавиша вверх
if (kbState.IsKeyDown(Keys.Up))
{
//Уменьшить на 1 счетчик, отвечающий за
//смену пунктов меню
currentItem--;
//Если в момент нажатия был активен самый верхний
//пункт
if (currentItem < 1)
{
//Делаем текущим третий пункт
currentItem = 3;
//Вызов процедуры для отображения смены пункта меню
menu.GetKey(currentItem);
}
//если при уменьшении номера пункта
//он не меньше 1, вызываем процедуру
//отображения смены пункта
else
{
menu.GetKey(currentItem);
}
}
//При нажатии клавиши вниз
if (kbState.IsKeyDown(Keys.Down))
{
//Увеличим счетчик
currentItem++;
//Если он больше 3 - активируем первый пункт
if (currentItem > 3)
{
currentItem = 1;
menu.GetKey(currentItem);
}
//Если не меньше 3 - переходим на следующий пункт
else
{
menu.GetKey(currentItem);
}
}
//При нажатии клавиши Enter
//выполняем команду, соответствующую текущему пункту меню
if (kbState .IsKeyDown (Keys .Enter))
{
//Первый пункт - скрываем экран меню
//и отображаем игровой экран
if (currentItem == 1)
{
menu.Hide();
newGame.Show();
}
//Скрываем меню и
//отображаем экран справки
if (currentItem ==2)
{
menu.Hide();
help.Show ();
}
//Выходим из игры
if (currentItem == 3)
{
this.Exit();
}
}
}
}
//Если активен экран справки
if (help.Enabled)
{
//При нажатии Esc закрываем экран справки
//И открываем меню
if (kbState.IsKeyDown(Keys.Escape))
{
help.Hide();
menu.Show();
}
}
//Если активен игровой экран
//При нажатии Esc закрываем его
//и открываем меню
//Обработка нажатий клавиш, необходимых для работы игрового экрана
//проводится в объекте, соответствующем этому экрану
if (newGame.Enabled)
{
if (kbState.IsKeyDown(Keys.Escape))
{
newGame.Hide();
menu.Show();
}
}
}
protected override void Update(GameTime gameTime)
{
//Обработка нажатий на клавиши
KeyboardHandle();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
base.Draw(gameTime);
spriteBatch.End();
}
}
}
В листинге 13.3. вы можете видеть код класса Classes.Menu
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2.Classes
{
//Класс для хранения данных об элементах меню
public class Menu
{
public Texture2D imageTexture;
public Rectangle imageRectangle;
public Color color;
public Menu(Game game, Texture2D _texture, Rectangle _rectangle, Color _color)
{
imageTexture = _texture;
imageRectangle = _rectangle;
color = _color;
}
}
}
В листинге 13.4. приведен код класса Screen – этот класс является базовым для классов игровых экранов. Он содержит методы для активации и деактивации игровых экранов.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Базовый класс, на основе которого создаются игровые экраны
public class Screen : Microsoft.Xna.Framework.DrawableGameComponent
{
//Для объекта SpriteBatch, который используется
//для вывода изображений в классах-наследниках
public SpriteBatch sprBatch;
public Screen(Game game)
: base(game)
{
//При создании объекта он по умолчанию
//невидим и неактивен
Visible = false;
Enabled = false;
//получим объект SpriteBatch
sprBatch =(SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
}
//Процедура для отображения и активации объекта
public void Show()
{
Visible = true;
Enabled = true;
}
//Процедура для скрытия и отключения объекта
public void Hide()
{
Visible = false;
Enabled = false;
}
}
}
На рис. 13.5. вы можете видеть экран игрового меню.
(рис 13.5) Экран игрового менюВ листинге 13.5. приведен код класса MenuScreen.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Экран меню
public class MenuScreen : Screen
{
//Элементы меню будем хранить в массиве типа Menu
//тип данных Menu хранит информацию об элементах меню
Classes.Menu[] menu;
//Текстуры и прямоугольники для вывода элементов меню
Texture2D menuTxtStartGame;
Texture2D menuTxtHelp;
Texture2D menuTxtExit;
Rectangle menuTxtStartGameR, menuTxtHelpR, menuTxtExitR;
Texture2D menuBack, menuGameName;
Rectangle menuBackR, menuGameNameR;
public MenuScreen(Game game, Texture2D _menuBack, Texture2D _menuGameName,
Texture2D _menuTxtStartGame, Texture2D _menuTxtHelp, Texture2D _menuTxtExit,
Rectangle _menuTxtStartGameR,Rectangle _menuTxtHelpR, Rectangle _menuTxtExitR)
: base(game)
{
menuBack = _menuBack;
menuGameName = _menuGameName;
menuBackR = new Rectangle(0, 0, 800, 600);
menuGameNameR = new Rectangle(0, 0, 800, 200);
menuTxtStartGame = _menuTxtStartGame ;
menuTxtStartGameR = _menuTxtStartGameR;
menuTxtHelp = _menuTxtHelp;
menuTxtHelpR = _menuTxtHelpR;
menuTxtExit = _menuTxtExit;
menuTxtExitR = _menuTxtExitR;
//Создаем массив из 3-х элементов
menu = new P9_2.Classes.Menu[3];
//Инициализируем элементы массива
//Элемент с номером 0 активен
menu[0]=new P9_2.Classes.Menu (game, menuTxtStartGame, menuTxtStartGameR ,Color.Magenta);
menu[1] = new P9_2.Classes.Menu(game, menuTxtHelp, menuTxtHelpR, Color.White);
menu[2] = new P9_2.Classes.Menu(game, menuTxtExit, menuTxtExitR, Color.White);
}
//Метод вызывается для отображения смены пункта меню
public void GetKey(int i)
{
//i=1 - первый пункт
//i=2 - второй пункт
//i=3 - третий пункт
if (i == 1)
{
menu[0].color = Color.Magenta;
menu[1].color = Color.White;
menu[2].color = Color.White;
}
if (i == 2)
{
menu[0].color = Color.White;
menu[1].color = Color.Magenta;
menu[2].color = Color.White;
}
if (i == 3)
{
menu[0].color = Color.White;
menu[1].color = Color.White;
menu[2].color = Color.Magenta;
}
}
//Рисование элементов
public override void Draw(GameTime gameTime)
{
//Вывод фона и названия игры
sprBatch.Draw(menuBack, menuBackR, Color.White);
sprBatch.Draw(menuGameName, menuGameNameR, Color.White);
//Вывод элементов меню
for (int i=0;i<3;i++)
sprBatch.Draw(menu[i].imageTexture, menu[i].imageRectangle, menu[i].color);
base.Draw(gameTime);
}
}
}
На рис. 13.6. вы может видеть справочный экран.
(рис 13.6) Экран игровой справки В листинге 13.6. вы можете найти код класса HelpScreen.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Экран справки
public class HelpScreen : Screen
{
//Текстуры для фона и справочной надписи
Texture2D backTexture;
Rectangle backRectangle;
Texture2D helpTexture;
Rectangle helpRectangle;
public HelpScreen(Game game, Texture2D _back, Texture2D _help, Rectangle _backRec, Rectangle _helpRec)
: base(game)
{
backTexture = _back;
helpTexture = _help;
backRectangle = _backRec;
helpRectangle = _helpRec;
}
public override void Draw(GameTime gameTime)
{
//Выводим изображения
sprBatch.Draw(backTexture, backRectangle, Color.White);
sprBatch.Draw(helpTexture, helpRectangle, Color.White);
base.Draw(gameTime);
}
}
}
На рис. 13.7. вы можете видеть игровой экран.
(рис 13.7) Игровой экранВ листинге 13.7. приведен код игрового экрана – класса GameScreen. Мы использовали простой код для перемещения объекта из проекта P3_4.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Игровой экран
public class GameScreen :Screen
{
private Texture2D sprTexture;
private Rectangle sprRectangle;
private Vector2 sprPosition;
private Rectangle scrBounds;
public GameScreen(Game game, ref Texture2D newTexture,
Rectangle newRectangle, Vector2 newPosition)
: base(game)
{
sprTexture = newTexture;
sprRectangle = newRectangle;
sprPosition = newPosition;
scrBounds = new Rectangle(0, 0,
game.Window.ClientBounds.Width,
game.Window.ClientBounds.Height);
}
public override void Initialize()
{
// TODO: Add your initialization code here
base.Initialize();
}
public override void Update(GameTime gameTime)
{
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.Up))
{
sprPosition.Y -= 5;
}
if (kbState.IsKeyDown(Keys.Down))
{
sprPosition.Y += 5;
}
if (kbState.IsKeyDown(Keys.Left))
{
sprPosition.X -= 5;
}
if (kbState.IsKeyDown(Keys.Right))
{
sprPosition.X += 5;
}
if (sprPosition.X < scrBounds.Left)
{
sprPosition.X = scrBounds.Left;
}
if (sprPosition.X > scrBounds.Width - sprRectangle.Width)
{
sprPosition.X = scrBounds.Width - sprRectangle.Width;
}
if (sprPosition.Y < scrBounds.Top)
{
sprPosition.Y = scrBounds.Top;
}
if (sprPosition.Y > scrBounds.Height - sprRectangle.Height)
{
sprPosition.Y = scrBounds.Height - sprRectangle.Height;
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
sprBatch.Draw(sprTexture, sprPosition, sprRectangle, Color.White);
base.Draw(gameTime);
}
}
}
Создайте систему игровых экранов и меню, которым можно управлять с помощью мыши и клавиатуры.
Для организации вспомогательных подсистем игры важно уметь работать с текстами. В XNA можно использовать несколько подходов к выводу текстовых сообщений. Во-первых – можно воспользоваться стандартными средствами вывода текста одним из шрифтов, установленных в системе. Таким способом удобно выводить на экран большие объемы текстов.
Во-вторых – можно создать нужные надписи в виде изображений и выводить их как обычные спрайты. Этот подход удобен при создании системы меню и других надписей, которые нет необходимости модифицировать в ходе работы игровой программы. Причем, такие надписи можно анимировать теми же способами, которые используются для анимации спрайтов. Обычно системы меню в компьютерных играх создаются именно таким способом.
Третий способ вывода текста – это создать нечто вроде алфавита – спрайта, содержащего изображения букв и, разработав систему вывода нужных участков этого спрайта с необходимыми символами, выводить любые тексты таким способом.
Рассмотрим способ вывода обычного текста в XNA. Создадим новый проект P9_1. Прежде чем заниматься выводом текста, нужно создать ресурс типа .SPRITEFONT. Это – XML-файл, который содержит параметры шрифта, используемого для вывода. Для того, чтобы создать этот файл, выполните следующие действия.
Этот файл состоит из множества документированных разделов, которые позволяют настраивать свойства шрифта. В частности, по умолчанию параметр Style установлен в Regular. Для шрифта
Теперь все готово для использования шрифта в программе. Ниже, в листинге 13.1. приведен код класса Game1, реализующий вывод на экран строки текста.
using System;
using System.Collections.Generic;
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.Net;
using Microsoft.Xna.Framework.Storage;
namespace P9_1
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//Для хранения шрифта
SpriteFont MyFont;
//Для хранения позиции вывода текста
Vector2 StringPosition;
//Строка для вывода
string OutString;
//Для нахождения центра строки
Vector2 StringOrigin;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
OutString = "Score: 12345";
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
//Загружаем шрифт
MyFont = Content.Load<SpriteFont>("Monotype Corsiva");
//Устанавливаем позицию вывода шрифта в центре экрана
StringPosition = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2,
graphics.GraphicsDevice.Viewport.Height / 2);
//Находим центр строки
StringOrigin = MyFont.MeasureString(OutString) / 2;
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
//Выводим строку
spriteBatch.DrawString(MyFont , OutString , StringPosition, Color.Red,
0, StringOrigin, 1.0f, SpriteEffects.None, 0.5f);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Как видите, вывод текста очень похож на вывод изображений. Для хранения шрифта используется переменная типа SpriteFont, метод DrawString объекта типа SpriteBatch отвечает за прорисовку текста на игровом экране:
spriteBatch.DrawString(MyFont, OutString, StringPosition, Color.Red, 0, StringOrigin, 1.0f, SpriteEffects.None, 0.5f);
Рассмотрим параметры вызова этого метода в табл. 13.1.
| Параметр вызова метода | Описание параметра |
|---|---|
MyFont |
Переменная типа SpriteFont – шрифт, которым выводится текст |
OutString |
Переменная типа String – текст для вывода |
StringPosition |
Переменная типа Vector2 – позиция текста |
Color.Red |
Цвет текста |
| 0 | Поворот текста в радианах относительно точки привязки координат текста |
StringOrigin |
Переменная типа Vector2 – точка привязки координат объекта |
1.0f |
Коэффициент масштабирования объекта |
SpriteEffects.None |
Эффект спрайта |
0.5f |
Глубина текста – положение относительно других графических объектов |
На рис. 13.3. вы можете видеть игровой экран проекта P9_1.
(рис 13.3) Экран проекта P9_1Создадим новый проект P9_2. На его примере рассмотрим приемы работы, освоение которых вынесено в задачи данной работы.
Задача оформления игры сводится к созданию нескольких игровых экранов с определенной функциональностью и к разработке системы перемещения между этими экранами.
На рис. 13.4. вы можете видеть окно Project Explorer проекта P9_2.
(рис 13.4) Окно Project Explorer проекта P9_2В листинге 13.2. приведен код класса Game1.
using System;
using System.Collections.Generic;
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.Net;
using Microsoft.Xna.Framework.Storage;
namespace P9_2
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//Экран справки
HelpScreen help;
Texture2D helpBack;
Texture2D helpText;
//Экран меню
MenuScreen menu;
Texture2D menuBack;
Texture2D menuGameName;
Texture2D menuTxtStartGame;
Texture2D menuTxtHelp;
Texture2D menuTxtExit;
//Текущий элемент меню
int currentItem;
//Интервал задержки переключения между элементами меню
int interval;
//Игровой экран
GameScreen newGame;
Texture2D gameBat;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
//При запуске игры активным устанавливается первый элемент меню
currentItem = 1;
interval = 0;
base.Initialize();
}
protected override void LoadContent()
{
//Загружаем элементы игры и создаем игровые экраны
spriteBatch = new SpriteBatch(GraphicsDevice);
Services.AddService(typeof(SpriteBatch), spriteBatch);
helpBack = Content.Load<Texture2D>("helpBack");
helpText = Content.Load<Texture2D>("helpText");
help = new HelpScreen(this, helpBack, helpText,
new Rectangle(0, 0, this.Window.ClientBounds.Width, this.Window.ClientBounds.Height),
new Rectangle((this.Window.ClientBounds.Width - helpText.Width)/2,
(this.Window.ClientBounds.Height - helpText.Height)/2,
helpText .Width , helpText .Height ));
Components.Add(help);
gameBat = Content.Load<Texture2D>("BallandBats");
newGame = new GameScreen(this, ref gameBat, new Rectangle(18, 9, 17, 88),
new Vector2(100, 100));
Components.Add(newGame);
menuBack = Content.Load<Texture2D>("menuBack");
menuGameName = Content.Load<Texture2D>("menuGameName");
menuTxtStartGame = Content.Load<Texture2D>("menuTxtStartGame");
menuTxtHelp = Content.Load<Texture2D>("menuTxtHelp");
menuTxtExit = Content.Load<Texture2D>("menuTxtExit");
menu = new MenuScreen(this, menuBack, menuGameName, menuTxtStartGame, menuTxtHelp,
menuTxtExit, new Rectangle(100, 300, 400, 50), new Rectangle(100, 350, 400, 50),
new Rectangle(100, 400, 400, 50));
Components.Add(menu);
//Отображаем меню, остальные элементы скрыты
menu.Show();
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
//Обработка нажатий на клавиши
void KeyboardHandle()
{
//считаем состояние клавиатуры
KeyboardState kbState = Keyboard.GetState();
//Если прошло 4 игровых цикла
interval ++;
if (interval >=4)
{
//Обнуляем счетичик
interval = 0;
//Если выбран экран меню
if (menu.Enabled)
{
//Если нажата клавиша вверх
if (kbState.IsKeyDown(Keys.Up))
{
//Уменьшить на 1 счетчик, отвечающий за
//смену пунктов меню
currentItem--;
//Если в момент нажатия был активен самый верхний
//пункт
if (currentItem < 1)
{
//Делаем текущим третий пункт
currentItem = 3;
//Вызов процедуры для отображения смены пункта меню
menu.GetKey(currentItem);
}
//если при уменьшении номера пункта
//он не меньше 1, вызываем процедуру
//отображения смены пункта
else
{
menu.GetKey(currentItem);
}
}
//При нажатии клавиши вниз
if (kbState.IsKeyDown(Keys.Down))
{
//Увеличим счетчик
currentItem++;
//Если он больше 3 - активируем первый пункт
if (currentItem > 3)
{
currentItem = 1;
menu.GetKey(currentItem);
}
//Если не меньше 3 - переходим на следующий пункт
else
{
menu.GetKey(currentItem);
}
}
//При нажатии клавиши Enter
//выполняем команду, соответствующую текущему пункту меню
if (kbState .IsKeyDown (Keys .Enter))
{
//Первый пункт - скрываем экран меню
//и отображаем игровой экран
if (currentItem == 1)
{
menu.Hide();
newGame.Show();
}
//Скрываем меню и
//отображаем экран справки
if (currentItem ==2)
{
menu.Hide();
help.Show ();
}
//Выходим из игры
if (currentItem == 3)
{
this.Exit();
}
}
}
}
//Если активен экран справки
if (help.Enabled)
{
//При нажатии Esc закрываем экран справки
//И открываем меню
if (kbState.IsKeyDown(Keys.Escape))
{
help.Hide();
menu.Show();
}
}
//Если активен игровой экран
//При нажатии Esc закрываем его
//и открываем меню
//Обработка нажатий клавиш, необходимых для работы игрового экрана
//проводится в объекте, соответствующем этому экрану
if (newGame.Enabled)
{
if (kbState.IsKeyDown(Keys.Escape))
{
newGame.Hide();
menu.Show();
}
}
}
protected override void Update(GameTime gameTime)
{
//Обработка нажатий на клавиши
KeyboardHandle();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
base.Draw(gameTime);
spriteBatch.End();
}
}
}
В листинге 13.3. вы можете видеть код класса Classes.Menu
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2.Classes
{
//Класс для хранения данных об элементах меню
public class Menu
{
public Texture2D imageTexture;
public Rectangle imageRectangle;
public Color color;
public Menu(Game game, Texture2D _texture, Rectangle _rectangle, Color _color)
{
imageTexture = _texture;
imageRectangle = _rectangle;
color = _color;
}
}
}
В листинге 13.4. приведен код класса Screen – этот класс является базовым для классов игровых экранов. Он содержит методы для активации и деактивации игровых экранов.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Базовый класс, на основе которого создаются игровые экраны
public class Screen : Microsoft.Xna.Framework.DrawableGameComponent
{
//Для объекта SpriteBatch, который используется
//для вывода изображений в классах-наследниках
public SpriteBatch sprBatch;
public Screen(Game game)
: base(game)
{
//При создании объекта он по умолчанию
//невидим и неактивен
Visible = false;
Enabled = false;
//получим объект SpriteBatch
sprBatch =(SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
}
//Процедура для отображения и активации объекта
public void Show()
{
Visible = true;
Enabled = true;
}
//Процедура для скрытия и отключения объекта
public void Hide()
{
Visible = false;
Enabled = false;
}
}
}
На рис. 13.5. вы можете видеть экран игрового меню.
(рис 13.5) Экран игрового менюВ листинге 13.5. приведен код класса MenuScreen.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Экран меню
public class MenuScreen : Screen
{
//Элементы меню будем хранить в массиве типа Menu
//тип данных Menu хранит информацию об элементах меню
Classes.Menu[] menu;
//Текстуры и прямоугольники для вывода элементов меню
Texture2D menuTxtStartGame;
Texture2D menuTxtHelp;
Texture2D menuTxtExit;
Rectangle menuTxtStartGameR, menuTxtHelpR, menuTxtExitR;
Texture2D menuBack, menuGameName;
Rectangle menuBackR, menuGameNameR;
public MenuScreen(Game game, Texture2D _menuBack, Texture2D _menuGameName,
Texture2D _menuTxtStartGame, Texture2D _menuTxtHelp, Texture2D _menuTxtExit,
Rectangle _menuTxtStartGameR,Rectangle _menuTxtHelpR, Rectangle _menuTxtExitR)
: base(game)
{
menuBack = _menuBack;
menuGameName = _menuGameName;
menuBackR = new Rectangle(0, 0, 800, 600);
menuGameNameR = new Rectangle(0, 0, 800, 200);
menuTxtStartGame = _menuTxtStartGame ;
menuTxtStartGameR = _menuTxtStartGameR;
menuTxtHelp = _menuTxtHelp;
menuTxtHelpR = _menuTxtHelpR;
menuTxtExit = _menuTxtExit;
menuTxtExitR = _menuTxtExitR;
//Создаем массив из 3-х элементов
menu = new P9_2.Classes.Menu[3];
//Инициализируем элементы массива
//Элемент с номером 0 активен
menu[0]=new P9_2.Classes.Menu (game, menuTxtStartGame, menuTxtStartGameR ,Color.Magenta);
menu[1] = new P9_2.Classes.Menu(game, menuTxtHelp, menuTxtHelpR, Color.White);
menu[2] = new P9_2.Classes.Menu(game, menuTxtExit, menuTxtExitR, Color.White);
}
//Метод вызывается для отображения смены пункта меню
public void GetKey(int i)
{
//i=1 - первый пункт
//i=2 - второй пункт
//i=3 - третий пункт
if (i == 1)
{
menu[0].color = Color.Magenta;
menu[1].color = Color.White;
menu[2].color = Color.White;
}
if (i == 2)
{
menu[0].color = Color.White;
menu[1].color = Color.Magenta;
menu[2].color = Color.White;
}
if (i == 3)
{
menu[0].color = Color.White;
menu[1].color = Color.White;
menu[2].color = Color.Magenta;
}
}
//Рисование элементов
public override void Draw(GameTime gameTime)
{
//Вывод фона и названия игры
sprBatch.Draw(menuBack, menuBackR, Color.White);
sprBatch.Draw(menuGameName, menuGameNameR, Color.White);
//Вывод элементов меню
for (int i=0;i<3;i++)
sprBatch.Draw(menu[i].imageTexture, menu[i].imageRectangle, menu[i].color);
base.Draw(gameTime);
}
}
}
На рис. 13.6. вы может видеть справочный экран.
(рис 13.6) Экран игровой справкиВ листинге 13.6. вы можете найти код класса HelpScreen.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Экран справки
public class HelpScreen : Screen
{
//Текстуры для фона и справочной надписи
Texture2D backTexture;
Rectangle backRectangle;
Texture2D helpTexture;
Rectangle helpRectangle;
public HelpScreen(Game game, Texture2D _back, Texture2D _help, Rectangle _backRec, Rectangle _helpRec)
: base(game)
{
backTexture = _back;
helpTexture = _help;
backRectangle = _backRec;
helpRectangle = _helpRec;
}
public override void Draw(GameTime gameTime)
{
//Выводим изображения
sprBatch.Draw(backTexture, backRectangle, Color.White);
sprBatch.Draw(helpTexture, helpRectangle, Color.White);
base.Draw(gameTime);
}
}
}
На рис. 13.7. вы можете видеть игровой экран.
(рис 13.7) Игровой экранВ листинге 13.7. приведен код игрового экрана – класса GameScreen. Мы использовали простой код для перемещения объекта из проекта P3_4.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P9_2
{
//Игровой экран
public class GameScreen :Screen
{
private Texture2D sprTexture;
private Rectangle sprRectangle;
private Vector2 sprPosition;
private Rectangle scrBounds;
public GameScreen(Game game, ref Texture2D newTexture,
Rectangle newRectangle, Vector2 newPosition)
: base(game)
{
sprTexture = newTexture;
sprRectangle = newRectangle;
sprPosition = newPosition;
scrBounds = new Rectangle(0, 0,
game.Window.ClientBounds.Width,
game.Window.ClientBounds.Height);
}
public override void Initialize()
{
// TODO: Add your initialization code here
base.Initialize();
}
public override void Update(GameTime gameTime)
{
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.Up))
{
sprPosition.Y -= 5;
}
if (kbState.IsKeyDown(Keys.Down))
{
sprPosition.Y += 5;
}
if (kbState.IsKeyDown(Keys.Left))
{
sprPosition.X -= 5;
}
if (kbState.IsKeyDown(Keys.Right))
{
sprPosition.X += 5;
}
if (sprPosition.X < scrBounds.Left)
{
sprPosition.X = scrBounds.Left;
}
if (sprPosition.X > scrBounds.Width - sprRectangle.Width)
{
sprPosition.X = scrBounds.Width - sprRectangle.Width;
}
if (sprPosition.Y < scrBounds.Top)
{
sprPosition.Y = scrBounds.Top;
}
if (sprPosition.Y > scrBounds.Height - sprRectangle.Height)
{
sprPosition.Y = scrBounds.Height - sprRectangle.Height;
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
sprBatch.Draw(sprTexture, sprPosition, sprRectangle, Color.White);
base.Draw(gameTime);
}
}
}
Создайте систему игровых экранов и меню, которым можно управлять с помощью мыши и клавиатуры.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.