пятница, 22 сентября 2017 г.

Урок LibGDX Scene2D использование UI

Одна из отличных возможностей Scene2D это встроенные UI слои. Scene2D предоставляет серию виджетов для создания пользовательского интерфейса, чего так часто не хватает в библиотеках разработки игр. Тем не менее, на пути к использованию UI есть один камень преткновения … Скины.

Скин представляет собой набор файлов, которые все вместе создают пользовательский интерфейс.

Во-первых это файл в формате JSON(JavaScript Object Notation), основанный на JavaScript и который является популярным форматом для хранения данных XML. В файле JSON описываются различные свойства скина, например как должны выглядеть виджеты.

Далее идут атласы .atlas. Текстура атласа описывает расположение всех изображений, которые составляют пользовательский интерфейс.

И наконец FNT. Файл шрифтов.

Всё это может поначалу показаться сложным, особенно для новичков. К счастью есть скины включенные в тестах LibGDX. Файлы которые нас интересуют, uiskin.atlas, uiskin.json, uiskin.png, Default.png и default.fnt. Просто скачайте и скопируйте их в папку assets проекта Android. При скачивании с Github, скачайте также RAW версии каждого файла!


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

uiskin.png:

Это различная графика, для создания пользовательского интерфейса. Давайте посмотрим на uiskin.json:



{
com.badlogic.gdx.graphics.g2d.BitmapFont: { default-font: { file: default.fnt } },
com.badlogic.gdx.graphics.Color: {
    green: { a: 1, b: 0, g: 1, r: 0 },
    white: { a: 1, b: 1, g: 1, r: 1 },
    red: { a: 1, b: 0, g: 0, r: 1 },
    black: { a: 1, b: 0, g: 0, r: 0 }
},
com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable: {
    dialogDim: { name: white, color: { r: 0, g: 0, b: 0, a: 0.45 } }
},
com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: {
    default: { down: default-round-down, up: default-round },
    toggle: { down: default-round-down, checked: default-round-down, up: default-round }
},
com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: {
    default: { down: default-round-down, up: default-round, font: default-font, fontColor: white },
    toggle: { down: default-round-down, up: default-round, checked: default-round-down, font: default-font, fontColor: white, 
    downFontColor: red }
},
com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: {
    default: { vScroll: default-scroll, hScrollKnob: default-round-large, background: default-rect, hScroll: default-scroll, 
    vScrollKnob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: {
    default: {
        font: default-font, fontColor: white, background: default-select,
        scrollStyle: default,
        listStyle: { font: default-font, selection: default-select-selection }
    }
},
com.badlogic.gdx.scenes.scene2d.ui.SplitPane$SplitPaneStyle: {
    default-vertical: { handle: default-splitpane-vertical },
    default-horizontal: { handle: default-splitpane }
},
com.badlogic.gdx.scenes.scene2d.ui.Window$WindowStyle: {
    default: { titleFont: default-font, background: default-window, titleFontColor: white },
    dialog: { titleFont: default-font, background: default-window, titleFontColor: white, stageBackground: dialogDim }
},
com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle: {
    default-horizontal: { background: default-slider, knob: default-slider-knob }
},
com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: {
    default: { font: default-font, fontColor: white }
},
com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: {
    default: { selection: selection, background: textfield, font: default-font, fontColor: white, cursor: cursor }
},
com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle: {
    default: { checkboxOn: check-on, checkboxOff: check-off, font: default-font, fontColor: white }
},
com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle: {
    default: { fontColorUnselected: white, selection: default-rect-pad, fontColorSelected: white, font: default-font }
},
com.badlogic.gdx.scenes.scene2d.ui.Touchpad$TouchpadStyle: {
    default: { background: default-pane, knob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.Tree$TreeStyle: {
    default: { minus: tree-minus, plus: tree-plus, selection: default-select-selection }
}
}


Если вы когда-либо использовали CSS, то наверняка код выше выглядит знакомо.


Вы, по сути, обращаетесь к LibGDX, как к стилям каждого класса, используя полное имя класса Java. Давайте посмотрим на конкретном примере, который мы будем использовать в ближайшее время, TextButton.


com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: {
    default: { down: default-round-down, up: default-round, font: default-font, fontColor: white },
    toggle: { down: default-round-down, up: default-round, checked: default-round-down, font: default-font, 
fontColor: white, 
    downFontColor: red }
}


Вы устанавливаете значения для класса TextButtonStyle является производным от класса. Как Вы можете заметить,  для FontColor, передается цвет "white". Если вы посмотрите на скин, вы можете увидеть, как его определить:

com.badlogic.gdx.graphics.Color: {
    green: { a: 1, b: 0, g: 1, r: 0 },
    white: { a: 1, b: 1, g: 1, r: 1 },
    red: { a: 1, b: 0, g: 0, r: 1 },
    black: { a: 1, b: 0, g: 0, r: 0 }
}

Как видите "white" имеет значениями 1/1/1 для RGB и 1 для альфа .


Другая ключевая вещь, это значение down. Как вы можете видеть из TextButtonStyle, down является Drawable. Значение, указанное, default-round-down является записью в файле атласа:

default-round-down
  rotate: false
  xy: 99, 29
  size: 12, 20
  split: 5, 5, 5, 4
  orig: 12, 20
  offset: 0, 0
  index: -1

Она указывает  размер и расположение в файле uiskin.png. Более подробную информацию о Skin можно найти в вики.
Теперь, когда у вас есть  файлы скина, давайте взглянем как это можно использовать с помощью библиотеки Scene2d.ui:
package com.gamefromscratch;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;

public class UIDemo implements ApplicationListener {
    private SpriteBatch batch;
    private Skin skin;
    private Stage stage;

    @Override
    public void create() {        
        batch = new SpriteBatch();
        skin = new Skin(Gdx.files.internal("data/uiskin.json"));
        stage = new Stage();

        final TextButton button = new TextButton("Click me", skin, "default");
        
        button.setWidth(200f);
        button.setHeight(20f);
        button.setPosition(Gdx.graphics.getWidth() /2 - 100f, Gdx.graphics.getHeight()/2 - 10f);
        
        button.addListener(new ClickListener(){
            @Override 
            public void clicked(InputEvent event, float x, float y){
                button.setText("You clicked the button");
            }
        });
        
        stage.addActor(button);
        
        Gdx.input.setInputProcessor(stage);
    }

    @Override
    public void dispose() {
        batch.dispose();
    }

    @Override
    public void render() {        
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        
        batch.begin();
        stage.draw();
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}



Запустив это приложение, вы должны увидите:


На данном этапе мы уже немного разобрались . Мы создали объект Skin и загрузили его, используя IO вызовов файла. Файл, который вы нужно загрузить это JSON настройки, uiskin.json. Этот файл указывает на все все другие файлы, они будут автоматически загружены скином. Далее мы создаем TextButton, значения, передаваемые в конструктор являются текстом, отображаемым на кнопке, Skin и значения в uiskin.json. Если вы посмотрите на запись для TextButton в скине JSON файла:
com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: {
    default: { down: default-round-down, up: default-round },
    toggle: { down: default-round-down, checked: default-round-down, up: default-round }
},

Тут мы указывали, что хотим использовать запись "default". Так совпало, что если нечего не задавать, то будет использоваться значение по умолчанию. Мы позиционируем размер кнопки и настраиваем слушателя клика, который просто изменяет отображаемый текст, когда кнопка нажата. Теперь интересная часть ... виджеты UI таки как TextButton просто актеры(actors), так что они работают так же, как и другие Scene2D актеры, добавьте его на сцену, и он готов к работе.

Комментариев нет:

Отправить комментарий