Объединение ресурсов с зависимостью от libGDX

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

Как я могу заставить эту структуру работать? Есть ли способ заставить зависимость включать свои активы? Альтернативой является дублирование всех активов для каждой игры, что я не считаю очень эффективным. Также активы по умолчанию находятся в модуле android, которого нет в зависимости от движка (движок представляет собой один модуль). Где разместить активы в модуле движка?


person Nicolas    schedule 29.01.2019    source источник
comment
Является ли ваш проект проектом Gradle, созданным с помощью генератора проектов LibGDX?   -  person Fooble    schedule 01.02.2019
comment
Проект движка — это всего лишь один модуль, но игры, в которые включен движок, — это проекты, сгенерированные с помощью генератора проектов. (оба основаны на Gradle)   -  person Nicolas    schedule 01.02.2019
comment
Глядя на эту страницу, я думаю, вы сможете хранить изображения в виде файла Classpath. github.com/libgdx/libgdx/wiki/File-handling Вам нужно только они должны быть доступны только для чтения, и они не являются игровыми активами, они являются частью вашего движка.   -  person Fooble    schedule 01.02.2019
comment
@Fooble Спасибо, похоже, что-то может сработать. Я попробую это завтра.   -  person Nicolas    schedule 01.02.2019
comment
Другим вариантом было бы отказаться от включения ресурсов в движок и импортировать атлас скинов и текстур. Таким образом, элементы могут иметь одинаковые имена, но различаться от игры к игре. github.com/libgdx/libgdx/wiki/Skin github.com/libgdx/libgdx/wiki/Texture-packer#textureatlas   -  person Fooble    schedule 01.02.2019
comment
Что вы имеете в виду, говоря, что движок импортирует атлас текстур? Будет ли он импортирован автоматически?   -  person Nicolas    schedule 01.02.2019


Ответы (2)


У нас есть установка, которая кажется похожей на то, что вы описали выше, с отношением «многие к одному» между проектами и активами. Вот потенциальный способ сделать это.

Основная идея:

  1. Иметь единую авторитетную папку активов
  2. Попросите отдельные проекты скопировать эту папку в свои выходные данные сборки во время сборки.
  3. Добейтесь этого, создав задачу компиляции проекта dependsOn или finalizedBy задачу копирования.
  4. Убедитесь, что Android и другие проекты довольны, скопировав активы в то место, где внутренние файловые API libgdx ищут этот конкретный тип проекта. (Например, проекты Android автоматически получают assets/ перед URI, предоставленным Gdx.files.internal(). Этот шаг больше зависит от вашей личной файловой структуры, поэтому может потребоваться небольшая настройка, чтобы получить правильный путь для всех проектов, но не получайте обескуражен!

Примечание: Gradle должен автоматически отслеживать, действительно ли изменился каталог ресурсов. Если ничего не обновлялось, то задачи копирования фактически станут неоперативными, что немного ускорит сборку для не первых запусков. Очевидно, что если вы сделаете cleanAssets, как я упоминаю ниже, это не будет применяться.

Преимущество этого подхода (во всяком случае, для меня) заключается в том, что он больше не полагается на межпроектные ссылки или навороченные манипуляции с путями к классам. Это просто настоящие файлы в реальных каталогах. Недостатком является то, что это увеличивает используемое дисковое пространство, поскольку в разных проектах может быть несколько физических копий ресурсов.

Следующий пример не является полным, но мы надеемся, что он даст вам достаточно информации.

Пример задачи копирования в действии. Этот конкретный пример берет каталог ресурсов из "основного" проекта и копирует его в проект Android.

android/build.gradle

task copyAssets(type: Copy) {
    from "../core/assets"
    into "./assets"
}

Пример того, как сделать сборку проекта Android зависимой от этой задачи:

android/build.gradle

afterEvaluate { project ->
    project.tasks.preDebugBuild {
        dependsOn copyAssets
    }

    project.tasks.preReleaseBuild {
        dependsOn cleanAssets
        finalizedBy copyAssets
    }
}

Вы заметите, что в preReleaseBuild я также добавил задачу cleanAssets. Всегда полезно очистить весь мусор и сделать новую копию во время производственной сборки. cleanAssets — это просто основная задача удаления.

Пример зависимости задачи копирования для проекта, отличного от Android:

build {
    finalizedBy copyAssets
}

Если вы все еще застряли, дайте мне знать, где, и я постараюсь помочь.

person Harvtronix    schedule 04.02.2019
comment
Отлично работает спасибо! Мне нужно было только изменить copyAssets на ":android:copyAssets" в сборке рабочего стола build.gradle, так как gradle не смог найти задачу. При упаковке моей игры в файл APK или JAR будут какие-то дополнительные действия или все будет так же? - person Nicolas; 05.02.2019
comment
Хороший! Если вы хотите избежать этой перекрестной ссылки на проект, вы можете сделать вторую задачу сборки copyAssets специфичной для настольного проекта, но это полностью на ваше усмотрение. Если вы поговорите с гуру Gradle, они порекомендуют не ссылаться явно на задачу одного проекта из другого, но спойлер: мы тоже делаем это в своем, ха-ха. - person Harvtronix; 05.02.2019
comment
Самое замечательное в наличии копии как части задачи сборки заключается в том, что любая задача, которая зависит от сборки, теперь также зависит от задачи copyAssets. Таким образом, учитывая сборку jar или apk по умолчанию, вы автоматически нажмете задачу сборки и/или preReleaseBuild во время развертывания. На самом деле вы можете проверить это из командной строки, если вы используете gradle или gradlew, выполнив пробный запуск и убедившись, что вы видите copyAssets в выводе команды. Что-то вроде: ./gradlew --dry-run :android:assembleRelease - person Harvtronix; 05.02.2019

Делайте это так, как это делает сама libgdx. В путь к классам включены активы, такие как arial-15.fnt, который находится в основном проекте по адресу gdx/src/com/badlogic/gdx/utils/. Взгляните на конструктор без параметров BitmapFont, как на него ссылаются.

person MrStahlfelge    schedule 01.02.2019
comment
Будет ли это также работать на Android, поскольку ресурсы не находятся в папке с ресурсами? - person Nicolas; 01.02.2019
comment
документация по FileHandle говорит, что звук и музыка не могут быть файлами пути к классам на Android, что будет проблемой для меня. Как-нибудь обойти это? - person Nicolas; 01.02.2019
comment
У нас был большой толчок к тому, чтобы переместить нашу папку с ресурсами, чтобы она была равной нашим подпроектам, что в некоторой степени связано с тем, что вы хотите сделать. Что мы сделали, так это добавили задачу Gradle, которая копирует все, что нам нужно, в проект Android во время сборки. Вы можете сделать это, указав, что задача сборки Android либо зависит от, либо завершена вашей пользовательской задачей копирования. При этом используется больше места на диске, но папка основных ресурсов остается авторитетным источником ресурсов для нескольких проектов. - person Harvtronix; 02.02.2019
comment
@Harvtronix Я думаю, что это лучший вариант, но я не смог заставить его работать. Должна ли задача быть в модуле Android или в основном модуле, поскольку рабочий стол также нуждается в ней? По какому пути вы копируете файлы? Что вы указываете в качестве рабочего каталога для конфигурации рабочего стола? Было бы очень полезно, если бы вы могли предоставить задачу gradle, если это возможно. - person Nicolas; 04.02.2019