Статья, по сути, являтся переводом официальной документации. Может что-то будет отличаться. libGDX включает в себя несколько модулей, предоставляющих определённые возможности при разработке. Думаю, очевидно, какие модули должны присутствовать в такого рода библиотеке.
Введение
libGDX включает несколько модулей:
- Input – предоставляет унифицированную модель ввода для всех платформ. Поддерживает клавиатуру, сенсорный экран, акселерометр и мышь, где это возможно.
- Graphics – позволяет выводить изображение на экран, использую OpenGL ES, реализованный на аппаратном уровне.
- Files – предоставляет абстрагированный доступ к файлам на различных платформах, реализуя типичные для работы с файлами функции ввода/вывода информации.
- Audio – упрощают работу со звуком (запись/во произведение для различных платформ).
- Math — предоставляет шустрые математический функции, которые могут понадобиться в игре.
- Physics — полноценная обёртка Box2D.
Модули
Ввод (Input)
Модель позволяет работать с устройствами ввода на любой платформе. Это могут быть клавиши клавиатуры или мобильного устройства, сенсорный экран, акселерометр или мышь. В desctop-приложениях сенсорный экран заменяет мышь, в то время, когда акселерометр отсутствует.
Модуль также предлагает средства для регистрации процессоров входных потоков для использования событий на основе модели входных данных.
В следующем примере показано как вывести координаты точки нажатия на тачскрине(или с помощью мыши на десктопе):
if (Gdx.input.isTouched()) { System.out.println("Input occurred at x=" + x + ", y=" + y); }
Если вы читали мою статью об архитектуре игр, то можете припомнить класс, который мы там создавали, а именно GameScreen
. Он реализовывает интерфейсы InputProcessor
. Так что нам всего лишь надо было переопределить кое-какие методы: mouseMoved(int x, int y)
, keyDown(int keycode)
и другие. Соль в том, что можно было всё реализовать для различных платформ за счёт нашей архитектуры. В InputProcessor
просто происходит обработка входного потока, а уже действия какие-то производятся в контроллере, независимо от типа ввода. В нашем примере реализована лишь обработка нажатий на сенсорном экране:
@Override public boolean touchDown(int x, int y, int pointer, int button) { if (!Gdx.app.getType().equals(ApplicationType.Android)) return false; ChangeNavigation(x,y); return true; } @Override public boolean touchUp(int x, int y, int pointer, int button) { if (!Gdx.app.getType().equals(ApplicationType.Android)) return false; controller.resetWay(); return true; } private void ChangeNavigation(int x, int y){ controller.resetWay(); if(height-y > controller.player.getPosition().y * renderer.ppuY) controller.upPressed(); if(height-y < controller.player.getPosition().y * renderer.ppuY) controller.downPressed(); if ( x< controller.player.getPosition().x * renderer.ppuX) controller.leftPressed(); if (x> (controller.player.getPosition().x +Player.SIZE)* renderer.ppuX) controller.rightPressed(); }
Как видите, в соответствии с нажатием, оповещаем об этом контроллер, вроде controller.leftPressed()
. Чтобы добавить возможность движения для нашего примера и с использованием клавиатуры, нам необходимо лишь переопределить метод keyDown(int keycode)
:
@Override public boolean keyDown(int keycode) { if (keycode == Keys.LEFT) controller.leftPressed(); if (keycode == Keys.RIGHT) controller.rightPressed(); if (keycode == Keys.UP) controller.upPressed(); if (keycode == Keys.DOWN) controller.downPressed(); return true; }
В соответствии с нажатой клавишей, мы опять же сигнализируем контроллер. Ну и, чтобы наш класс GameScreen
мог перехватывать эти события, необходимо класс зарегистрировать как обработчик входного потока:
Gdx.input.setInputProcessor(this);
Графика (Graphics)
Модуль абстрагируется от работы с графическим процессором и предоставляет доступ к методам обертки OpenGL ES. Так же данный модуль заботится обо всём необходимом для реализации возможностей, предоставляемых производителями.
Главная особенность модуля — обеспечение возможности работы с текстурами и растровыми изображениями (ну, это очевидно из специфики модуля).
Как пример, для получения доступа к OpenGL API 1.0, необходимо выполнить следующий код:
GL10 gl = Gdx.graphics.getGL10 ();
Метод возвратит экземпляр, который можно использовать для вывода изображения. Если аппаратная конфигурация не поддерживает OpenGL ES 1.0, возвращается null.
В следующем фрагменте происходит очистка экрана и заливка красным цветом:
gl.glClearColor(0.1f, 0.0f, 0.0f, 1); gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Возвращается всегда конкретная реализация API (LWJGL, JOGL или Android), поэтому не нужно знать специфику; приложение будет работать на всех платформах.
Поддерживаемые версии API:
1.0 | Gdx.graphics.getGL10(); |
1.1 | Gdx.graphics.getGL11(); |
2.0 | Gdx.graphics.getGL20(); |
Для подробностей можете глянуть официальную документацию.
Понятно, что при разработке игры это модуль будет задействован чаще всего. Но в данной статье просто обзор модулей, конкретно по каждому модулю будет отдельная статья.
Файлы (Files)
Файловый модуль обеспечивает универсальный способ доступа к файлам независимо от платформы. Это упрощает работу по чтению/записи файлов. Очевидно, запись в файл имеет свои ограничения, связанным с безопасностью платформы.
Наиболее распространенные случаи использования модуля Files — загрузка ресурсов (текстур, звуковых файлов) из одного подкаталога приложения для всех платформ. Это также очень удобно для сохранения состояния игры, результатов, достижений.
Если вы ресурсы храните в assets директории и включили её в итоговую сборку, то примерно так будет выглядеть создание текустуры на основе изображения:
Texture myTexture = new Texture(Gdx.files.internal("texture/brick.png"));
За счёт высокого уровня абстракции, работает что на андройде, что на десктопе.
К слову о сохранении состояния. В Android есть очень удобный механизм, названный SharedPreferences. В LibGDX для этого есть класс com.badlogic.gdx.Preferences
. Так что, лично я файлы юзаю только для загрузки изображений/музыки. А состояние и результаты сохраняю используя Preferences
.
Аудио (Audio)
Аудио-модуль упрощает создание и использование аудио файлов. Он так же предоставляет прямой доступ к устройству аудио-вывода.
Он позволяет работать со звуковыми файлами двух типов: музыка и звук. Оба типа поддерживает форматы WAV, MP3, OGG, mid. Возможно и другие, но вам и этих должно хватить (:
Экземпляры sound
загружается в память и могут быть воспроизведены в любое время. Идеально подходит для звуковых эффектов, которые используются по несколько раз, таких как взрывы или выстрелы.
Экземпляр music
, с другой стороны, являют собой поток из файлов на диске (или SD карты). При каждом воспроизведении он считывается из источника.
Следующий фрагмент кода воспроизводит повторно файл myMusicFile.mp3 с диска и устанавливает громкость 50%:
Music music = Gdx.audio.newMusic( Gdx.files.getFileHandle("music/myMusicFile.mp3", FileType.Internal)); //или так music = Gdx.audio.newMusic( Gdx.files.internal("music/myMusicFile.mp3")); //установка громкости в промежутке [0;1F] music.setVolume(0.5f); //начать воспроизведение music.play(); //указываем, что воспроизведение файла надо повторять music.setLooping(true);
Математика (Math)
Ну, про этот модуль особо и не надо говорить. Он предоставляет шустрые математический функции, которые могут понадобиться в игре. В общем-то, мне пока этих методов хватало при разработке. Там есть и тригонометрические функции (синусы, косинусы, арктангенсы и прочие), методы по нахождению максимумы и минимума, логарифмы, методы по округлению. В общем, достаточно. А если чего-то и нет, то всегда можно самому написать (;