Опубликован: 14.08.2012 | Доступ: свободный | Студентов: 880 / 20 | Оценка: 5.00 / 5.00 | Длительность: 09:59:00
Специальности: Программист
Самостоятельная работа 3:

2D-графика в XNA

8.4. Разработка игрового компонента

Создадим новый игровой проект, назовем его P3_3. Щелкнем правой кнопкой мыши по значку проекта в панели Обозреватель проектов, выберем пункт Добавить > Создать элемент. В появившемся окне выберем миниатюру Игровой компонент, зададим имя для компонента – spriteComp и нажмем на кнопку Добавить. В проект будет добавлен новый игровой компонент. В листинге 8.6 вы можете видеть полный код этого компонента.

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;


namespace P3_3
{
    /// <summary>
    /// Это игровой компонент, реализующий интерфейс IUpdateable.
    /// </summary>
    public class spriteComp : Microsoft.Xna.Framework.GameComponent
    {
        public spriteComp(Game game)
            : base(game)
        {
            // ЗАДАЧА: здесь создаются дочерние компоненты
        }

        /// <summary>
        /// Позволяет игровому компоненту выполнить необходимую инициализацию перед\r\запуском. 
         Здесь можно запросить нужные службы и загрузить контент.
        /// 
        /// </summary>
        public override void Initialize()
        {
            // ЗАДАЧА: добавьте здесь код инициализации

            base.Initialize();
        }

        /// <summary>
        /// Позволяет игровому компоненту обновиться.
        /// </summary>
        /// >param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        public override void Update(GameTime gameTime)
        {
            // ЗАДАЧА: добавьте здесь код обновления

            base.Update(gameTime);
        }
    }
}
Листинг 8.6. Код игрового компонента, унаследованного от GameComponent

Можно отметить, что игровой компонент представляет собой класс, который наследует класс Microsoft.Xna.Framework.GameComponent. Наследование класса GameComponent подходит для создания игровых компонентов, которые не имеют графических представлений. Мы же хотим создать компонент, который планируется визуализировать. Поэтому нужно заменить GameComponent на DrawableGameComponent.

Обратите внимание на то, что созданный компонент имеет несколько методов. Так, метод spriteComp – это конструктор класса, метод Initialise предназначен для инициализации компонента, метод Update – это игровой цикл компонента.

Здесь не хватает еще одного метода – метода Draw. Добавим этот метод в класс (после ввода текста public override void нам автоматически предложат список, из которого достаточно выбрать Draw и нажать Enter – набор входных переменных и структура метода будет создана автоматически. В листинге 8.7 представлен измененный код компонента, готовый для дальнейшей работы.

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;


namespace P3_3
{
    /// <summary>
    /// Это игровой компонент, реализующий интерфейс IUpdateable.
    /// </summary>
    public class spriteComp : Microsoft.Xna.Framework.DrawableGameComponent
    {
        public spriteComp(Game game)
            : base(game)
        {
            // ЗАДАЧА: здесь создаются дочерние компоненты
        }

        /// <summary>
        /// Позволяет игровому компоненту выполнить необходимую инициализацию перед\r\запуском.  
        Здесь можно запросить нужные службы и загрузить контент.
        /// 
        /// </summary>
        public override void Initialize()
        {
            // ЗАДАЧА: добавьте здесь код инициализации

            base.Initialize();
        }

        /// <summary>
        /// Позволяет игровому компоненту обновиться.
        /// </summary>
        /// >param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        public override void Update(GameTime gameTime)
        {
            // ЗАДАЧА: добавьте здесь код обновления

            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
        }
    }
}
Листинг 8.7. Код игрового компонента, унаследованного от DrawableGameComponent

Выше мы рассматривали вывод прямоугольного изображения, которое занимало всю площадь графического файла. Нам не требовалось никаких дополнительных настроек для вывода такого изображения. На практике не очень удобно пользоваться множеством отдельных файлов, которые хранят изображения. К тому же, далеко не все изображения – это прямоугольники. Здесь нам понадобится, во-первых – более совершенный, чем Paint, инструмент для рисования, а во-вторых – несколько другая методика вывода изображений. Ранее для вывода изображения нам требовалась текстура и координата изображения в игровом окне. Теперь же понадобятся координаты положения нужного нам изображения в графическом файле.

Создадим новый графический файл. Воспользуемся для этого графическим редактором Adobe Photoshop CS. На рис. 8.10 вы можете видеть изображение в окне редактора. Обратите внимание на то, что один графический файл содержит несколько изображений, а так же на то, что фон сделан прозрачным – такая техника позволяет выводить в игровое окно рисунки сложной формы.

Создание изображений в Adobe Photoshop

Рис. 8.10. Создание изображений в Adobe Photoshop

Здесь мы создали три изображения.

Сохраним изображение в виде PNG-файла. Такие файлы поддерживают прозрачность фона. Теперь нам нужно решить еще одну задачу – определить координаты отдельных спрайтов в нашем большом изображении. Это можно сделать следующим образом. Откроем сохраненное изображение в каком-нибудь графическом редакторе, можно – в том же Photoshop CS – мы рассмотрим вопрос определения координат именно для этой программы.

Увеличим масштаб изображения, переключимся на панель Info, и, наведя мышь на пиксель левого верхнего угла изображения, запишем отобразившиеся координаты указателя (рис. 8.11). В нашем случае это (18, 9). Обратите внимание на то, что нас интересует координата, выраженная в пикселях, для правильного определения координаты в данном случае нам нужно настроить параметр Ruler Units (окно Info Options, где производится настройка, можно найти в меню палитры) на измерение в пикселях (Pixels).

Определение координат объектов в Photoshop

Рис. 8.11. Определение координат объектов в Photoshop

Точно так же узнаем координату правого нижнего угла изображения. В нашем случае это – (35, 97). Для дальнейшей работы нам понадобится знание координаты левой верхней точки прямоугольника, ограничивающего спрайт, а так же – его ширина и высота. В нашем случае ширина составляет 17 пикселей (35– 18), высота – 88 пикселей (97 – 9). В итоге получаем следующие параметры прямоугольника, в который заключен наш спрайт:

Х: 18
Y: 9
Width: 17
Height: 88

Ниже эти данные понадобятся нам.

Теперь загрузим изображение в проект и продолжим работу. Как вы помните, выше мы создали шаблон игрового компонента, который подходит для вывода на экран. Теперь доработаем этот шаблон. В листинге 8.8 вы можете видеть доработанный код игрового компонента

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;


namespace P3_3
{
    /// <summary>
    /// Это игровой компонент, реализующий интерфейс IUpdateable.
    /// </summary>
    public class spriteComp : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private Texture2D sprTexture;
        private Rectangle sprRectangle;
        private Vector2 sprPosition;

        public spriteComp(Game game, ref Texture2D newTexture, 
            Rectangle newRectangle, Vector2 newPosition
)
            : base(game)
        {
            sprTexture = newTexture;
            sprRectangle = newRectangle;
            sprPosition = newPosition;

            // ЗАДАЧА: здесь создаются дочерние компоненты
        }

        /// <summary>
        /// Позволяет игровому компоненту выполнить необходимую инициализацию перед\r\запуском.  
        Здесь можно запросить нужные службы и загрузить контент.
        /// 
        /// </summary>
        public override void Initialize()
        {
            // ЗАДАЧА: добавьте здесь код инициализации

            base.Initialize();
        }

        /// <summary>
        /// Позволяет игровому компоненту обновиться.
        /// </summary>
        /// >param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        public override void Update(GameTime gameTime)
        {
            // ЗАДАЧА: добавьте здесь код обновления

            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime)
        {
            SpriteBatch sprBatch =
                (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

            sprBatch.Draw(sprTexture, sprPosition, sprRectangle, Color.White);

            base.Draw(gameTime);
        }
    }
}
Листинг 8.8. Доработанный код игрового компонента
Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто