Для создания GUI (графический интерфейс пользователя) в Inner Core предусмотрены огромные возможности, которые позволяют не только создавать сложный интерфейс в стиле MCPE (и не только), но и эффективно интегрировать его с остальными игровыми элементами, которые добавляются модами с помощью контейнеров.
Все размеры и координаты в интерфейсе задаются в юнитах, где 1 юнит это 1/1000 от ширины окна, в котором создается интерфейс. Если юниты используются для задания позиции и размера окна, то 1 юнит составляет 1/1000 от ширины экрана (как и в случае, когда окно открыто на весь экран).
//Частые параметры
type: "тип_элемента" - задает тип элемента.
x: число - положение элемента по горизонтали.
y: число - положение элемента по вертикали.
scale: число - сколько юнитов приходится на 1 пиксель текстуры, если этот параметр не указан, он будет равен 1.
bitmap: "текстура" - задает текстуру элементу.
//Для других элементов(частный случай)
text: "текст"- задает текст элементу.
color: цвет - задает цвет,
font: шрифт_текста- задает параметры шрифта, имеет следующий вид:
{color: цвет, shadow: тень(число от 0 до 1), size: размер(в юнитах)}
bg: "текстура" - задает текстуру фона
bitmap2: "текстура" - аналогично.
width: число - ширина элемента.
height: число - высота элемента.
Текстуры интерфейса, которые находятся в папке gui вашего мода, будут загруженны и доступны под именем файла без расширения: "gui/slot.png" будет загружен как "slot". Также возможно использование объекта Bitmap вместо имени файла, если возникает такая необходимость.
Цвет задается с помощью метода класса android.api.android.graphics.Color.rgb(r, g, b) - где r, g и b - красная, зеленая и синяя составляющие цвета от 0 до 255 каждая.
Текстурой рамки является текстура размера 16x16, изображающая нужную рамку самого маленького размера, которая будет потом растянута до любых размеров. </div>
Любой интерфейс имеет объект описания, позволяющий задать данный интерфейс и динамично изменять его, меняя этот объект, пока интерфейс открыт. Объект описания любого типа имеет значения drawing (массив) и elements (объект), которые задают отрисовку фона и элементы соответственно. Их изменение из любого места ведет к динамичному изменению интерфейса, если он открыт. Т.е если вы изменените параметры какого-то элемента или команды отрисовки, то интерфейс изменится в соответствии с вашими изменениями.
Элементы отрисовки задаются в объекте описания в массиве drawing и отвечают за отрисовку фона интерфейса. Стоит учесть что каждый элемент будет накладываться послойно(т.е 2й элемент будет сверху 1го и тд).
drawing: [
{/* параметры элемента 1 */},
{/* параметры элемента 2 */},
{/* параметры элемента 3 */},
//....
]
/*Background*/ {type: "background", color: цвет}
/*Bitmap*/ {type: "bitmap", bitmap: "текстура", x: число, y: число, scale: число}
/*Frame*/ {type: "frame", x: число, y: число, width: число, height: число, bitmap: "текстура_рамки", bg: цвет, scale: число}
/*Text*/ {type: "text", text: "текст", x: число, y: число, font: шрифт_текста}
/*Line*/ {type: "line", x1: число, y1: число, x2: число, y2: число, width: число, color: цвет}
Background Заполняет весь фон указанным цветом.
Bitmap Отрисовывает данную текстуру на данных координатах.
Frame Отрисовывает рамку данного размера на данных координатах.
Text Отрисовывает данный текст на данных координатах с данным шрифтом.
Line Отрисовывает линию от x1 и y1 до x2 и y2. width - толщина линии в юнитах, по-умолчанию 1, color - цвет линии, по-умолчанию черный.
Элементы задаются в объекте описания в объекте elements, каждый элемент должен иметь уникальное имя. По этим именам с ними можно будет взаимодействовать позже.
elements: {
"name1": {/* элемент 1 */},
"name2": {/* элемент 2 */},
"name3": {/* элемент 3 */},
//....
}
Формат объекта:
{
onClick: function(position, container, tileEntity, window, canvas, scale){
// если задан, задает функцию короткого нажатия
},
onLongClick: function(position, container, tileEntity, window, canvas, scale){
// если задан, задает функцию долгого нажатия
}
//возвращаемые параметры
//position - возвращает позицию касания
// container - контейнер, для которого открыт данный интерфейс
// tileEntity - если интерфейс открыт для какого то tile entity, то передаст его, иначе null
//window - возвращает окно с которого было воспроизведено нажатие
//canvas - возвращает канвас ??
//scale размер элемента ??
}
{type: "slot", x: число, y: число, size: число, visual: bool, bitmap: "текстура", clicker: объект функций клика, needClean: bool, isTransparentBackground: bool}
{type: "invSlot", x: число, y: число, size: число, index: число, bitmap: "текстура"}
{type: "button", x: число, y: число, bitmap: "текстура", bitmap2: "текстура", scale: число, clicker: объект функций клика}
{type: "closeButton", x: число, y: число, global: лог.значение, bitmap: "текстура", bitmap2: "текстура", scale: число}
{type: "scale", x: число, y: число, direction: число, bitmap: "текстура", scale: число, invert: bool, overlay: "текстура", overlayScale: число, overlayOffset: {x: число, y: число}}
overlay - если задан, накладывает на шкалу дополнительную текстуру, которая перекрывает ее. overlayScale - параметр scale для перекрытия. overlayOffset: {x: , y: } - если задан, задает позицию перекрытия, относительно позиции шкалы.
Направления:
{type: "text", x: число, y: число, width: число, height: число, text: "текст", font: шрифт_текста}
{type: "image", x: число, y: число, bitmap: "текстура", scale: число, overlay: "текстура", overlayScale: число, overlayOffset: {x: число, y: число}, clicker: объект функций клика}
Кроме drawing и elements в объекте описания можно определить объект стилизации интерфейса для изменения стандартных текстур элементов.
Если какое-то из нижеприведённых значений будет указано в объекте стилизации, оно заменит стандартый параметр.
params: {
slot: "текстура слота",
invSlot: "текстура слота инвентаря",
frame: "текстура обычной рамки",
selection: "текстура выделения слота",
closeButton: "текстура кнопки закрытия",
closeButton2: "текстура нажатой кнопки закрытия",
}
Интерфейс бывает 3 типов: однооконный, многооконный и стандартный. В данной главе будет рассмотрен только последний, как самый простой в использовании и при этом эффективный и применимый в большинстве случаев. Объект интерфейса во всех этих случаев создается как объект класса одного из типов, после создания такой объект класса может быть настроен и открыт для любого контейнера.
Любой интерфейс может быть протестирован с помощью функции UI.testUI(объект интерфейса);
Создается как объект класса UI.StandartWindow, которому может быть передан объект описания.
Пример использования:
var testUiScreen = UI.StandartWindow({/* ... пустой объект описания ... */});
UI.testUI(testUiScreen); // откроет полностью пустой интерфейс
Формат объекта описания стандартного типа интерфейса:
{
standart: { // стандартные параметы, поддерживаемые данным типом интерфейса, позволяют быстро задавать базовые элементы, такие как заголовок, фон и инвентарь
// если хотите определить какой то стандартный элемент, но оставить его без изменений, то пропишите там единственное значение - standart: true, например inventory: {standart: true}
header: { // определите, если вам нужен заголовок, заголовок содержит кнопку закрытия
text: { // обязательный параметр, если заголовок определен
text: "текст заголовка", // содержание текста, обязательный параметр
},
font: {...}, // фонт текста, определите, если хотите изменить стандартный
color: цвет, // нужен только, если вы хотите изменить цвет заголовка
frame: "текстура рамки", // нужно только, если вы хотите изменить текстуру рамки заголовка
width: 80, // высота заголовка в юнитах,
hideButton: true, // определите и установите значение на true, чтобы убрать кнопку закрытия
},
inventory: { // для определения стандартного инвентаря используйте inventory: {standart: true}
width: 300, // ширина окна инвентаря
padding: 20, // паддинг окна инвентаря
},
background: { // для определения стандартного фона используйте background: {standart: true}
color: цвет, // определите, если хотите изменить цвет фона
bitmap: "текстура фона", // определите, если хотите добавить текстуру фона
frame: "текстура рамки" // определите, если хотите добавить рамку
},
minHeight: 650, // если высота окна в юнитах меньше этого параметра, окно будет прокручиваться так, чтобы его внутренний размер составлял по высоте minHeight юнитов
},
params: {
// стилизация (изменение стандартных текстур)
},
drawing: [/* команды отрисовки фона */],
elements: {/* описание элементов */}
}
Как пример использован реальный интерфейс из таумкрафта (реактор аспектов).
Для того, чтобы пример работал, установите таумкрафт или скопируйте оттуда нужные текстуры интерфейса (которые используются в объекте описания интерфейса).
var aspectReactorGui = new UI.StandartWindow({
standart: {
header: {
text: {
text: "Aspect reactor"
},
color: android.graphics.Color.rgb(0x47, 0x26, 0x0c),
frame: "thaum_frame_header"
},
inventory: {
standart: true
},
background: {
bitmap: "thaum_background"
},
minHeight: 600
},
params: {
textures: {
slot: "thaum_slot",
invSlot: "thaum_inv_slot",
selection: "thaum_selection",
closeButton: "thaum_close_button_up",
closeButton2: "thaum_close_button_down",
frame: "thaum_frame_default"
}
},
drawing: [
{type: "bitmap", x: 842, y: 104, bitmap: "aspect_scale_background", scale: 4},
{type: "bitmap", x: 560, y: 100, bitmap: "aspect_reactor_background", scale: 360 / 128},
],
elements: {
"slot1": {type: "slot", x: 400, y: 100, size: 160},
"slot2": {type: "slot", x: 400, y: 300, size: 160},
"aspectScale": {type: "scale", x: 850, y: 120, direction: 1, scale: 8, value: 1, bitmap: "aspectScale_nitor", overlay: "aspect_scale_overlay_1", overlayScale: 4},
"stateText": {type: "text", x: 625, y: 227, width: 90, height: 100, text: "", font: {color: android.graphics.Color.WHITE, shadow: .6, size: 25}}
}
});
UI.testUI(aspectReactorGui); // тестовое открытие после создания
// добавляем созданный интерфейс нашему tile entity из прошлых глав
IDRegistry.genBlockID("testBlock");
// ...
// создаем блок
TileEntity.registerPrototype(BlockID.testBlock, {
defaultValues: {
someValue: 0 // сохраняемое значение someValue, по умолчанию 0
},
tick: function(){
// что то сделать каждый тик, к примеру выводим someValue
Debug.message(this.data.someValue);
},
click: function(id, count, data, coords){
this.data.someValue = 1; // установить значение someValue на 1
},
getGuiScreen: function(){
return aspectReactorGui; // при попытке открыть интерфейс, возвращаем наш объект интерфейса
}
// остальные события не трогаем
});