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

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

Опубликованно: 04.09.2015, 20:14
Последняя редакция, AdiDOS: 07.05.2017 8:51

Для разнообразности решил создать я небольшую 3D игру жанра шутер от первого лица на движке JME3,так как эта тема обширна уроки буду писать поэтапно , в данном уроке мы попробуем привязать оружие и прицел.

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

package weapons;

import com.jme3.asset.AssetLocator;
import com.jme3.asset.AssetManager;
import com.jme3.asset.plugins.FileLocator;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

public abstract class Weapon extends Node{
   protected AssetManager assetManager;
   protected Camera cam;

   protected Spatial weapon;

   protected Vector3f rotate = new Vector3f(0,0,0); //Вращение оружия
   protected Vector3f move = new Vector3f(0, 0, 0);//Перемещение оружия

 /**
 * @param rotate Возвращает угол поворота оружия на камере
 */
 public Vector3f getRotate() {
   return rotate;
 }
 /**
 * @param rotate Установка поворота оружия на камере
 */
 public void setRotate(Vector3f rotate) {
   this.rotate = rotate;
 }
 /**
 * @param move Возвращает позицию оружия на камере
 */
 public Vector3f getMove() {
   return move;
 }
 /**
 * @param move Установка смещения оружия на камере
 */
 public void setMove(Vector3f move) {
   this.move = move;
 }
 /**
 * В этой функции передаем параметры сцены <br>
 * @param assetManager Мэнеджер ресурсов
 * @param cam камера сцены
 */
 public void init(AssetManager assetManager, Camera cam){
   this.assetManager = assetManager;
   this.cam = cam;

 }
 /**
 * Функция загрузки модели <br>
 * @param rootPath Путь к корневому каталогу
 * @param name Имя Файла
 * @param locatorClass Локатор
 */
 public void loadModel(String rootPath, String name, Class<? extends AssetLocator> locatorClass){
   assetManager.registerLocator("E:/Models/Weapons/animAk47", FileLocator.class);
   weapon = assetManager.loadModel(name);
   this.attachChild(weapon);
 }

 /**
 * Функция разчета и маштабирования оружия с камерой
 */
 public void update(){
   //Перемещение оружия по координатам камеры
   Vector3f vectorDifference = new Vector3f(cam.getLocation().subtract(this.getWorldTranslation()));
   this.setLocalTranslation(vectorDifference.addLocal(this.getLocalTranslation()));
   Quaternion worldDiff = new Quaternion(cam.getRotation().mult(this.getWorldRotation().inverse()));
   this.setLocalRotation(worldDiff.multLocal(this.getLocalRotation()));

   //Позиция оружия
   this.move(cam.getDirection().mult(move.x));
   this.move(cam.getUp().mult(move.y));
   this.move(cam.getLeft().mult(move.z));
   this.rotate(rotate.x,rotate.y, rotate.z);
 }

}

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

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

package weapons;

import com.jme3.asset.AssetManager;
import com.jme3.asset.plugins.FileLocator;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import com.jme3.system.AppSettings;

public class AK47 extends Weapon{

 BitmapText ch;
 Node guiNode;
 public AK47(AssetManager assetManager, Camera cam) {
   init(assetManager, cam);
   loadModel("E:/Models/Weapons/animAk47", "ak47.mesh.xml", FileLocator.class);
   setMove(new Vector3f(27.1f, -35.5f, -4.4f));
   setRotate(new Vector3f());
 }
 //Создание прицела
 public void attachBreechSight(AppSettings settings, Node guiNode){
   this.guiNode = guiNode;
   BitmapFont guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
   ch = new BitmapText(guiFont, false);
   ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
   ch.setText("+");
   ch.setLocalTranslation(settings.getWidth() / 2 - ch.getLineWidth() / 2, //Перемещаем в центр
   settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
   guiNode.attachChild(ch);
 }

 public void detachBreechSight(){
   guiNode.detachChild(ch);
 }

}

Класс AK47 унаследован  от класса Weapons в его конструкторе я передаю  параметры которые нужны для работы текущего класса , ну перейдем собственно к описанию этого кода.

Функция инициализации нужна для передачи параметров классу Weapon.

init(assetManager, cam);

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

loadModel("E:/Models/Weapons/animAk47", "ak47.mesh.xml", FileLocator.class);

 

Установка позиции оружия на камере .

setMove(new Vector3f(27.1f, -35.5f, -4.4f));

 

Установка поворота оружия на камере .

setRotate(new Vector3f());

Что по поводу функции attachBreechSight она нужна для привязки прицела , где входящий параметр AppSettings нужен для считывания размеров экрана  , а к guiNode мы привязываем наш псевдо-прицел а псевдо потому что на самом деле если посмотреть внимательно в код то можно понять что это обычный текст который мы устанавливаем с помощью функции setText(«+»); .

Далее немного тестового кода который объединяет все эти функции.

package tests;

import com.jme3.app.SimpleApplication;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.util.SkyFactory;

import weapons.AK47;

public class SceneControl extends SimpleApplication {
 AK47 player;

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

 }

 @Override
 public void simpleInitApp() {
   flyCam.setMoveSpeed(50);
   setDisplayStatView(false);
   createAmbienLight();
   createDirectionLight();
   createSkyBoxDds();
   createTerrain();

   player = new AK47(assetManager, cam);
   player.attachBreechSight(settings, guiNode);
   rootNode.attachChild(player);

 }

 @Override
 public void simpleUpdate(float tpf) {
   player.update();
   super.simpleUpdate(tpf);
 }
 // Рассеянный свет
 private void createAmbienLight() {
   AmbientLight al = new AmbientLight();
   al.setColor(ColorRGBA.White.mult(1.2f));
   rootNode.addLight(al);
 }

 // Направленный свет
 private void createDirectionLight() {
   DirectionalLight sun = new DirectionalLight();
   sun.setColor(ColorRGBA.White);
   sun.setDirection(new Vector3f(-10f, -10f, -10f).normalizeLocal());
   rootNode.addLight(sun);
 }

 // Создание неба с загрузкой dds файла
 private void createSkyBoxDds() {
   Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
   sky.setLocalScale(350);
   rootNode.attachChild(sky);
 }

 // Создаем ландшафт
 private void createTerrain() {
   Material mat = assetManager.loadMaterial("Textures/Terrain/Rocky/Rocky.j3m");
   Spatial terrain = assetManager.loadModel("Models/Terrain/Terrain.mesh.xml");

   terrain.setMaterial(mat);
   terrain.setLocalScale(400);
 // terrain.setLocalTranslation(0, -10, -120);

   rootNode.attachChild(terrain);
 }
}

1

2

Я думаю последний код я комментировать не буду что я могу добавить как видите я создал класс AK47 так как он унаследован от Node мы смело его добавляем на сцену да и в конструкторе я передаю параметры assetManager и cam.

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

5 комментариев на «“Создание 3D шутер ч1”»

  1. AdiDOS AdiDOS:

    Все таки я советую не писать в одном файле эту задумку ) небо например запросто может подключаться и так же оружие и т п.

  2. AdiDOS AdiDOS:

    Но ты уже сказал что разобьешь на пакеты, еще заметил это моделька ак 47 для левой руки.

    • RomaGZ:

      Я сильно много классов создавать не буду просто немного распределю код будет не маленький , а по поводу левой руки какая разница это урок ,да и анимация перезарядки там готовая есть

  3. RomaGZ:

    В данном случае у меня 3 класса может еще 2 и все

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

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