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

Создание 3D шутер ч4

Опубликованно: 16.09.2015, 7:46
Последняя редакция, AdiDOS: 07.05.2017 9:01

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

Что касается физики движения игрока на сцене я использовал стандартную физику JME а точнее JBullet , весь код я поместил в отдельный класс PlaerCollisionControl  , а также анимация взрыва в классе ExplosionGeometry , код этих двух классов  размещать здесь я не буду , первая причина размер а вторая для этого созданы отдельные темы физика и эффекты , ну в общем мы рассмотрим их функции а также функции касающиеся выстрелов и уничтожения объектов.

Начнем наверно с физики а точнее класса PlaerCollisionControl   у него всего 2 функции.

Первый параметр это stateManager он нужен для привязки физики к сцене , inputManager естественно для назначение событий мыши и клавиатуры для управления игроком, камера (cam) привязывается к физическому объекту для передвижения по сцене, ну и последний параметр это сцена на которой физика будет производить вычисления столкновений а простыми слова по которой мы будем двигаться.

 init(stateManager, inputManager, cam, (Node) scene.scene);

Этот метод физика производит расчеты позиции где мы находимся и мы  перемещаем камеру.

update();

Теперь опишу класс эффектов.

Тоже инициализация как и с физикой но с другими параметрами первый нужен для загрузки текстур анимации которые входят в стандартный пакет JME , ну а остальные нужны для привязки эффекта к сцене.

init(assetManager, rootNode, renderManager);

Этот метод нужен для вызова прорисовки эффекта.

draw();

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

Принцип такой передаем параметры камеры лучу и проверяем если наш результат больше 0  а точнее он есть , и если наш объект под именем «Box»  то с помощью функции detachChild убираем коробку из сцену таким образом мы имитируем что то подобное убийства коробки  , ну а далее с помощью функции setLocalTranslation мы перемещаем наш эффект на позицию убитой коробки и с помощью функции draw рисуем .

private void parseRay(){
  CollisionResults results = new CollisionResults();
  Ray ray = new Ray(cam.getLocation(), cam.getDirection());
  rootNode.collideWith(ray, results);

  if (results.size() > 0 && results.getCollision(0).getGeometry().getName().equals("Box")) {
    rootNode.detachChild(results.getCollision(0).getGeometry());
    ExplosionGeometry.explosionEffect.setLocalTranslation(
                      results.getCollision(0).getGeometry().getLocalTranslation());
    ExplosionGeometry.draw();

  }
} 

Ну по сути все просто при выстреле вызываем метод parseRay и он делает свое дело , ну далее перейдем к главному классу.


package test;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;

import weapons.AK47;

public class SceneControl extends SimpleApplication {
  AK47 player;
  Scene scene;
  PlaerCollisionControl pcc = new PlaerCollisionControl();
  ExplosionGeometry eg = new ExplosionGeometry();

public static void main(String[] args) {
  new SceneControl().start();

}
//Инициализация
@Override
public void simpleInitApp() {

  flyCam.setMoveSpeed(30);
  //flyCam.setDragToRotate(true);
  setDisplayStatView(false);
  scene = new Scene(assetManager, rootNode, viewPort); //Создание сцены неба ландшафта и прочее
  scene.createScene();

  createCube(1000);

  player = new AK47(assetManager, cam, inputManager, settings, guiNode, rootNode);//Создание оружия
  rootNode.attachChild(player);

  pcc.init(stateManager, inputManager, cam, (Node) scene.scene);
  eg.init(assetManager, rootNode, renderManager);

}

@Override
public void simpleUpdate(float tpf) {
  pcc.update();
  player.update();
  super.simpleUpdate(tpf);

}
//Хаотичное добавление моделей на сцену
public void createCube(int count){
  for (int i = 0; i < count; i++) {
    Box cube1Mesh = new Box(FastMath.rand.nextFloat()*10,FastMath.rand.nextFloat()*10,
    FastMath.rand.nextFloat()*10);
    Geometry cube1Geo = new Geometry("Box", cube1Mesh);
    //cube1Geo.getMesh().setMode(Mode.LineStrip);
    cube1Geo.setLocalTranslation(new Vector3f(-3f,1.1f,0f));
    Material cube1Mat = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
    Texture cube1Tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
    cube1Mat.setTexture("ColorMap", cube1Tex);
    cube1Geo.setMaterial(cube1Mat);

    cube1Geo.setLocalTranslation(FastMath.rand.nextFloat()*300, FastMath.rand.nextFloat()*300,
    FastMath.rand.nextFloat()*300);
    rootNode.attachChild(cube1Geo);

    }
  }

}

Единственное что я могу дополнить это класс он хаотично создает кубики на сцене где его входящий параметр count определяет количество кубиков.

createCube(int count)

1

Исходники тут.

Спасибо за внимание!!

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

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