- PVSM.RU - https://www.pvsm.ru -
jMonkeyEngine (jME) [1] — трёхмерный игровой движок с открытым исходным кодом [2]. Написан на Java и использует по умолчанию LWJGL для рендеринга. Полностью поддерживаются версии OpenGL со второй по четвёртую.
Как-то раз упоминался [3] на Хабре в далёком 2010-м году.
Помимо характеристик [4] примечателен джавой и не очень примечателен средой разработки NetBeans, которая идёт в комплекте с SDK.
В данной статье хочу рассказать о том, как прикрутить обезьянку к привычной Android Studio.
Создаём новый проект для API не ниже 8 с Blank Activity и в корневой директории проекта создаём папки core и desktop. На языке скриншотов это выглядит как:
Подразумеваем, что core — основной код приложения, а desktop и app — запускатели для десктопа и Андроида соответственно.
В корневом settings.gradle указываем эти директории:
include ':app', ':core', ':desktop'
Жмём Sync Now в правом верхнем углу окна. Это нужно будет делать при любой модификации gradle-файлов.
В директориях core и desktop создаём файл build.gradle:
apply plugin: "java"
sourceSets.main.java.srcDirs = ["src/"]
В корневой build.gradle добавляем репозиторий jmonkeyengine и минимальный набор библиотек для наших подпроектов:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
}
}
allprojects {
repositories {
jcenter()
maven {
url 'http://updates.jmonkeyengine.org/maven'
}
}
}
project(":core") {
apply plugin: "java"
dependencies {
compile 'com.jme3:jme3-core:3.0.+'
}
}
project(":desktop") {
apply plugin: "java"
dependencies {
compile project(":core")
compile 'com.jme3:jme3-desktop:3.0.+'
compile 'com.jme3:jme3-lwjgl:3.0.+'
}
}
project(":app") {
apply plugin: "android"
dependencies {
compile project(":core")
compile 'com.jme3:jme3-android:3.0.+'
}
}
После синхронизации в External Libraries должны появится указанные библиотеки со своими соратниками:
В директориях core и desktop создаём директории src, добавляем в core/src файл Game.java с содержимым из базового примера:
package org.lunapark.dev.jme3example;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
public class Game extends SimpleApplication {
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
rootNode.attachChild(geom);
}
}
Package укажите тот же, что и при создании проекта и вылечите недуги при помощи Alt + Enter и Move to package ...:
В desktop/src создаём файл DesktopLauncher.java:
package org.lunapark.dev.jme3example;
public class DesktopLauncher {
public static void main(String[] args) {
Game game = new Game();
game.start();
}
}
Можно запустить DesktopLauncher.java и полюбоваться фантастической трёхмерной моделькой синего кубика.
Для запуска на Android заменим код в MainActivity.java на код из примера (обязательно измените значение переменной appClass):
package org.lunapark.dev.jme3example;
import android.content.pm.ActivityInfo;
import com.jme3.app.AndroidHarness;
import com.jme3.system.android.AndroidConfigChooser;
import java.util.logging.Level;
import java.util.logging.LogManager;
public class MainActivity extends AndroidHarness {
public MainActivity() {
// Set the application class to run
appClass = "org.lunapark.dev.jme3example.Game";
// Try ConfigType.FASTEST; or ConfigType.LEGACY if you have problems
eglConfigType = AndroidConfigChooser.ConfigType.BEST;
// Exit Dialog title & message
exitDialogTitle = "Exit?";
exitDialogMessage = "Are you sure you want to quit?";
// Choose screen orientation
screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
// Enable MouseEvents being generated from TouchEvents (default = true)
mouseEventsEnabled = true;
// Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)
LogManager.getLogManager().getLogger("").setLevel(Level.INFO);
}
}
Дополним AndroidManifest.xml рекомендуемыми параметрами (android:launchMode=«singleTask» и блок «supports-screens»):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lunapark.dev.jme3example">
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" />
</manifest>
Можно запустить app и созерцать кубик уже на телефоне. Если вместо кубика вы созерцаете ClassNotFound Exception и прочее NPE, скорее всего вы забыли поменять переменную appClass в MainActivity.java. Со мной так было.
Можно, конечно, в MainActivity.java заменить переменную appClass на
appClass = Game.class.getCanonicalName();
и избавиться от хардкода в переменных для диалога, но какой вы после этого индус, правда?
Для использования ресурсов создадим в app директорию assets. Добавим
sourceSets { main { assets.srcDirs = ['src/main/assets', 'assets/'] } }
в app/build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "org.lunapark.dev.jme3example"
minSdkVersion 8
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets { main { assets.srcDirs = ['src/main/assets', 'assets/'] } }
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
Создатели движка рекомендуют такую структуру каталогов:
jMonkeyProjects/MyGame/assets/Interface/ # .font, .jpg, .png, .xml
jMonkeyProjects/MyGame/assets/MatDefs/ # .j3md
jMonkeyProjects/MyGame/assets/Materials/ # .j3m
jMonkeyProjects/MyGame/assets/Models/ # .j3o
jMonkeyProjects/MyGame/assets/Scenes/ # .j3o
jMonkeyProjects/MyGame/assets/Shaders/ # .j3f, .vert, .frag
jMonkeyProjects/MyGame/assets/Sounds/ # .ogg, .wav
jMonkeyProjects/MyGame/assets/Textures/ # .jpg, .png; also .mesh.xml+.material, .mtl+.obj, .blend (!)
Поддержим товарищей и запихнём для проверки в assets/Textures какую-нибудь небольшую текстуру:
Заменим код в Game.java:
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Textures/poster.jpg");
Texture tex = assetManager.loadTexture(key);
mat.setTexture("ColorMap", tex);
geom.setMaterial(mat);
rootNode.attachChild(geom);
}
Запуск приложения на андроид-устройстве должен пройти успешно, в то время как при запуске десктоп-версии ЭВМ выругается злым красным AssetNotFoundException.
Отправляемся в desktop/build.gradle и объясняем:
apply plugin: "java"
sourceSets.main.java.srcDirs = ["src/"]
dependencies {
compile files("../app/assets")
}
По обычаю, синхронизируем и, с высокой долей вероятности, наблюдаем положительный результат.
Если вы не очень хорошо знакомы с jME, то неплохо будет отправиться в раздел Tutorials for Beginners [5] на официальном сайте и пройтись по основам. Или даже скачать [6] сам движок в комплекте с IDE на базе NetBeans, JDK, Блендером и всякими другими полезными штуками.
При изучении примеров в корневой build.gradle рекомендую добавить:
project(":core") {
apply plugin: "java"
dependencies {
compile 'com.jme3:jme3-core:3.0.+'
compile 'com.jme3:jme3-effects:3.0.+'
compile 'com.jme3:jme3-networking:3.0.+'
compile 'com.jme3:jme3-plugins:3.0.+'
compile 'com.jme3:jme3-jogg:3.0.+'
compile 'com.jme3:jme3-terrain:3.0.+'
compile 'com.jme3:jme3-blender:3.0.+'
compile 'com.jme3:jme3-jbullet:3.0.+'
compile 'com.jme3:jme3-niftygui:3.0.+'
compile 'net.sf.sociaal:jME3-testdata:3.0.0.20130526'
}
}
Это почти все модули движка плюс ресурсы для примеров (testdata). Полный список модулей на официальном сайте [7].
При разработке под мобильные платформы есть определённые сложности (применение шейдеров, обработка жестов, ...), но что-нибудь вполне играбельное можно смастерить если следовать известному крылатому выражению [8] 1899 года. Хотя, наверное, это относится не только к jMonkeyEngine.
Надеюсь, всё это кому-нибудь поможет и никому не навредит.
Автор: 3h4k
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/81130
Ссылки в тексте:
[1] jMonkeyEngine (jME): http://jmonkeyengine.org/
[2] открытым исходным кодом: http://jmonkeyengine.googlecode.com/svn/trunk/engine/
[3] упоминался: http://habrahabr.ru/post/88254/
[4] характеристик: http://wiki.jmonkeyengine.org/doku.php?id=jme3:features
[5] Tutorials for Beginners: http://wiki.jmonkeyengine.org/doku.php/jme3#tutorials_for_beginners
[6] скачать: http://jmonkeyengine.org/?page_id=301327
[7] Полный список модулей на официальном сайте: http://wiki.jmonkeyengine.org/doku.php/jme3:maven
[8] крылатому выражению: https://ru.wikipedia.org/wiki/%D0%9B%D0%B5%D0%BD%D0%B8%D0%BD%D1%81%D0%BA%D0%B8%D0%B5_%D1%84%D1%80%D0%B0%D0%B7%D1%8B#.C2.AB.D0.A3.D1.87.D0.B8.D1.82.D1.8C.D1.81.D1.8F.2C_.D1.83.D1.87.D0.B8.D1.82.D1.8C.D1.81.D1.8F_.D0.B8_.D1.83.D1.87.D0.B8.D1.82.D1.8C.D1.81.D1.8F.C2.BB
[9] Источник: http://habrahabr.ru/post/249305/
Нажмите здесь для печати.