Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Документация для продвинутых пользователей
                Взаимодействие с GUI в Java

Взаимодействие с GUI в Java

Опубликованно: 20.08.2017, 21:06
Последняя редакция, Andry: 13.05.2018 14:40
  1. Концепция Nifty GUI
  2. Nifty GUI Рекомендации
  3. Nifty GUI XML Компоновка или Nifty GUI Java Компоновка
  4. Nifty GUI Накладывается или Nifty GUI Проецируется
  5. Nifty GUI Java Взаимодействие
  6. В предыдущих уроках вы создали двуэкранный пользовательский интерфейс. Но он все еще статичен, и когда вы нажимаете кнопки, ничего не происходит. Предназначение GUI это общение с вашими Java-классами: Ваша игра должна знать, куда пользователи щелкнули, какие настройки они выбрали, какие значения они ввели в текстовое поле и.т.п. . Точно так же и пользователь должен знать, состояние игры когда он играет (Очки, здоровье и.т.п.).

    Подключить GUI к Java-контроллеру

    Чтобы позволить Nifty экрану взаимодействовать с приложением Java, вы регистрируете ScreenController на каждом NiftyGUI экране. Вы создаете ScreenController, создавая Java класс, который реализует интерфейс de.lessvoid.nifty.screen.ScreenController и его абстрактные методы.

    Создайте AppState файл MyStartScreen.java в своем пакете. (Кликнув [ПК Мыши] на вашем пакете ▸ Новый ▸ Другое … ▸ JME3 Classes ▸ New BaseAppState)

    Поскольку вы пишете jME3 приложение, вы можете дополнительно сделать класс ScreenController расширением класса BaseAppState! Это дает ScreenController доступ к объекту приложения и циклу обновления!

    Теперь добавьте implements ScreenController в public class MyStartScreen extends BaseAppState{ и добавляет import de.lessvoid.nifty.screen.ScreenController;

    Продолжайте добавлять:

    import de.lessvoid.nifty.screen.Screen;
    
    ...
    
    public void bind(Nifty nifty, Screen screen) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    public void onStartScreen() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    public void onEndScreen() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    Полный BaseAppState файл

    package mygame;
    
    import com.jme3.app.Application;
    import com.jme3.app.state.BaseAppState;
    import de.lessvoid.nifty.Nifty;
    import de.lessvoid.nifty.screen.Screen;
    import de.lessvoid.nifty.screen.ScreenController;
    
    public class MyStartScreen extends BaseAppState implements ScreenController {
    
      @Override
      protected void initialize(Application app) {
          //Технически безопасно выполнять всю инициализацию и очистку в методах 
          //onEnable()/onDisable(). Выбор использования initialize() и
          //cleanup() для этого, дело эффективности для конкретного
          //разработчика.
          //TODO: инициализацию AppState, например присоединить spatials к rootNode
      }
    
      @Override
      protected void cleanup(Application app) {
          //TODO: очистка того, что вы инициализировали в методе initialize ,
          //например удалить все spatial-ы из rootNode
      }
    
    //onEnable()/onDisable() могут использоваться для управления вещами, которые должны 
    //существовать только при включенном состоянии(state). Основными примерами были бы привязки
    //графа сцены или привязки слушателя ввода.
      @Override
      protected void onEnable() {
          //Вызывается, когда состояние(state) полностью включено, то есть: присоединено и 
          //isEnabled() в true , или когда статус setEnabled() изменяется после 
          //присоединения состояния.
      }
    
      @Override
      protected void onDisable() {
          //Вызывается, когда состояние(state) было ранее включено, но теперь отключено
          //либо потому, что вызвано setEnabled(false) либо состояние
          //очищается(cleaned up).
      }
    
      @Override
      public void update(float tpf) {
          //TODO: реализовать поведение для времени выполнения
      }
    
      /**
       * Привяжите ScreenController к экрану(screen). Это происходит прямо перед
       * ЗАПУСКОМ onStartScreen и только ровно один раз для экрана!
       * @param nifty nifty
       * @param screen экран
       */
      @Override
      public void bind(Nifty nifty, Screen screen) {
          throw new UnsupportedOperationException("Not supported yet.");
      }
    
      /**
       * вызывается сразу после события onStartScreen ENDED.
       */
      @Override
      public void onStartScreen() {
          throw new UnsupportedOperationException("Not supported yet.");
      }
    
      /**
       * вызывается сразу после события onEndScreen ENDED.
       */
      @Override
      public void onEndScreen() {
          throw new UnsupportedOperationException("Not supported yet.");
      }
    }

    Название и пакет вашего пользовательского класса ScreenController (здесь mygame.MyStartScreen) входят в параметр контроллера соответствующего XML-экрана, к которому они принадлежат. Например:

    <nifty>
      <screen id="start" controller="mygame.MyStartScreen">
          <!-- код панелей и слоёв ... -->
      </screen>
    </nifty>

    И то же самое в синтаксисе Java:

    nifty.addScreen("start", new ScreenBuilder("start") {{
      controller(new mygame.MyStartScreen());
    }}.build(nifty));

    Теперь подключены Java-класс MyStartScreen и этот GUI экран (start). В этом примере вы также можете подключить hud экран к MyStartScreen.

    Смотрите так же: Nifty GUI — Руководство: Elements (Screen Controller)

    Сделаем взаимодействие между GUI и Java

    В большинстве случаев вам нужно будет передавать игровые данные в ScreenController и из него. Обратите внимание, что вы можете передать любые пользовательские аргументы из вашего Java-класса в конструктор своего ScreenController (public MyStartScreen(GameData data) {}).

    Используйте любую комбинацию из трех следующих способов, чтобы заставить Java-классы взаимодействовать с GUI.

    GUI вызывает метод Void Java

    Это то, как вы реагируете на взаимодействие с GUI, например, клики в XML GUI:

    1. Добавите visibleToMouse=“true для родительского элемента!
    2. Встроите элемент <interact /> в родительский элемент.
    3. Укажите Java методы которые вы хотите вызвать когда выполняете некоторые действия, такие как клик мыши.
      Пример: <interact onClick=“startGame(hud) />

    Или это то, как вы реагируете на взаимодействие с GUI, такое как клики в Java GUI:

    1. Добавите visibleToMouse(true); для родительского элемента!
    2. Встроите элемент interact…() в родительский элемент
    3. Укажите Java методы которые вы хотите вызвать когда выполняете некоторые действия.
      Пример: interactOnClick(«startGame(hud)»);

    В следующем примере мы вызываем метод startGame(), когда игрок нажимает кнопку [Start] и quitGame(), когда игрок нажимает кнопку [Quit].

            <panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center">
              <control name="button" label="Start" id="StartButton" align="center" valign="center"
              visibleToMouse="true" >
                <interact onClick="startGame(hud)"/>
              </control>
            </panel>
    
            <panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center">
              <control name="button" label="Quit" id="QuitButton" align="center" valign="center"
              visibleToMouse="true" >
                <interact onClick="quitGame()"/>
              </control>
            </panel>

    И то же самое в синтаксисе Java:

    control(new ButtonBuilder("StartButton", "Start") {{
      alignCenter();
      valignCenter();
      height("50%");
      width("50%");
      visibleToMouse(true);
      interactOnClick("startGame(hud)");
    }});
    ...
    
    control(new ButtonBuilder("QuitButton", "Quit") {{
      alignCenter();
      valignCenter();
      height("50%");
      width("50%");
      visibleToMouse(true);
      interactOnClick("quitGame()");
    }});

    Вернемся в класс MyStartScreen, вы указываете, что делают методы startGame() и quitGame(). Как вы видите, вы можете передать String аргументы (здесь в hud) в вызове метода. Вы также видите, что у вас есть доступ к объекту app.

    public class MyStartScreen extends BaseAppState implements ScreenController {
      ...
    
      /** пользовательские методы */
      public void startGame(String nextScreen) {
        nifty.gotoScreen(nextScreen);  // переключиться на другой экран
        // запустите игру и сделайте еще что-нибудь...
      }
    
      public void quitGame() {
        getApplication().stop();
      }
    
      ...
    }

    Пример startGame() просто переключает GUI на экран hud, когда пользователь нажимает кнопку [Start]. Конечно, в реальной игре вы бы выполнили больше шагов: Загрузка игрового уровня, переключение на игровой ввод и обработку управления, задание boolean значения пользовательского running в true, добавление пользовательских внутриигровых AppStates и многое другое.

    Пример quitGame() показывает, что у вас есть доступ к объекту Приложения, потому что вы сделали ScreenController расширением BaseAppState.

    GUI получает значение возвращаемое из Java-метода

    Когда Nifty GUI инициализирован, вы можете получить данные из Java. В этом примере Java класс getPlayerName() в MyStartScreen определяет Текст, который отображается в текстовом поле перед словами ‘s Cool Game.

    Сначала определите Java метод в экранном контроллере, в этом примере getPlayerNam().

    public class MySettingsScreen implements ScreenController {
      ...
      public String getPlayerName(){
        return System.getProperty("user.name");
      }
    }

    Nifty использует ${CALL.getPlayerName()}, чтобы получить значение возвращаемое методом getPlayerName() из вашего Java класса ScreenController.

    <text text="${CALL.getPlayerName()}'s Cool Game" font="Interface/Fonts/Default.fnt" width="100%" height="100%" />

    И то же самое в синтаксисе Java:

    text(new TextBuilder() {{
      text("${CALL.getPlayerName()}'s Cool Game");
      font("Interface/Fonts/Default.fnt");
      height("100%");
      width("100%");
    }});

    Вы можете использовать это для строковых и числовых значений (например, когда вы считываете настройки из файла, вы показываете результаты в GUI), а также для методов с побочными эффектами.

    Java изменяет элементы и события

    Вы также можете изменять внешний вид и функции ваших nifty элементов в Java. Убедитесь, что элемент, который вы хотите изменить, имеет свой идентификатор атрибута id=»name», который поможет вам идентифицировать его и задать его.

    Вот пример того, как изменить изображение под названием playerhealth:

    // загрузка или создание нового изображения
    NiftyImage img = nifty.getRenderEngine().createImage("Interface/Images/face2.png", false);
    // поиск старого
    Element niftyElement = nifty.getCurrentScreen().findElementByName("playerhealth");
    // поменяем старое на новое
    niftyElement.getRenderer(ImageRenderer.class).setImage(img);

    То же самое справедливо и для других элементов, например текстовой метки «score»:

    // найдем старый текст
    Element niftyElement = nifty.getCurrentScreen().findElementByName("score");
    // поменяем старый на новый текст
    niftyElement.getRenderer(TextRenderer.class).setText("124");

    Аналогично, чтобы изменить для элемента событие onClick(), создайте объект ElementInteraction:

    Element niftyElement = nifty.getCurrentScreen().findElementByName("myElement");
    niftyElement.getElementInteraction().getPrimary().setOnMouseOver(new NiftyMethodInvoker(nifty, "myCustomMethod()", this));

    Чтобы это работало, в вашем элементе xml уже должен быть (возможно, неактивный) тег <interact />:

    <interact onClick="doNothing()"/>

    Следующие шаги

    Вы закончили с базовыми уроками по Nifty GUI для jME3. Вы можете перейти к расширенным темам и узнать, как добавлять элементы управления(controls) и эффекты:


    Переведено для jmonkeyengine.ru, оригинал
    Автор перевода: Andry

    Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.