Суббота, 14.12.2024, 12:46
Приветствую Вас Гость

Разработка игр c использованием JPCT

Каталог статей

Главная » Статьи » Разработка игр » JPCT

4. Анимация и устройства ввода в JPCT
Начнем с обработки ввода
Для обработки ввода в JPCT есть два класса KeyMapper и Mouse для удобства я создал класс отражающий состояние клавиш и собирающий информацию из этих двух классов.
Код

package gram.engine.input;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.util.KeyMapper;
import com.threed.jpct.util.KeyState;
import java.awt.event.KeyEvent;
import org.lwjgl.input.Mouse;

/**
  *
  * @author Ruslan Nevedomy
  * @site jpct.ucoz.ru
  */
public class InputMap {
   
  public int mouse_x;
  public int mouse_y;
   
  public boolean mouse_leftbutton_down = false;
  public boolean mouse_rigthbutton_down = false;
   
  public int numeric_key=-1;
  public boolean space_key = false;
   
  private KeyMapper keyMapper;
  private FrameBuffer buffer;
   
  public InputMap(FrameBuffer buffer)
  {
  keyMapper = new KeyMapper();
  this.buffer = buffer;  
  }
   
  public void evaluteInput()
  {
  KeyState ks;
  //Обработка клавиатуры
  while( ( ks = keyMapper.poll() ) != KeyState.NONE )  
  {  
  switch (ks.getKeyCode())
  {  
  //пример Обработки ввода цифр на основной клавиатуре
  case KeyEvent.VK_0: {numeric_key = 0;continue;}
   
  //обработка пробела
  case KeyEvent.VK_SPACE: {space_key = ks.getState(); continue;}  
  }  
  }
  //Обработка мыши  
  //получение координат мыши
  mouse_x = Mouse.getX();
  //не забываем про инверсию по Y
  mouse_y = buffer.getOutputHeight()-Mouse.getY();
  //чтение состояния кнопок мыши
  if (Mouse.isButtonDown(0))
  {
  mouse_leftbutton_down = true;
  }
  else
  {
  mouse_leftbutton_down = false;
  }
  if (Mouse.isButtonDown(1))
  {
  mouse_rigthbutton_down = true;
  }
  else
  {
  mouse_rigthbutton_down = false;
  }
  }
}


Как видно из кода в нем нет ничего сложного. Функция evaluteInput() получает и последовательно обрабатывает состояние устройств ввода сначала клавиатуры затем мыши.
Обработка ввода с клавиатуры происходит в цикле. Сначала мы проверяем есть ли что обрабатывает. Если в пуле есть события то программа последовательно извлекает их из него и в соответствии с условиями case устанавливает состояние клавиш. В данном случае нас интересует исключительно нажата ли клавиша "Пробел", т.к. именно она переключает анимацию.
Код

KeyState ks;
  //Обработка клавиатуры
  while( ( ks = keyMapper.poll() ) != KeyState.NONE )  
  {  
  switch (ks.getKeyCode())
  {  
  //пример Обработки ввода цифр на основной клавиатуре
  case KeyEvent.VK_0: {numeric_key = 0;continue;}
   
  //обработка пробела
  case KeyEvent.VK_SPACE: {space_key = ks.getState(); continue;}  
  }  
  }
[code]
Далее мы читаем и обрабатываем события с мышки не забывая про то, что координаты по Y необходимо инвертировать
[code]
//Обработка мыши  
  //получение координат мыши
  mouse_x = Mouse.getX();
  //не забываем про инверсию по Y
  mouse_y = buffer.getOutputHeight()-Mouse.getY();
  //чтение состояния кнопок мыши
  if (Mouse.isButtonDown(0))
  {
  mouse_leftbutton_down = true;
  }
  else
  {
  mouse_leftbutton_down = false;
  }
  if (Mouse.isButtonDown(1))
  {
  mouse_rigthbutton_down = true;
  }
  else
  {
  mouse_rigthbutton_down = false;
  }

С обработкой ввода закончили теперь перейдем к анимации.
Анимация в JPCT реализована в классе Animation . Данный класс позволяет загрузить ключевые кадры на основании которых будет выполнена анимация, а также метод по которому будут интерполироваться координаты сетки объекта. Рассмотрим некоторые из доступных методов интерполяции:
1) LINEAR - метод линейной интерполяции между кадрами. Этот вид интерполяции является самым быстрым.
2) COSINE - метод косинус интерполяции между кадрами. Этот метод интерполяции немного медленнее, чем линейная интерполяция, но все еще очень быстр. Косинус интерполяции, как правило, "генерирует" кадры, так что анимация выглядит как будто движение выполняет робот.
3) BICUBIC - метод использующий бикубическую интерполяцию между кадрами. Это обеспечивает "сглаживаемую" интерполяция, но она медленнее, чем линейная или косинус интерполяции.
4) KEYFRAMESONLY - метод без интерполяции между кадрами. Это самый быстрый метод отображения Анимации, но при этом анимация выглядит очень некрасиво. Данный метод должен быть использован только для создания специальных эффектов или отладки анимации.
А также режимы выполнения интерполяции:
1) USE_WRAPPING - В этом режиме, интерполяция переходит из позиции 1 (последний кадр) в положение 0 (первый кадр) т.е. ходит по кругу. Это значение установлено по умолчанию.
2) USE_CLAMPING - В этом режиме интерполяции не начинается с начала суб-последовательность, если закончится (и наоборот) т.е. не ходит по кругу.
Они устанавливаются методом setInterpolationMethod.

Заканчиваем с теорией и переходим к практике.
Загрузка кадров анимации выглядит следующим образом:
Код

//Загрузка анимации  
  Animation animation = new Animation(3);
  //Меняем метод расчета интерполяции вершин
  // animation.setInterpolationMethod(Animation.BICUBIC);
  //анимация стояния
  animation.createSubSequence("стояние");
  animation.addKeyFrame(model.getMesh());
  //анимация движения
  animation.createSubSequence("движение");
  animation.addKeyFrame(loadModelfrom3DS(".\\res\\testanim2_1.3ds", 1.0f).getMesh());  
  animation.addKeyFrame(loadModelfrom3DS(".\\res\\testanim2_2.3ds", 1.0f).getMesh());  
  //добавлении анимации к объекту
  model.setAnimationSequence(animation);

Как видно из кода с начала мы инициализируем экземпляр класса Animation числом 3 это общее количество кадров анимации затем мы создаем 2 анимационные последовательности. В первой из них только 1 сетка отражающая стоящий объект. Вторая анимационная последовательность состоит из 2-х кадров отражающих крайние точки анимации при движении объекта. Очень важно чтобы количество полигонов в данных ключевых кадрах совпадало иначе вы увидите при анимации артефакты, следите за этим т.к. при создании и выгрузке анимации вы можете случайно удалить один полигон в результате чего вся работа будет испорчена.  
Для расчета анимации в данном примере мною была создана специальная функция doAnimation(), вот ее код:
Код

  private void doAnimation() {  
  AFrame+=0.001f;
  if (AFrame>1) {AFrame=0;}
  model.animate(AFrame, ASequence);  
  }

Данная функция очень проста, мы за каждый вызов функции увеличиваем счетчик анимации пока он не станет равным единицы и затем его обнуляем. Расчет вершин проходит при вызове функции animate, принимающей 2 параметра счетчик кадров анимации согласно документации он должен быть равен от 0 до 1 при этом  0 это первый кадр анимации а 1 последний (направление счетчика можно управлять установкой флагов изменения режимов интерполяции) и номер последовательности кадров к которой он должен применяться.

Собственно все, код данного урока находится тут.
Категория: JPCT | Добавил: Gram01 (02.08.2013)
Просмотров: 1806 | Комментарии: 1 | Рейтинг: 2.3/3
Всего комментариев: 1
1 grebionkinmaxim  
0
Откуда взялся метод "loadModelfrom3DS()"?

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа
Категории раздела
JPCT [11]
Раздел о разработке игр на устройства работающие не под управлением Android'а
Сеть [2]
Раздел по вопросам касающимся сетевого взаимодействия приложений на java в контексте разработки игр
Контент [0]
Статьи о работе к контентом при разработки игр
Скрипты [2]
использование скриптов в игровом движке
Разное [1]
различные материалы о разработке игрового движка
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Copyright Неведомый Р.А. © 2024 | Рейтинг@Mail.ru