Вторник, 19 сентября 2017, 21:46

Приветствую Вас Гость

Меню сайта
Категории каталога
Создание игр [306]
Статьи об общих понятиях связанных с созданием игр.
Программирование [68]
Гайды по программированию на разных ЯП.
Движки и Гейммейкеры [123]
Статьи о программах для создания игр, уроки и описания.
Софт [27]
Различные программы, в том числе в помощь игроделам.
2D-графика [11]
Уроки по рисованию, растр, пиксель-арт, создание спрайтов и пр.
3D-графика [10]
Уроки по моделированию, ландшафт, модели, текстурирование и пр.
Моддинг игр [4]
Модификация компьютерных игр, создание дополнений, перевод, хакинг.
Игры [69]
Статьи об играх, в том числе и сделанных на гейммейкерах.
Разное [54]
Статьи, которые не вошли в определённые разделы.
Наш опрос
Покупаете ли вы конструкторы игр?
Всего ответов: 10921
Главная » Статьи » Создание игр

Урок по JMonkeyEngine №2 - Input

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

Урок№2.

Ввод.

Сначала, как и в прошлом уроке, создадим новый проект и в создавшемся классе оставим следующее:
Код

package mygame;

import com.jme3.app.SimpleApplication;

public class Main extends SimpleApplication {

  public static void main(String[] args) {
  Main app = new Main();
  app.start();
  }

  @Override
  public void simpleInitApp() {
   
  }

  @Override
  public void simpleUpdate(float tpf) {
   
  }

}


Теперь, чтобы реализовать ввод с клавиатуры/мыши, необходимо к нашему классу добавить интерфейс ActionListener:
Код
public class Main extends SimpleApplication implements ActionListener

Программа сразу же нам указывается на ошибку и предлагает реализовать все абстрактные методы для этого интерфейса. Мы конечно же соглашаемся и видим, что у нас появился такой метод:
Код
public void onAction(String name, boolean isPressed, float tpf) {
  throw new UnsupportedOperationException("Not supported yet.");
  }


Пока оставим его.
Теперь создадим событие для нажатия левой кнопки мыши и слушатель этого события. Для этого в метод simpleInitApp() добавим следующее:
Код
inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "MouseL");


Теперь создадим новый метод, в котором у нас будут создаваться пули. Я назвал его bulletCreate. В итоге у нас получится следующее:
Код
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;

public class Main extends SimpleApplication implements ActionListener {

  public static void main(String[] args) {
  Main app = new Main();
  app.start();
  }

  @Override
  public void simpleInitApp() {
  inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  inputManager.addListener(this, "MouseL");
  }

  @Override
  public void simpleUpdate(float tpf) {
   
  }

  public void onAction(String name, boolean isPressed, float tpf) {
  throw new UnsupportedOperationException("Not supported yet.");
  }
   
  void bulletCreate(){
   
  }

}



Теперь сделаем так, чтобы при нажатии левой кнопки мыши у нас вызывался метод bulletCreate():
Код
public void onAction(String name, boolean isPressed, float tpf) {
  if (name.equals("MouseL") && isPressed){
  bulletCreate();
  }
  }

Дабы проверить работоспособность кода создадим BitmapText, в котором будет отображаться некая целочисленная переменная i, которая будет увеличиваться при нажатии кнопки мыши. Чтобы не мучиться с созданием текста, воспользуемся готовым шаблоном, который нас предлагает движок. Справа, в окошке под название "Палитра компонентов", есть вкладка "Interface", в которой имеется компонент "HUDText". Просто, методом drag'n'drop, перетаскиваем его в метод simpleInitApp(). Так будет выглядеть наш метод:
Код
public void simpleInitApp() {
  inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  inputManager.addListener(this, "MouseL");
  /** Write text on the screen (HUD) */
  guiNode.detachAllChildren();
  guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  BitmapText helloText = new BitmapText(guiFont, false);
  helloText.setSize(guiFont.getCharSet().getRenderedSize());
  helloText.setText("Hello World");
  helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
  guiNode.attachChild(helloText);  
  }

Тут у нас появляется проблема. Мы не сможем взаимодействовать с этим компонентов из другого метода. Нам необходимо, чтобы объект helloText создавался до инициализации методов. Для этого часть BitmapText helloText поставим перед методами, а в методе simpleInitApp() оставим лишь ту часть, где этот компонент инициализируется (как то каряво выразился). После всего этого наш класс будет выглядеть так:
Код
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;

public class Main extends SimpleApplication implements ActionListener {
BitmapText helloText;
  public static void main(String[] args) {
  Main app = new Main();
  app.start();
   
  }

  @Override
  public void simpleInitApp() {
  inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  inputManager.addListener(this, "MouseL");
  /** Write text on the screen (HUD) */
  guiNode.detachAllChildren();
  guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  helloText = new BitmapText(guiFont, false);
  helloText.setSize(guiFont.getCharSet().getRenderedSize());
  helloText.setText("Hello World");
  helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
  guiNode.attachChild(helloText);  
  }

  @Override
  public void simpleUpdate(float tpf) {
   
  }

  public void onAction(String name, boolean isPressed, float tpf) {
  if (name.equals("MouseL") && isPressed){
  bulletCreate();
  }
  }
   
  void bulletCreate(){
   
  }

}



Там же, где создали helloText, создадим целочисленную переменную:
Код
int i = 0;


В методе simpleUpdate(float tpf) будем прибавлять к ней 1 и отображать ее в нашем тексте:
Код
public void simpleUpdate(float tpf) {
  i++;
  helloText.setText("i= "+i);
  }


Запускаем и... Все работает, можно продолжать.
Теперь будем создавать сферу, которая у нас будет пулей. Но есть одна особенность, мы его будем добавлять в некий контейнер. Подробнее про ArrayList'ы вы сможете узнать из документации по библиотеки java.util.
С контейнером поступим также как и текстом, т.е. создадим его вне методов, а инициализируем в методе simpleInitApp().
Код
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.scene.Geometry;
import java.util.ArrayList;

public class Main extends SimpleApplication implements ActionListener {
BitmapText helloText;
int i = 0;
ArrayList<Geometry> ar;
  public static void main(String[] args) {
  Main app = new Main();
  app.start();  
  }

  @Override
  public void simpleInitApp() {
  ar = new ArrayList<Geometry>();
  inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  inputManager.addListener(this, "MouseL");
  /** Write text on the screen (HUD) */
  guiNode.detachAllChildren();
  guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  helloText = new BitmapText(guiFont, false);
  helloText.setSize(guiFont.getCharSet().getRenderedSize());
  helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
  guiNode.attachChild(helloText);  
  }

  @Override
  public void simpleUpdate(float tpf) {
  i++;
  helloText.setText("i= "+i);
  }

  public void onAction(String name, boolean isPressed, float tpf) {
  if (name.equals("MouseL") && isPressed){
  bulletCreate();
  }
  }
   
  void bulletCreate(){
   
  }

}


Мы создали контейнер(лист), в котором будут содержаться объекты типа Geometry. Но нашу геометрию надо на что-то "натягивать", для этого создадим объект типа Sphere. Создавать его будем по той же схеме что и контейнер:
Код
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Sphere;
import java.util.ArrayList;

public class Main extends SimpleApplication implements ActionListener {
BitmapText helloText;
int i = 0;
ArrayList<Geometry> ar;
Sphere s;
  public static void main(String[] args) {
  Main app = new Main();
  app.start();  
  }

  @Override
  public void simpleInitApp() {
  s = new Sphere(14,14,1);
  ar = new ArrayList<Geometry>();
  inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  inputManager.addListener(this, "MouseL");
  /** Write text on the screen (HUD) */
  guiNode.detachAllChildren();
  guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  helloText = new BitmapText(guiFont, false);
  helloText.setSize(guiFont.getCharSet().getRenderedSize());
  helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
  guiNode.attachChild(helloText);  
  }

  @Override
  public void simpleUpdate(float tpf) {
  i++;
  helloText.setText("i= "+i);
  }

  public void onAction(String name, boolean isPressed, float tpf) {
  if (name.equals("MouseL") && isPressed){
  bulletCreate();
  }
  }
   
  void bulletCreate(){
   
  }

}


Теперь будем заполнять наш контейнер сферами, но для начала, так же перед методами, создадим материал строчкой:
Код
Material m;

А в методе bulletCreate() пишем следующее:
Код
m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
ar.add(new Geometry("bullet",s));
for (Geometry g : ar){  
g.setMaterial(m);
rootNode.attachChild(g);
  }

Цикл for нужен для того, чтобы в нем мы могли обращаться непосредственно к объектам из нашего контейнера. Сейчас наш класс выглядит так:
Код
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Sphere;
import java.util.ArrayList;

public class Main extends SimpleApplication implements ActionListener {
BitmapText helloText;
int i = 0;
ArrayList<Geometry> ar;
Sphere s;
Material m;
  public static void main(String[] args) {
  Main app = new Main();
  app.start();  
  }

  @Override
  public void simpleInitApp() {
  s = new Sphere(14,14,1);
  ar = new ArrayList<Geometry>();
  inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  inputManager.addListener(this, "MouseL");
  /** Write text on the screen (HUD) */
  guiNode.detachAllChildren();
  guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  helloText = new BitmapText(guiFont, false);
  helloText.setSize(guiFont.getCharSet().getRenderedSize());
  helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
  guiNode.attachChild(helloText);  
  }

  @Override
  public void simpleUpdate(float tpf) {
  i++;
  helloText.setText("i= "+i);
  }

  public void onAction(String name, boolean isPressed, float tpf) {
  if (name.equals("MouseL") && isPressed){
  bulletCreate();
  }
  }
   
  void bulletCreate(){
  m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  ar.add(new Geometry("bullet",s));
  for (Geometry g : ar){  
  g.setMaterial(m);
  rootNode.attachChild(g);
  }
  }

}


Если его выполнить, то при каждом нажатии левой кнопки мыши у нас каждая новая сфера накладывается на другую. Давайте заставим их двигаться по направлению камеры. Для этого создадим новый вектор:
Код
Vector3f dir = new Vector3f();

А в метод bulletCreate() напишем:
Код
dir = cam.getDirection().normalizeLocal();

Т.е. при каждом нажатии кнопки мыши задаем ему вектор направления камеры.
Вектор есть, теперь давайте сделаем так, чтобы шары двигались по его направлению. В методе simpleUpdate(float tpf) пишем:
Код
for (Geometry g : ar){  
  g.move(dir);  
  }

Теперь запускаем проект и любуемся. Теперь для пущего эффекта давайте сделаем так, чтобы у наших пуль постоянно менялся цвет. В тот же цикле for пишем:
Код
m.setColor("Color", ColorRGBA.randomColor());

Здесь полный текст нашего класса:
Код
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Sphere;
import java.util.ArrayList;

public class Main extends SimpleApplication implements ActionListener {
BitmapText helloText;
ArrayList<Geometry> ar;
Sphere s;
Material m;
Vector3f dir;
  public static void main(String[] args) {
  Main app = new Main();
  app.start();  
  }

  @Override
  public void simpleInitApp() {
  s = new Sphere(14,14,1);
  ar = new ArrayList<Geometry>();
  inputManager.addMapping("MouseL", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  inputManager.addListener(this, "MouseL");
  /** Write text on the screen (HUD) */
  guiNode.detachAllChildren();
  guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  helloText = new BitmapText(guiFont, false);
  helloText.setSize(guiFont.getCharSet().getRenderedSize());
  helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
  guiNode.attachChild(helloText);  
  }

  @Override
  public void simpleUpdate(float tpf) {

  for (Geometry g : ar){  
  g.move(dir);  
  m.setColor("Color", ColorRGBA.randomColor());
   
  }
  }

  public void onAction(String name, boolean isPressed, float tpf) {
  if (name.equals("MouseL") && isPressed){
  bulletCreate();
  }
  }
   
  void bulletCreate(){
  dir = new Vector3f(cam.getDirection().normalizeLocal());
  m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  ar.add(new Geometry("bullet",s));
  for (Geometry g : ar){  
  g.setMaterial(m);
  rootNode.attachChild(g);
  }
  }

}

На этом сегодняшний урок закончен. Жду ваших замечаний, пожеланий и предложений. Спасибо за внимание smile
Категория: Создание игр | Добавил: matthew01 (17 мая 2013) | Автор: Дмитрий
Просмотров: 3821 | Комментарии: 6 | Рейтинг: 3.8/11 |
Теги: урок, JME, уроки по jMonkeyEngine, java, JMonkeyEngine, уроки, Разработка игр, начинающим, Курс, jME3
Дополнительные опции:
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:

Игровые объявления и предложения:
Если вас заинтересовал материал «Урок по JMonkeyEngine №2 - Input», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела. Предлагаются такие схожие материалы: Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.

Всего комментариев: 6
+0-
6 GlumSpirit   (10 мая 2017 15:44)
GlumSpiritУроки по движку вы можете найти вот здесь http://jmonkeyengine.ru

+0-
5 GlumSpirit   (25 января 2015 17:29)
GlumSpiritВ официальной Вики не стоит переводить. они поддерживают только английский язык

+0-
4 GlumSpirit   (19 декабря 2014 00:19)
GlumSpiritУроки на Русском переведенные в официальной Вики: http://hub.jmonkeyengine.org/wiki/doku.php/документация:jme3_ru
Если есть желающие можете перевести то что еще не успели перевести.

+2-
3 _pDirectDevice   (21 мая 2013 07:00)
Это конечно все интересно, но не очень познавательно, все это есть в справке, было бы очень круто если бы уроки по jmonkeyengine ,были посвящены 2d на android, думаю со мной согласятся многие

+2-
1 goldsphere   (19 мая 2013 06:58)
goldsphereНеплохо было бы вставлять картинки с результатами

+0-
2 matthew01   (19 мая 2013 17:24)
matthew01Спасибо за совет smile В следующем уроке обязательно сделаю картинки

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск по сайту
10 случ. движков
  • LKI-Creator
  • EDGE
  • Genesis3D
  • J.U.R.P.E.
  • TyranoBuilder
  • PointJS
  • Novelty
  • Eclipse Wold
  • Corona
  • BasiEgaXorz
  • Друзья сайта
    Игровой форум GFAQ.ru Перевод консольных игр
    GameDev, Уроки OpenGL, Программирование, Создать Minecraft
    Все права сохранены. GcUp.ru © 2008-2017 Рейтинг