Fenyx Engine: создание окна и контекста

от
Java    fenyx, engine, opengl

Всем доброго времени суток! Сегодня я хочу познакомить вас с моим движком, который на данный момент разрабатываю. Я покажу, как быстро и эффективно создать окно и контекст. Приступим.

В первую очередь, вам понадобится сам движок, его текущую версию можно найти на гитхабе: https://github.com/DarkPartizaN/fenyx-engine/tree/Experemental_UI

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

Впрочем, чтобы вам не пришлось мучаться, приложу все необходимые либы, включая движок: https://disk.yandex.ru/d/OXUB3Vb7qO6tcw

Учтите, однако, что гит периодически обновляется. Работать буду в NetBeans.

Создадим новый проект:
1.PNG

Подключим к нему LWJGL и fenyx-engine из моего архива, как библиотеки.
Первоначальная инициализация происходит в методе public static void main(final String[] args), как и в любом ява-приложении. Но к нему мы вернёмся позднее. На данном этапе необходимо создать класс приложения, скажем DemoApp.java

Заполним его следующим образом:
  1. package com.aftergames;
  2.  
  3. import com.fenyx.core.FenyxApp;
  4. import com.fenyx.core.Input;
  5.  
  6. /**
  7.  *
  8.  * @author DarkPartizaN
  9.  */
  10. public class DemoApp extends FenyxApp {
  11.  
  12.     public void startApp() {
  13.         Input.show_system_cursor = true; //Говорим движку рисовать системную мышку
  14.  
  15.         createWindow(); //Создаем окно
  16.  
  17.         //Здесь будет дальнейшая инициализация
  18.  
  19.         displayWindow(); //Выводим окно на экран
  20.     }
  21.  
  22.     public void destroyApp() {
  23.     }
  24. }

Теперь вернёмся в Main.java и добавим туда наше приложение, а так же познакомимся с системой конфигов:
  1. package com.aftergames;
  2.  
  3. import com.fenyx.core.AppParams;
  4.  
  5. /**
  6.  *
  7.  * @author DarkPartizaN
  8.  */
  9. public class Main {
  10.  
  11.     public static DemoApp app;
  12.  
  13.     public static void main(final String[] args) {
  14.         AppParams.setDefaults();
  15.         (Main.app = new DemoApp()).startApp();
  16.     }
  17.  
  18. }

Как мы могли увидеть, мы создаём статический вариант нашего приложения, а затем запускаем его цикл из главного метода. Теперь поговорим о системе конфигов. В данном примере используется статический метод AppParams.setDefaults(). У AppParams все методы статические, а соответственно, параметры, сохраненные в них доступны глобально из любого места движка. Подробнее расскажу в последующих уроках. Сейчас же нас интересуют два метода - setDefaults(), который используется в примере, и AppParams.loadFromFile(String path) - это альтернатива стандартным настройкам, которая грузит текстовый файл с любыми настройками (с условием соблюдения формата). Для наглядности приведу код этих двух методов:
  1. public static void setDefaults() {
  2.         AppParams.addParam("com.fenyx.AppName", "Default Fenyx App");
  3.         AppParams.addParam("com.fenyx.Width", "1024");
  4.         AppParams.addParam("com.fenyx.Height", "600");
  5.         AppParams.addParam("com.fenyx.Fullscreen", "false");
  6. }
  1. public static void loadFromFile(String path) {
  2.     setDefaults();
  3.  
  4.     for (String s : ResourceUtils.loadLinesArray(path)) {
  5.         if (s.isEmpty() || s.startsWith("//")) continue;
  6.  
  7.         String[] tokens = StringUtils.splitString(s, "=");
  8.         tokens[0] = StringUtils.trim(tokens[0]);
  9.         tokens[0] = StringUtils.replace(tokens[0], " ", "");
  10.         tokens[1] = StringUtils.crop(tokens[1], "//");
  11.         tokens[1] = StringUtils.trim(tokens[1]);
  12.  
  13.         AppParams.addParam(tokens[0], tokens[1]);
  14.     }
  15. }
Как мы видим, второй метод загружает текстовый файл с поддержкой комментариев. Приведу пример файла конфига:
  1. com.fenyx.AppName = Fenyx Engine Demo //Будет выводиться в заголовке окна
  2. com.fenyx.Width = 1024 //Ширина окна
  3. com.fenyx.Height = 600 //Высота окна
  4. com.fenyx.Fullscreen = false //На полный ли экран?
Все указанные переменные и значения в конфиге - служебные, они используются движком. Но вы легко можете добавить свои, например
  1. com.mypackage.JustLittleHappyVar = HelloWorld
И затем получить её методом AppParams.getString(String name)
В AppParams предусмотрен широкий спектр для хранения и получения значений. В процессе выполнения программы, вы всегда можете сделать вызов вида:
  1. AppParams.addParam(String name, String value)
Или же, если параметр уже есть, то:
  1. AppParams.editParam(String name, String newValue)
Значение добавится или заменится, и каждое добавленное значение доступно глобально по запросу AppParams.get...(). Однако имейте в виду, вы должны точно указывать тип переменной, которую хотите получить. Все методы для этого есть.

Однако, если мы попытаемся сейчас запустить приложение, то получим или вечный черный экран, или ошибку (исправлю в обновлении на неё):
2.PNG
А всё потому-что у нас не создан ни один State приложения. Впрочем, исправить это несложно. Создадим рядом файл TestState.java и заполним его следующим образом:
  1. package com.aftergames;
  2.  
  3. import com.fenyx.core.AppState;
  4.  
  5. /**
  6.  *
  7.  * @author DarkPartizaN
  8.  */
  9. public class TestState extends AppState {
  10.  
  11.     public void init() {
  12.     }
  13.  
  14.     protected void onActivate() {
  15.     }
  16.  
  17.     public void process() {
  18.     }
  19.  
  20.     protected void onDeactivate() {
  21.     }
  22.  
  23.     public void onStop() {
  24.     }
  25. }
Это класс состояния приложения. Они могут быть абсолютно разными - заставка, меню, загрузка, непосредственно игровой процесс, или различные меню (к UI обращусь чуть позже). Пока что, давайте просто зарегистрируем и запустим наш стейт. Откроем DemoApp.java и добавим статическую переменную private final int STATE_ID_TEST = 1;

Это - ID стейта, по которому он может быть вызван менеджером состояний. Число в целом не важно, просто служит для удобства. Зарегистрируем наш стейт, в том же DemoApp:
  1. public void startApp() {
  2.     Input.show_system_cursor = true;
  3.  
  4.     createWindow();
  5.  
  6.     //Инициализируем стейт
  7.     TestState tasteState = new TestState();
  8.     tasteState.id = STATE_ID_TEST;
  9.  
  10.     //Регистрируем стейт и добавляем его в менеджер состояний
  11.     StateManager.registerState(tasteState);
  12.     StateManager.pushState(STATE_ID_TEST);
  13.  
  14.     displayWindow();
  15. }

Теперь, после запуска мы должны получить вожделенное окно:
3.PNG

В следующем уроке мы добавим в него счётчик FPS! :)
  • +3
  • views 3059