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

Выбор мышью

Опубликованно: 13.05.2017, 12:28
Последняя редакция, Andry: 16.10.2017 18:29

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

mouse-picking

Подробную информацию о том, как задавать необходимые триггеры ввода, сопоставления ввода и слушателей ввода, см. В разделе «Обработка Ввода».

Выберите цель с помощью фиксированных перекрестий

Следующее сопоставление ввода «выбор цели» реализует действие, которое определяет, что пользователь нажал. Предполагается, что указатель мыши невидим, а в центре экрана расположены перекрестия. Предполагает, что пользователь направляет перекрестье на объект в сцене и нажимает. Вы используете Ray Casting для определения геометрии, которая была выбрана пользователем. Используйте этот метод вместе с flyCam от первого лица.

  1. Активируйте камеру от первого лица: flyCam.setEnabled(true);
  2. Держите указатель мыши невидимым с помощью inputManager.setCursorVisible(false).
  3. Сопоставьте действие pick target(выбрать цель) с MouseButtonTrigger.
  4. Реализуйте действие в Listener.

В следующем примере при нажатии вращается Spatial с именем «Red Box» или «Blue Box». Измените этот код, чтобы сделать то, что ваша игра должна сделать с идентифицированной целью (снимать, брать, перемещать и.т.д.).

  private AnalogListener analogListener = new AnalogListener() {
    public void onAnalog(String name, float intensity, float tpf) {
        if (name.equals("pick target")) {
         // Сбросить список результатов.
         CollisionResults results = new CollisionResults();
         // Направьте луч от камеры по направлению камеры
         // (assuming crosshairs in center of screen).
         Ray ray = new Ray(cam.getLocation(), cam.getDirection());
         // Соберите пересечения между лучом и всеми узлами в списке результатов.
         rootNode.collideWith(ray, results);
         // Распечатайте результаты, чтобы мы увидели, что происходит
         for (int i = 0; i < results.size(); i++) {
           // Для каждого «удара» мы знаем расстояние и точку удара по геометрии.
           float dist = results.getCollision(i).getDistance();
           Vector3f pt = results.getCollision(i).getContactPoint();
           String target = results.getCollision(i).getGeometry().getName();
           System.out.println("Selection #" + i + ": " + target + " at " + pt + ", " + dist + " WU away.");
         }
         // 5. Используйте результаты - мы вращаем выбранную геометрию.
         if (results.size() > 0) {
           // Ближайшим результатом является цель, которую выбрал игрок:
           Geometry target = results.getClosestCollision().getGeometry();
           // Здесь происходит действие:
           if(target.getName().equals("Red Box"))
             target.rotate(0, - intensity, 0);
           else if(target.getName().equals("Blue Box"))
             target.rotate(0, intensity, 0);
         }
        } // иначе, если ...
    }
  };


Выберите цель с помощью указателя мыши

Следующее pick target(выбрать цель) сопоставления ввода реализует действие, которое определяет, на что пользователь кликнул. Оно предполагает, что указатель мыши видим, и пользователь направляет курсор на объект в сцене. Вы используете ray casting, чтобы определить геометрию, которую выбрал пользователь.

Выделение с помощью видимого указателя мыши означает, что ваше приложение больше не может использовать flyCam по умолчанию, где MouseAxisTrigger поворачивает камеру. Необходимо деактивировать сопоставления flyCam и предоставить настраиваемые сопоставления. Либо иной ввод для поворота камеры, либо зафиксировать камеру.
  1. Сопоставьте действие pick target(выбрать цель) с MouseButtonTrigger.
  2. Сделайте указатель мыши видимым с помощью inputManager.setCursorVisible(true).
  3. Переназначьте ввод для вращения камеры или отключите вращение камеры.
  4. Реализуйте действие в Listener.

В следующем примере при нажатии вращается Spatial с именем «Red Box» или «Blue Box». Измените этот код, чтобы делать то, что ваша игра должна делать с идентифицированной целью (снимать, брать, перемещать и.т.д.).

private AnalogListener analogListener = new AnalogListener() {
    public void onAnalog(String name, float intensity, float tpf) {
      if (name.equals("pick target")) {
        // Сбросить список результатов.
        CollisionResults results = new CollisionResults();
        // Конвертировать экран по клику в 3D-позицию
        Vector2f click2d = inputManager.getCursorPosition();
        Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
        Vector3f dir = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y),
 1f).subtractLocal(click3d).normalizeLocal();
        // Направьте луч от выбранной точкой вперед.
        Ray ray = new Ray(click3d, dir);
        // Соберите пересечения между лучом и всеми узлами в списке результатов.
        rootNode.collideWith(ray, results);
        // (Распечатайте результаты, чтобы мы увидели, что происходит :)
        for (int i = 0; i < results.size(); i++) {
          // (Для каждого «попадания» мы знаем расстояние и точку попадания, на геометрии).
          float dist = results.getCollision(i).getDistance();
          Vector3f pt = results.getCollision(i).getContactPoint();
          String target = results.getCollision(i).getGeometry().getName();
          System.out.println("Selection #" + i + ": " + target + " at " + pt + "," + dist + " WU away.");
        }
        // Используем результаты - мы вращаем выбранную геометрию.
        if (results.size() > 0) {
          // Ближайшим результатом является цель, которую выбрал игрок:
          Geometry target = results.getClosestCollision().getGeometry();
          // Вот действие:
          if (target.getName().equals("Red Box")) {
            target.rotate(0, -intensity, 0);
          } else if (target.getName().equals("Blue Box")) {
            target.rotate(0, intensity, 0);
          }
        }
      } // иначе, если ...
    }
  };

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

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

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