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

Управление физикой транспортного средства

Опубликованно: 15.06.2017, 0:29
Последняя редакция, Andry: 15.06.2017 14:04

Для физики транспортных средств, jME использует jBullet для бросание лучей(ray-cast) транспортным средством. В этой реализации транспортного средства физическое шасси «плавает» вдоль четырех нефизических вертикальных лучей.

Внутренне каждое колесо отбрасывает луч вниз и, используя точку пересечения луча, jBullet вычисляет длину подвески и силу подвески. Сила подвески применяется к шасси, удерживая её от удара о землю. Сила трения вычисляется для каждого колеса, вместе где луч пересекается с землёй. Трение применяется как боковая и передняя сила. [1]

В этой статье показано, как вы используете эту реализацию транспортного средства в приложении jME3.

physics-vehicle

Примеры кода

Примеры полного кода:

Обзор этого приложения с физикой

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

  1. Создайте SimpleApplication с BulletAppState
    • Это дает нам PhysicsSpace для PhysicsNode
  2. Создайте VehicleControl + CompoundCollisionShape для физического поведения транспортного средства
    • Установите физические свойства транспортного средства, такие как подвеска.
  3. Создайте VehicleNode для модели автомобиля
    • Создайте куб плюс 4 цилиндра в виде колес (используя vehicle.addWheel()).
    • Добавьте поведение VehicleControl в Геометрию VehicleNode.
  4. Создайте RigidBodyControl и CollisionShape для пола
  5. Сопоставьте триггеры клавишам и добавьте слушателей ввода
    • Навигационные команды Left, Right, Foward, Brake(Влево, Вправо, Вперед, Тормоз).
  6. Определите действия рулевого управления, которые будут инициироваться событиями нажатия клавиш.
    • vehicle.steer()
    • vehicle.accelerate()
    • vehicle.brake()

Создание шасси транспортного средства

Транспортное средство, которое мы создаем здесь в примере TestPhysicsCar.java, представляет собой всего лишь «коробку на колесах», базовую фигуру автомобиля, которую вы можете заменить модной моделью автомобиля, как показано в TestFancyCar.java.

Каждый физический объект должен иметь фигуру столкновения, которую мы сначала подготовим. Для транспортного средства мы выбираем сложную фигуру столкновения, состоящую из прямоугольного корпуса правильного размера для автомобиля. Мы добавим колеса позже.

CompoundCollisionShape compoundShape = new CompoundCollisionShape();
BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f));

Рекомендации: мы прикрепляем BoxCollisionShape (тело транспортного средства) к CompoundCollisionShape с Vector (0,1,0): это сдвигает эффективный центр массы BoxCollisionShape вниз до 0, -1,0 и делает движущееся транспортное средство более стабильный!

compoundShape.addChildShape(box, new Vector3f(0, 1, 0));

Любая Геометрия может составлять видимую часть транспортного средства, здесь мы используем куб каркас. Мы создаем узел, который мы используем для группировки геометрии.

Node vehicleNode=new Node("vehicleNode");
vehicle = new VehicleControl(compoundShape, 400);
vehicleNode.addControl(vehicle);

Мы инициализируем Vehicle Control с составной фигурой и устанавливаем его массу на большое значение, 400f. Управление транспортным средством представляет собой физическое поведение автомобиля.

vehicle = new VehicleControl(compoundShape, 400);

Наконец, мы добавляем поведение (VehicleControl) к видимой геометрии (узлу).

vehicleNode.addControl(vehicle);

Мы настраиваем физические свойства подвески автомобиля: Compresion, Damping, Stiffness и MaxSuspenionForce. Выбор допустимых значений для подвески колес может быть сложным — для получения дополнительной информации см. Эти советы по настройке подвески. Пока что давайте работать со следующими значениями:

float stiffness = 60.0f;//200=f1 машина
float compValue = .3f; //(должен быть меньше чем damp)
float dampValue = .4f;
vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
vehicle.setSuspensionStiffness(stiffness);
vehicle.setMaxSuspensionForce(10000.0f);

Теперь у нас есть узел vehicleNode с видимой «геометрией автомобиля», который действует как транспортное средство. Одна вещь, которая отсутствует, — это колеса.

Добавление колес

Мы создаем четыре колесные геометрии и добавляем их в автомобиль. Наша геометрия колесо — это простые, нефизические диски (плоские цилиндры), они просто визуальные украшения. Обратите внимание, что поведение физического колеса (объект com.jme3.bullet.objects.VehicleWheel) создается внутри метода vehicle.addWheel().

Метод addWheel() устанавливает следующие свойства:

  • Vector3f connectionPoint — координата, где подвеска подключается к шасси (внутри, где Луч отбрасывается вниз).
  • Vector3f direction — Направление колес, как правило, (0, -1,0).
  • Vector3f axle — направление оси обычно представляет собой (-1,0,0) вектор.
  • float suspensionRestLength — длина подвески в покое в мировых единицах
  • float wheelRadius — радиус колеса в мировых единицах
  • boolean isFrontWheel — Независимо от того, является ли это колесо одним из рулевых колес.
    Передние колеса — это те, которые вращаются достаточно заметно, когда автомобиль поворачивается.

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

Vector3f wheelDirection = new Vector3f(0, -1, 0);
Vector3f wheelAxle = new Vector3f(-1, 0, 0);
float radius = 0.5f;
float restLength = 0.3f;
float yOff = 0.5f;
float xOff = 1f;
float zOff = 2f;

Мы создаем сетку фигуру цилиндра, которую мы используем для создания четырех видимых геометрий колес.

Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true);

Для каждого колеса мы создаем узел и геометрию. Мы привязываем геометрию цилиндра к узлу. Вращаем колесо на 90 ° вокруг оси Y. Мы устанавливаем материал, чтобы сделать его видимым. Наконец, мы добавим колесо (плюс его свойства) к транспортному средству.

Node node1 = new Node("wheel 1 node");
Geometry wheels1 = new Geometry("wheel 1", wheelMesh);
node1.attachChild(wheels1);
wheels1.rotate(0, FastMath.HALF_PI, 0);
wheels1.setMaterial(mat);

vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff),
    wheelDirection, wheelAxle, restLength, radius, true);

Три следующих колеса создаются одинаково, только смещения разные. Не забудьте правильно установить логический параметр, чтобы указать, является ли это передним колесом.

...
vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff),
  wheelDirection, wheelAxle, restLength, radius, true);
...
vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff),
  wheelDirection, wheelAxle, restLength, radius, false);
...
vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff),
  wheelDirection, wheelAxle, restLength, radius, false);

Прикрепите колесные узлы к узлу автомобиля, чтобы сгруппировать их, чтобы они перемещались вместе.

vehicleNode.attachChild(node1);
vehicleNode.attachChild(node2);
vehicleNode.attachChild(node3);
vehicleNode.attachChild(node4);

Как всегда, прикрепите узел транспортного средства к корневому узлу, чтобы сделать его видимым, и добавьте Vehicle Control в PhysicalSpace, чтобы автомобиль стал подвергатмя влиянию физики.

rootNode.attachChild(vehicleNode);
getPhysicsSpace().add(vehicle);

Здесь не показано, то как мы создали Material mat.

Управление автомобилем

Здесь не показан стандартный способ, как мы сопоставляем клавиши ввода с действиями (см. Полный образец кода). Также см. Раздел «Обработка ввода»).

В ActionListener мы реализуем действия, которые контролируют направление и скорость транспортного средства. Для четырех направлений (accelerate=up, brake=down, left, right(ускорение = вверх, торможение = вниз, влево, вправо)) мы указываем, как мы хотим, чтобы транспортное средство двигалось.

  • Торможение довольно просто:
    vehicle.brake(brakeForce)
  • Для левого и правого поворотов мы прибавляем константу к steeringValue при нажатии клавиши и вычитаем ее при отпускании клавиши.
    vehicle.steer(steeringValue);
  • Для ускорения мы прибавляем константу к accelerationValue при нажатии клавиши и вычитаем ее, при отпускании клавиши.
    vehicle.accelerate(accelerationValue);
  • Поскольку мы можем и это весело, мы также добавляем турбоусилитель, который заставляет автомобиль прыгать, когда вы нажимаете назначенную клавишу (пробел).
    vehicle.applyImpulse(jumpForce, Vector3f.ZERO);
public void onAction(String binding, boolean value, float tpf) {
  if (binding.equals("Lefts")) {
      if (value) { steeringValue += .5f; } else { steeringValue += -.5f; }
      vehicle.steer(steeringValue);
  } else if (binding.equals("Rights")) {
      if (value) { steeringValue += -.5f; } else { steeringValue += .5f; }
      vehicle.steer(steeringValue);
  } else if (binding.equals("Ups")) {
      if (value) {
        accelerationValue += accelerationForce;
      } else {
        accelerationValue -= accelerationForce;
      }
      vehicle.accelerate(accelerationValue);
  } else if (binding.equals("Downs")) {
      if (value) { vehicle.brake(brakeForce); } else { vehicle.brake(0f); }
  } else if (binding.equals("Space")) {
      if (value) {
        vehicle.applyImpulse(jumpForce, Vector3f.ZERO);
      }
  } else if (binding.equals("Reset")) {
      if (value) {
        System.out.println("Reset");
        vehicle.setPhysicsLocation(Vector3f.ZERO);
        vehicle.setPhysicsRotation(new Matrix3f());
        vehicle.setLinearVelocity(Vector3f.ZERO);
        vehicle.setAngularVelocity(Vector3f.ZERO);
        vehicle.resetSuspension();
      } else {
    }
  }
}

Вм для справки, так мы инициализировали константы для этого примера:

private final float accelerationForce = 1000.0f;
private final float brakeForce = 100.0f;
private float steeringValue = 0;
private float accelerationValue = 0;
private Vector3f jumpForce = new Vector3f(0, 3000, 0);

Помните, что стандартный слушателя клавиш, который сопоставляет действия с клавишами, можно найти в образцах кода.

Обнаружение столкновений

Ознакомьтесь с разделом PhysicsCollisionEvent в документации по общей физике о том, как обнаруживать столкновения. Это можно сделать, если вы хотите реагировать на столкновения пользовательскими событиями, например, добавлять очки или убавлять здоровье.

Рекомендации

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

Для более продвинутого примера рассмотрите TestFancyCar.java.



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

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

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