libGDX. Урок 4. Отображение текста.

Сейчас мы с вами научимся отображать текст (текстовые сообщения) на экране вашего Android устройства или эмулятора. Благодаря сообщениям пользователю будет ясно, какое действие он должен предпринять.

 

ОТОБРАЖЕНИЕ ТЕКСТА

Мы уже с вами создали разные и достаточно логичные состояния, в которых может находится наша игра. Но до сих пор не показываем пользователю, выиграл он или нет. Также мы не отображаем никакой информации о том, какой действие ожидает от него наша игра. В этом уроке будем разбираться с классом BitmapFont, который предоставляет нам libGDX для отображения текста на экране.

Нам потребуется создать собственный класс и дать ему имя TextManager, в котором будем обрабатывать всю отрисовку текстовых сообщений. Но сперва нужно внести небольшие изменения в уже существующем коде. Мы введём новую переменную hasWon типа Boolean в классе GameManager, с помощью которой будем определять победил ли пользователь или нет:

static Level level;
static boolean hasWon = false;

Установим эту переменную в классе InputManager. Изменения в коде выделены:

case CONFIRM:
    door.isOpen = true; //открыть выбранную дверь
    if(!door.isGoat){
    GameManager.hasWon=true;
    }
    GameManager.level = GameManager.Level.END;
    //меняем состояние нашей игры на END
    break;

Теперь создайте новый класс в пакете com.door.managers и дайте ему имя TextManager. Введите в этот класс следующий код:

import com.badlogic.gdx.graphics.Color;
        import com.badlogic.gdx.graphics.g2d.BitmapFont;
        import com.badlogic.gdx.graphics.g2d.GlyphLayout;
        import com.badlogic.gdx.graphics.g2d.SpriteBatch;



public class TextManager {

    static BitmapFont font; //мы будем отображать текст на экране
    //используя эту переменную

    //Текст, относящийся к разным состояниям
    static String start = "Select a door";
    static StringBuffer confirm;
    static String win = "You Win!";
    static String lose = "You Lose!";
    //высоты и ширина области просмотра
    static float width,height;

    public static void initialize(float width,float height){

        TextManager.width = width;
        TextManager.height= height;
        //установим цвет шрифта - cyan
        font = new BitmapFont();
        font.setColor(Color.CYAN);
        //масштабируем размер шрифта в соответствии с шириной экрана
        font.getData().setScale(width/800f);

        confirm = new StringBuffer( (String) "You selected door no.Do you want to switch or stay?");
    }

    public static void displayMessage(SpriteBatch batch){

        GlyphLayout glyphLayout = new GlyphLayout(); //используем класс GlyphLayout

        switch(GameManager.level){
            case START:
                //вычисления для определения позиции сообщения на экране
                glyphLayout.setText(font, start);
                font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
                break;
            case CONFIRM:
                glyphLayout.setText(font, confirm);
                font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
                break;
            case END:
                // отображаем победный/проигрышный вариант текста в зависимости от значения переменной hasWon
                if(GameManager.hasWon) {
                    glyphLayout.setText(font, win);
                    font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
                }
                else {
                    glyphLayout.setText(font, lose);
                    font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
                }
                break;
        }
    }

    public static void setSelectedDoor(int doorIndex){
        //вставляем номер выбранной пользователем двери в текст строки confirm
        confirm.insert(confirm.indexOf("door no")+ "door no".length(), " "+(doorIndex+1));
    }
}

С начала мы объявили экземпляр класса BitmapFont, который будем использовать для отображения текста. Далее объявили строку (String), которую собираемся отображать, когда пользователь находится в состоянии START. Для хранения сообщения в состоянии CONFIRM мы используем StringBuffer потому что нам нужно будет модифицировать текст с учетом двери, которую выбрал пользователь. После, мы объявили переменные width и height. Они нам понадобятся для корректного позиционирования текста на экране.

Потом мы создали метод initialize() для задания начальных значений некоторых переменных. В качестве аргументов этот метод принимает width и height, которые будем передавать из класса GameManager:

public static void initialize(float width,float height){

Первыми строками мы установили разрешение экрана. Далее создали экземпляр класса BitmapFont (по умолчанию 15pt, Arial):

font = new BitmapFont();

Мы можем использовать свой шрифт и этому будет посвящен отдельный урок. Далее мы установили цвет текста:

font.setColor(Color.CYAN);

После чего отмасштабировали шрифт соответственно нашим требованиям:

font.getData().setScale(width/800f);

Данный метод мы вызовем в методе initialize() класса GameManager и передадим ему размеры области видимости в качестве параметров:

public static void initialize(float width,float height){
    //код метода initialize()
    TextManager.initialize(width, height);
}

Также в классе TextManager мы создали метод setSelectedDoor, который отвечает за то, чтобы вставлять в текст для отображения в состоянии CONFIRM номер двери, которую выбрал пользователь.

Этот метод будет вызван в классе InputManager, в методе handleDoor():

//меняем состояние нашей игры на CONFIRM
GameManager.level = GameManager.Level.CONFIRM;
TextManager.setSelectedDoor(doorIndex);
break;

 
Помимо прочего в классе TextManager мы создали метод displayMessage(), который в качестве параметра принимает объект класса SpriteBatch. В этом методе с помощью switch мы определим, какое сообщение в данный момент должно быть отображено на экране. В случаях с START и CONFIRM мы отображаем стандартные сообщения, а в случае END основываемся на том, выиграл ли пользователь или проиграл:

public static void displayMessage(SpriteBatch batch){

    GlyphLayout glyphLayout = new GlyphLayout(); //используем класс GlyphLayout

    switch(GameManager.level){
        case START:
            //вычисления для определения позиции сообщения на экране
            glyphLayout.setText(font, start);
            font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
            break;
        case CONFIRM:
            glyphLayout.setText(font, confirm);
            font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
            break;
        case END:
            // отображаем победный/проигрышный вариант текста в зависимости от значения переменной hasWon
            if(GameManager.hasWon) {
                glyphLayout.setText(font, win);
                font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
            }
            else {
                glyphLayout.setText(font, lose);
                font.draw(batch, glyphLayout, (width/2 - glyphLayout.width/2), GameManager.doors.first().closeSprite.getY()/2 + glyphLayout.height/2);
            }
            break;
    }
}

Мы используем метод draw класса BitmapFont, который в нашем случае принимает 4 (четыре) аргумента: 1 – экземпляр класса SpriteBatch (используется для рисования); 2 – экземпляр класса GlyphLayout (хранит в себе данные шрифта и текст); 3 – расположение по оси X; 4 – расположение по оси Y.

Ну и чтобы удостоверить в том, что мы всё сделали верно, нам необходимо вызвать метод displayMessage() класса TextManager в методе renderGame() класса GameManager. Добавьте следующую строку в конце метода renderGame():

TextManager.displayMessage(batch);

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

libGDX, android studio

 
Весь код с этого урока доступен для скачивания внизу:

Скачать исходники