Возможно вы искали: 'Space Ark'

May 12 2025 01:25:41
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96030355
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18346
• Обзор The Walking ... 18789
• Обзор DMC: Devil M... 19864
• Обзор на игру Valk... 15867
• Обзор на игру Stars! 17754
• Обзор на Far Cry 3 17935
• Обзор на Resident ... 16012
• Обзор на Chivalry:... 17495
• Обзор на игру Kerb... 17970
• Обзор игры 007: Fr... 16604
Превью о играх
• Превью к игре Comp... 17946
• Превью о игре Mage... 14451
• Превью Incredible ... 14706
• Превью Firefall 13462
• Превью Dead Space 3 16325
• Превью о игре SimC... 14717
• Превью к игре Fuse 15432
• Превью Red Orche... 15532
• Превью Gothic 3 16334
• Превью Black & W... 17345
Главная » Статьи » Всё о XNA » Записки программиста XNA - разработка GUI

Записки программиста XNA - разработка GUI

Так уж случилось, что мне пришлось довольно много времени уделить разработке GUI компонент (контролов). Наиболее известные/популярные технологии в .NET это : WinForms — враперы для стандартных контролов Windows OS и новый и красивый WPF (уже не так уж новый, и далеко не такой красивый... вы уж мне поверьте :( ). Но не будем об грустном :), ведь под XNA стандартных контролов нет (хотя есть много готовых и бесплатных решений) и  нам будет надо делать самим. 

Хочу вас сразу застеречь, что написанное является опысом моих решений стоящих перед до мной вопросом и не является окончательной реализацией GUI (уверен найдется что-то что я не учел). 

Введение

Создание Gui элетента делится на две важных для нас части — рендеринг и логика. В свою очередь рендеринг делится на рисование и компоновки элемента, а логика на роботу с вводом, обработка данных и т.д. На схеме показаны только те части о которых пойдет речь.
articles: GUIXNA01.png

1) Layout 
Наиболее сложный вопрос при создании интерфейса — правильная компоновка. Конечно что ее можно сделать вручную задав размеры и позицию каждому элементу, но в динамическом интерфейсе такой вариант неприемлем. В WPFе этим делом занимаются компоновочные элементы (GuiContainer). Реализуется компоновка в два шага 
• измерение нужных размеров
• расстановка элементов

Сначала компоновочные элементы измеряют свои под-элементы, потом размещают в зависимости от реализированой логики. 

Чтобы сделать первое у элемента есть методы  
public Point Measure(Point point) 
protected virtual Point OnMeasure(Point point)

 


Первый реализует базовую логику работы с пропертями Padding ( отступ изнутри ), Margin ( отступ снаружи ), Width и Height (ширина и высота элемента). Проперти Width и Height имеют тип int? и могут быть не заданными. В таком случае размер считается по контенту.  Второй метод служат для измерения контента элемента (тест, картинка, под-елементы).
Расстановка элементов осуществляется методами 

public void Layout(Rectangle rect)
protected virtual void OnLayout(Rectangle rect)

 


Как и с Measure, первый реализует базовую логику работы Padding и Margin, а также пропертями HAlignment и VAlignment (смещение элемента относительно области расстановки). Второй метод – для расстановки контента.

Пример. В качестве примера рассмотрим реализацию класса StackPanel. Этот контейнер умеет размещать элементы один за другим в горизонтальном или вертикальном порядке (StackPanel.Orientation). В методе OnMeasure нам надо посчитать размер его контента – под-элементов. Пусть Orientation равен Horizontal, тогда ширина равна суме всех ширин элементов, а высота – наибольшая высота элементов. Реализация метода OnLayout похожа, только теперь мы уже размещаем элементы в нужном месте.

Домашнее задание – реализировать WrapPanel, унаследованную от GuiContainer. Этот контейнер должен размещать элементы в ряд (как буквы в текстовом редакторе). Если ряд выходить за границы элемента, мы начинаем новую строку.
articles: GUIXNA02.png

2) Drawing
Пожалуй наиболее легкий но и самый не определенный вопрос.Есть много способов для того чтобы отрисовать элемент. Для начала выберем чем же мы будем отрисовывать. Простой вариант — графические примитивы.Это довольно просто и удобно, но создать сложный и красивый интерфейс примитивами почти невозможно. Потому я сразу перехожу к варианту с текстурами и SpriteBatch. Текстурами можно отрисовать почти любой интерфейс, хотя нет такой «вседозволенности». Для отрисовки у нас есть виртуальный метод 
 
public virtual void Draw(SpriteBatch sprite)

 

 
Так как каждый элемент у нас должен иметь свою внешность, стандартной реализации у него нет (кроме компоновочных элементов которые отрисовывают свои под-элементы). А это значит что для каждого элемента вам надо будет самим реализовать такой метод.
Но все же чтобы упростить нам задачу с рисованием, мы добавим новый абстрактный класс — GuiDrawable. Этот объект представляет собой некий примитив, способный отрисоватся в указанную область. У него есть единственный абстрактный метод, 
 
public abstract void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color);

 

 
но возможно в дальнейшем вы захотите расширить функционал добавив например метод для рисования с поворотом, и т.д. 

Класс TextureDrawable демонстрирует роботу простого GuiDrawable. Он просто обрисовывает текстуру в прямоугольник. Но зачем нам еще один класс, если можно просто отрисовать текстуру? Проблема в том, что иногда надо простой текстуры не достаточно. Например если рисовать одной текстурой элементы разных размеров, то они растягиваются и получается не очень красиво. Пример решения данной проблемы класс —  BorderDrawable. Этот класс рисует текстуру таким образом, что растягивается только ее центральная часть, Вертикальные и горизонтальные края  растягиваются только в своем направлении. Углы остаются без изменений в углах прямоугольника. Вы можете реализовать угодную вам реализацию этого класса.
 
Домашнее задание - реализовать класс анимации унаследованный от GuiDrawable. Пусть в классе будет массив текстур, и на каждом  вызове Draw рисуем следующею. Когда прошли все текстуры, начинаем заново.

3) Logic / Input
А собственно вопрос логики мы решать не будем, так как и внешность, так и логика у каждого Gui элемента своя. Для ее реализации у нас есть простой виртуальный метод 
 
public virtual void Update(GameTime gameTime)

 

 
который вы реализуете для каждого елемента по своему (или не реализуете).
Но мы решим вопрос с вводом. Для этого у нас есть компонента InputComponent(для доступа к компоненте, мы добавляем ее в сервисы). Все что он делает — это на каждом апдейте сохраняет текущее и предыдущее состояние мыши и клавиатуры (реализацию геймпада я не делал). Также есть несколько пропертей для проверки состояния мыши. Это все что нам надо. 
Обработка ввода у нас будет осуществляется методами 
 
public virtual void OnMouse\Keyboard <что-то там>(InputComponent input)
 
Единственым вопросом который остался - какой элемент должен оброблять ввод?
 
3a) Mouse
Мышь у нас будет оброблять элемент над которым она находится или элемент который ее захватил (например кнопка). Для реализации первого у каждого элемента есть метод 
 
public virtual GuiElement HitTest(int x, int y)

 

 
который возвращает элемент по которому попал курсор мыши. В базовой реализации, элемент возвращает самого себя. В базовой реализации контейнеров, возвращает также и свои под-элементы.
Реализацией второго варианта есть методы 
 
public void CaptureMouse(GuiElement element)
public void ReleaseMouse(GuiElement element)

 

 
класса GuiManager. Элемент который захватил мышь будет обрабатывать все изменения мыши пока не будет вызван метод  ReleaseMouse.
 
3b) Keyboard
С обработкой клавиатуры все проще, ее обробляет элемент на котором есть фокус. Элемент на котором должен быть фокус задается пропертей 
 
public GuiElement FocusedElement

 

 
класса GuiManager. котором должен быть фокус задается пропертей. Есть несколько способов передачи фокуса : по нажатию какой нибудь клавиши, по нажатию мыши, в результате выполнения некого условия логики GUI. В примере, фокус использует только элемент TextEditBox по нажатию мыши на элементе.
 
Домашнее задание - реализовать элемент TrackBar\ScrolBar унаследованный от GuiElement.  Вам будет нужно добавить две проперти типа GuiDrawable для ползунка и фону. При нажатии на ползунку элемент должен захватить мышь.

articles: GUIXNA03.png

ContentElement 
ContentElement – особый класс элементов, конечный контент которых не определен. Поэтому в качестве контента в нем служит его единственный под-элемент.
 
Пример. Клас ContentButton – реализует элемент «кнопка». Но так как в кнопке может быть текст или рисунок, или то и другое вместе (или еще что-то), то контентом его есть неопределенным. Унаследовал это от  ContentElement в зависимости от случая мы можем поместить в него или элемент текста (TextBlock) или элемент картинки (ImageBlock).
 
GuiManager
Класс GuiManager – компонента которая отрисовывает и апдейтит элементы GUI. Для добавления элементов есть пропертя GuiElement RootElement. Так как это не коллекция, то можно задать только один элемент. В большинстве случаев этим элементом есть компоновочный элемент.
 
GuiManager.Update
В методе void Update(GameTime gameTime) заключена вся логика работы менеджера, поэтому очень важно понять принцип его работы. В этом нам поможет маленькая диаграмма.

articles: GUIXNA04.png


На вопрос – «почему обработка ввода и апдейт элементов идет первым», ответ – «потому что во время апдейта или обработка ввода, возможно надо пересчитать все заново, как например в редакторе текста».
 
Оптимизация           
Возможны несколько вариантов оптимизации, вот два из них :
  • оптимизировать Layout перерасчетом не всего дерева, а только тех ветвей которые надо пересчитать (например если у контейнера установлен размер вручную, то надо пересчитать размер только его под-элементов)
  • оптимизировать прорисовку отрисовав все на текстуру и перерисовывать только по надобности.
 
Заключение
Вот и все, я старался не делать очень много кода (ну не очень получилось :/ ). Хочется верить что это поможет вам в реализации своего полноценного GUI.

1589 Прочтений •  [Записки программиста XNA - разработка GUI] [08.08.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Записки программиста XNA - разработ... Ukraine Vova 08.08.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка