XNA для начинающих: обзор проекта, свойства окон, игровой фон.
Вступительное слово:
Здравствуйте уважаемые пользователи портала GcUp.Ru! В этой статье я расскажу Вам, как создать игровой фон в XNA GameStudio, а так же познакомлю Вас с параметрами игрового окна и расскажу в общий чертах об XNA и его структуре. Весь приведенный ниже код проверен, и отлично функционирует в версии 3.1. Но, так же он должен работать и в других версиях (3.0 и 4.0; на счет 2.0 не уверен). Перед знакомством с этим уроком рекомендую прочитать статью пользователя E][pert, так как здесь использован похожий принцип.
Так же перед прочтением данной статьи Вы должны обладать базовыми знаниями языка программирования C#, а так же иметь программу Microsoft Visual C# Express необходимой Вам версии (для XNA 3.1 - Microsoft Visual C# Express 2008, а для XNA 4.0 - Microsoft Visual C# Express 2010) с установленной библиотекой XNA GameStudio. И так, если Вы имеете все вышеприведенное, тогда приступим!
Знакомство с XNA Game Studio:
Для начала давайте создадим новый проект в Microsoft Visual C# Express. Для этого перейдите в Файл -> Создать проект -> XNA Game Studio 3.1 (или 4.0) -> Windows Game (3.1). Так как с английским у меня не очень, назовем его просто и понятно – fon (так как я тестировал данный код, проект fon у меня уже есть, поэтому я назвал наш проект fon1). У Вас должно получиться так:
После этого нажмите кнопку «ОК». Нажав ее, Вы, тем самым, создали новый проект игры для Windows. Теперь давайте посмотрим на окно «Обозреватель решений», или «Solution Explorer». Как Вы видите, там создалось несколько файлов. Properties и Ссылки пропускаем, ибо они нам не к чему. Следом идет папка Content. Именно сюда загружаются все файлы игры. Будь то музыка, графика или эффекты. Все содержится в этой папке. Дальше идет файл Game.ico. Это иконка нашей игры. Позже я покажу, как она будет выглядеть. Так же Вы можете заменить ее на любую другую, но соблюдая размер!
Следом идет класс Game1.cs. Это главный класс данного проекта и работать мы будем именно в нем. Мы еще к нему вернемся.
Дальше следует еще одна иконка игры и последний класс данного проекта - Program.cs. С ним мы работать не будем. Скажу лишь только, что в нем создается объект класса Game1, который и запускает нашу игру.
Если Вы хотите увидеть, как сейчас выглядит наша игра, нажмите клавишу «F5». Как Вы видите, открылось окно с синим фоном. А вверху как раз та самая иконка под названием Game.ico.
И так, теперь перейдем непосредственно к работе с классом Game1.
Класс Game1:
Ну, для начала давайте посмотрим на структуру класса Game1.cs. Сначала в нем созданы объекты graphics и spriteBatch.
Затем создан конструктор класса Game1. Если в двух словах, то конструктор указывает первоначальные (значения, которые будут с самого начала) значения переменных и объектов класса. Он нам понадобится, когда мы будем задавать размер окна нашего приложения, но об этом позже.
Затем идут следующие методы:
• Initialize() – отвечает за инициализацию (создание и присвание значений) переменных и объектов. Он нам нужен будет почти для тех же самых целей, что и конструктор. • LoadContent() – загружает в игру весь контент (графику, музыку и тп.), который мы будем использовать. • UnloadContent() – выгружает весь контент из игры после выхода. • Update(GameTime gameTime) – отвечает за изменение всех значений в игре, будь то нажатие клавиши или изменение времени. • Draw(GameTime gameTime) – рисует всю графику в игре.
Вот, так в «двух словах» выглядит основной класс нашего пректа.
Теперь приступим к следующему шагу, а именно к созданию полноэкранного режима.
Полноэкранный режим:
Давайте сразу разберемся, для чего это нужно. Я это делаю для коректной отрисовки фона. Ведь во время создания фона Вы задаете его размер, который должен соответствовать размеру игрового окна. И для того что бы не гадать, какого размера окно, приведем его до стандартного. Пусть это будет 1024 x 768. Это стандартный размер мониторов (по крайней мере, так нас учили на уроках информатики), и поэтому мы возьмем его. Так же Вы можете указать любой удобный для Вас размер.
И наконец мы переходим к программированию. А именно в конструктор класса Game1, после строк:
Code
graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content";
Code
graphics.PreferredBackBufferWidth = 1024; //ширина экрана graphics.PreferredBackBufferHeight = 768; //его высота graphics.IsFullScreen = true; //включаем полноэкранный режим
Как Вы заметили, в первых строках конструктора был инициализирован объект graphics класса GraphicsDeviceManager, который как раз и отвечает за настройки отображения окна. Дальше мы просто прописали поля (различные свойства, такие как ширина, вытота и тп.) этому объекту. Что они означают описано в коментариях. Единственное, на чем хочется задержать Ваше внимание, это на строке:
Code
graphics.IsFullScreen = true;
Она означает, что нашему окну, во первых, дается приоретет (т.е. оно будет поверх других окон), а во вторых содержимое окна (наша игра) развернется на весь экран, т.е.не будет ни заголовка окна, ни кнопок «свернуть» и «выйти» ни чего-либо еще.
Правда, это еще не все. Что бы выйти из такого приложения, понадобится каждый раз нажимать сочетание клавишь «Alt+F4», что не очень удобно. Для того, что бы тот же выход поставить на нужную Вам клавишу (пусть это будет Esc, которая чаще всего служит для выхода из игры), пропишите в метод Update такой код:
Code
keys = Keyboard.GetState();//Инициализация объекта keys.
if (keys.IsKeyDown(Keys.Escape))//Проверяем, нажата ли клавиша this.Exit();//Если клавиша нажата, то происходит выход
Осталось только создать объект keys класса KeyboardState. Для этого перед конструктором (после создания объектов) напишите
Code
KeyboardState keys;
Весь код класса Game1 на данный момент выглядит так:
Code
using System; using System.Collections.Generic; using System.Linq; 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.Media; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage;
namespace fon1 { /// <summary> /// This is the main type for your game /// </summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; KeyboardState keys;
public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content";
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here
base.Initialize(); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here }
/// <summary> /// UnloadContent will be called once per game and is the place to unload /// all content. /// </summary> protected override void UnloadContent() { // TODO: Unload any non ContentManager content here }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit();
keys = Keyboard.GetState();//Инициализация объекта keys.
if (keys.IsKeyDown(Keys.Escape))//Проверяем, нажата ли клавиша this.Exit();//Если клавиша нажата, то происходит выход
// TODO: Add your update logic here
base.Update(gameTime); }
/// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
base.Draw(gameTime); } } }
Все, теперь все готово, и мы можем перейти к главной теме нашей статьи, а именно к созданию фона к игре…
Создание фона:
И так, для начала давайте разберемся, что будет изображено на нашем фоне. В этом уроке я покажу Вам, как добавлять не только один слой фона (об этом позже), и поэтому сделаю так… Мы возьмем два фона. Первый, который будет на переднем плане, будет показывать нам количество жизней игрока, его очки и тп. Второй фон будет так называемым «задним фоном» и будет на заднем плане.
Так как я, увы, ничего сложнее поля для крестиков-ноликов нарисовать не могу, буду использовать не очень красивые рисунки, но, тем не менее, на их примере будет понятен принцип создания фона. Вот так должен выглядеть передний слой:
А задний слой пусть будет таким:
Все это должно в итоге выглядеть примерно так:
Обратите внимание на то, что самый передний слой должен быть в формате *.png, и место, в котором будет другой слой фона, нужно вырезать. Иначе за передним слоем ничего не будет видно. И САМОЕ ГЛАВНОЕ! Запомните! Фон должен быть размером Вашего игрового окна (у нас это 1024x768). Иначе это будет не фон, а картинка в углу экрана!
И так, если Вы подготовили необходимые Вам фоны, тогда приступим! Зайдите в XNA Game Studio и в окне «Обозреватель решений» («Solution Explorer») кликните правой кнопкой мыши на папке Content. Затем нажмите: Добавить -> Существующий элемент и выберите оба Ваших фона.
Предварительно назовите их fon1 (передний слой) и fon2 (задний слой). И так, теперь давайте пропишем необходимый код. Собственно говоря, рисование фона практически не отличается от рисования спрайта. Но, отличия все же есть. Во первых, фонов может быть несколько слоев (спрайтов тоже может быть несколько слоев, но это практически нигде не используется, в отличие от фона), а во вторых, координаты фона указывать проще, ибо просто нужно указать самое начало координатной плоскости экрана. Ведь, фон и экран одинакового размера.
И так, для начала давайте создадим две переменные. Сразу после строки
Code
KeyboardState keys;
Напииште:
Code
Texture2D fon1; Texture2D fon2;
Тем самым мы создали две переменные типа Texture2D, который как раз и используется для текстур фона, спрайтов и тп. Теперь давайте загрузим текстуры в методе LoadContent(). Сразу после строки
Этим самым мы загрузили текстуры из папки Content, под названием fon1 и fon2 и присвоили их, как значения, нашим переменным(текстура “fon1” - переменной fon1, а текстура “fon2” - переменной fon2).
Как я уже говорил, фону мы будем задавать координаты начала координатной плоскости (X = 0, Y = 0). Поэтому, это мы можем указать сразу при рисовании объекта… Хотя, их можно указать и отдельно.
Теперь осталось только нарисовать наш фон. Для этого в методе Draw(), сразу после
Code
GraphicsDevice.Clear(Color.CornflowerBlue)
Напишите:
Code
spriteBatch.Begin(); //Начинаем прорисовку (рисование) изображений на экране.
spriteBatch.Draw(fon2, new Vector2(0, 0), Color.White); //Рисуем второй слой
spriteBatch.Draw(fon1, new Vector2(0,0), Color.White); //Рисуем первый слой
spriteBatch.End();//Заканчиваем прорисовку (рисование) изображений на экране.
Весь ход рисования объектов описан в комментариях. Единственное (и самое главное) на что я хочу обратить Ваше внимание, это рисование слоев. Запомните! Чем Выше в коде написан слой, тем ниже он по приоритету (он рисуется на заднем плане). Например, у нас фон fon1 нарисуется поверх фона fon2, так как он написан после него. Я понимаю, может сначала сложно привыкнуть к таким правилам, но просто запомните. А привыкните Вы со временем.
Конечный код класса Game1 выглядит так:
Code
using System; using System.Collections.Generic; using System.Linq; 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.Media; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage;
namespace fon1 { /// <summary> /// This is the main type for your game /// </summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; KeyboardState keys; Texture2D fon1; Texture2D fon2;
public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content";
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here
base.Initialize(); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here }
/// <summary> /// UnloadContent will be called once per game and is the place to unload /// all content. /// </summary> protected override void UnloadContent() { // TODO: Unload any non ContentManager content here }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit();
keys = Keyboard.GetState();//Инициализация объекта keys.
if (keys.IsKeyDown(Keys.Escape))//Проверяем, нажата ли клавиша this.Exit();//Если клавиша нажата, то происходит выход
// TODO: Add your update logic here
base.Update(gameTime); }
/// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(); spriteBatch.Draw(fon2, new Vector2(0, 0), Color.White); spriteBatch.Draw(fon1, new Vector2(0,0), Color.White); spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime); } } }
Послесловие:
Если Вы читаете эту заключительную часть статьи, то хочу поблагодарить Вас за то, что Вы не пожалели своего времени и все же прочитали этот урок. Если у Вас будут какие-то проблемы с рисованием объектов в окне XNA – обращайтесь. Помогу по мере сил. Надеюсь, что этот урок помог Вам в освоении этой не совсем простой, но очень интересной среды разработки!
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:
Игровые объявления и предложения:
Если вас заинтересовал материал «XNA для начинающих: обзор проекта, свойства окон, игровой фон.», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела.
Предлагаются такие схожие материалы:
Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.