понедельник, 20 февраля 2012 г.

Быстрое создание GUI для XNA 4.0

Здравствуйте.
Сейчас я расскажу, как можно быстро создать GUI для игрового приложения на XNA 4.0.  Специально к этой статье я написал свой конвертор для конвертирования Windows Form класса в класс Neoforce Control.
Начнем сразу с примера и добавим GUI в приложения с домиком из этой статьи.

Этап I
Создадим Windows Form Application и построим следующую форму.






На этой форме имеется три TrackBar и три Label. У каждого TrackBar установим свойства Maximum в 360. Эта форма будет отвечать за вращение нашего домика.

Из этого проекта c только что созданной формой нам понадобиться только один файл Form1.Disigner.cs .
Далее откроем программу для конвертирования классов(Neoforce GUI Builder) и в качестве input file выберем класс из только что созданного проекта Windows Form, а именно Form1.Disigner.cs. Далее укажем, куда сохранить сконвертированный класс. И нажмем на кнопку Convert. Таким образом, мы создадим наш класс GUI для приложения XNA 4.0.







 Этап II
Наша форма готова теперь осталось лишь только в проекте с игрой добавить в качестве контента скин формы и две ссылки.  Шаблон скина и собственно сам скин и все DLL я приложу ко всем файлам. В проект Home нужно добавить две ссылки как показано на рисунке. В этот же проект нужно добавить в контент всю папку Skins и в качестве импортера файла Skin.xml выбрать Skin neoforce controls.








Далее в проект добавим сконвертированный класс из этапа I.



using TomShane.Neoforce.Controls;
using Microsoft.Xna.Framework;
namespace GUI
{
    sealed class Dialog1 : Window
    {
        public Label label1;
        public Label label2;
        public Label label3;
        public TrackBar trackBarRotX;
        public TrackBar trackBarRotY;
        public TrackBar trackBarRotZ;
        public Dialog1(Manager manager)
            : base(manager)
        {
            label1 = new Label(manager);
            this.label1.Text = "Rotation X";
            label1.Init();
            label1.Left = 12;
            label1.Top = 19;
            label1.Width = 57;
            label1.Height = 13;
            label1.Parent = this;

            label2 = new Label(manager);
            this.label2.Text = "Rotation Y";
            label2.Init();
            label2.Left = 15;
            label2.Top = 86;
            label2.Width = 57;
            label2.Height = 13;
            label2.Parent = this;

            label3 = new Label(manager);
            this.label3.Text = "Ratation Z";
            label3.Init();
            label3.Left = 9;
            label3.Top = 150;
            label3.Width = 57;
            label3.Height = 13;
            label3.Parent = this;

            trackBarRotX = new TrackBar(manager);
            this.trackBarRotX.Range = 360;
            trackBarRotX.Init();
            trackBarRotX.Left = 12;
            trackBarRotX.Top = 35;
            trackBarRotX.Width = 258;
            trackBarRotX.Height = 45;
            trackBarRotX.Parent = this;

            trackBarRotY = new TrackBar(manager);
            this.trackBarRotY.Range = 360;
            trackBarRotY.Init();
            trackBarRotY.Left = 15;
            trackBarRotY.Top = 102;
            trackBarRotY.Width = 258;
            trackBarRotY.Height = 45;
            trackBarRotY.Parent = this;

            trackBarRotZ = new TrackBar(manager);
            this.trackBarRotZ.Range = 360;
            trackBarRotZ.Init();
            trackBarRotZ.Left = 12;
            trackBarRotZ.Top = 179;
            trackBarRotZ.Width = 258;
            trackBarRotZ.Height = 45;
            trackBarRotZ.Parent = this;

            this.Width = 313;
            this.Height = 268;
            this.Text = "Game Panel";
        }
    }
}



Этап III
Далее подключим пространство имен в GUI в файле MyGame.cs.


using GUI;
 using TomShane.Neoforce.Controls;


И добавим следующие переменные
private float _rotX;
 private float _rotY;
 private float _rotZ;
 private Dialog1 _gamePanel;
 private Manager _guiManager;


Далее инициализируем наши переменные в методе Initialize
_guiManager = new Manager(this, graphics, "Green");
_guiManager.Initialize();
_gamePanel = new Dialog1(_guiManager);
_gamePanel.Init();


Этап IV


using GUI;
using TomShane.Neoforce.Controls;


И добавим следующие переменные


private float _rotX;
private float _rotY;
private float _rotZ;
private Dialog1 _gamePanel;
private Manager _guiManager;


Далее инициализируем наши переменные в методе Initialize
_guiManager = new Manager(this, graphics, "Green");
_guiManager.Initialize();
_gamePanel = new Dialog1(_guiManager);
_gamePanel.Init();


Не забудьте в менеджер добавить форму


_guiManager.Add(_gamePanel);
IsMouseVisible = true


В методе Update нужно добавить
_guiManager.Update(gameTime);


В метод Draw


protected override void Draw(GameTime gameTime)
{
   _guiManager.BeginDraw(gameTime);
   //Рисуем GUI
   _guiManager.Draw(gameTime);
   //Рисуем модель
   GraphicsDevice.DepthStencilState = DepthStencilState.Default;
   DrawModel(_home, _world, _view, _proj);

   spriteBatch.Begin();
   spriteBatch.DrawString(_font, "Hello word", new Vector2(10, 10), Color.Red);
   spriteBatch.End();
 
   _guiManager.EndDraw();
   base.Draw(gameTime);
}


Метод вращения


void Rotate(out Matrix parWorld, float parRotX, float parRotY, float parRotZ) 
{
   parWorld = Matrix.Identity;
   parWorld = Matrix.CreateRotationZ(MathHelper.ToRadians(parRotZ)) * 
   Matrix.CreateRotationY(MathHelper.ToRadians(parRotY)) * 
   Matrix.CreateRotationX(MathHelper.ToRadians(parRotX)); ;
}


Далее напишем обработчики событий.


void trackBarRotZ_ValueChanged(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
  _rotZ = _gamePanel.trackBarRotZ.Value;
  Rotate(out _world,_rotX, _rotY, _rotZ);          
}

void trackBarRotY_ValueChanged(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
   _rotY = _gamePanel.trackBarRotY.Value;
   Rotate(out _world, _rotX, _rotY, _rotZ);
}
void trackBarRotX_ValueChanged(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
   _rotX = _gamePanel.trackBarRotX.Value;
   Rotate(out _world, _rotX, _rotY, _rotZ);
}


Материалы к статье


  • HomeGUI.rar исходник к этой статье. ( Все сборки содержаться в архиве в /Home/bin)
  • Neoforce GUI Builder. Конвертер классов.  


Все это можно скачать по ссылке.


На этом все.

3 комментария:

  1. Очень хорошо излагаете, понятно, последовательно, хотя я не работала с XNA :)
    У Вас крутой проект, Вы бы могли защитить его как дипломный проект!
    Единственное, что лучше переименовывать компоненты вроде label1, label2, давая названия по назначению, а так код хороший :)

    ОтветитьУдалить
  2. Отличная статья, большое спасибо:) :)
    можно добавить, что не надо называть элементы формы по-русски)))))) Пока дошло в чём дело - прошло 3 часа, а проект большой, половину и там и там перелопатил:D

    ОтветитьУдалить
  3. почему при использовании этого движка у меня теперь текстура неправильно накладывается вот мой вопрос : http://otvety.google.ru/otvety/thread?tid=1b7bacbe1c4404b5&table=%2Fotvety%2Fuser%3Fclk%3Dlftpn%26userid%3D06292739056880534858%26tab%3Dwtmtoa

    ОтветитьУдалить