Управление активами между версией рабочего стола и устройства в libgdx

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

Это прекрасно работает в настольном приложении, но дает мне исключение FileNotFound в приложении для Android:

Texture texture = new Texture(Gdx.files.internal("assets/someImage.png"));

Если я удалю "активы" из имени файла, это наоборот (Android работает, сбой рабочего стола):

Texture texture = new Texture(Gdx.files.internal("someImage.png"));

Я не уверен, в чем проблема. Структура папок точно такая же для обоих проектов... Каков правильный путь к этому с помощью libgdx?

Ответ 1

Вы должны хранить все свои активы в папке с файлами Android и связывать свой рабочий проект с этой папкой. Это краткое описание можно найти на http://www.badlogicgames.com/wordpress/?p=1537

EDIT: официальное руководство по настройке Project описывает, как это сделать. Он найден в http://code.google.com/p/libgdx/wiki/ProjectSetup#Asset_folder_setup

Помимо настройки проекта, я считаю, что ваш второй метод - это правильный способ ссылки на активы обоих проектов. После того, как вы исправите свою установку, она должна работать правильно в обеих средах.

Ответ 2

Папка "Ресурсы" для рабочего проекта также может быть выбрана с помощью Gradle - добавьте эту строку в build.gradle в папку desktop:

sourceSets.main.resources.srcDirs = [ "../android/assets/" ]

Или, если вы не создали проект Android:

sourceSets.main.resources.srcDirs = [ "../core/assets/" ]

Это должно правильно связать папку в Eclipse и IntelliJ при запуске задач eclipse/idea Gradle. По сравнению с созданием ссылок или вручную добавлением папки в исходный код, я думаю, что это самый простой способ настройки и управления.

Ответ 3

После большого количества экспериментов я обнаружил способ заставить это работать:

Для модуля android, Gdx.files.internal внедряется в папку ресурсов Android. Для настольного модуля Gdx.files.internal внедрен в папку проекта верхнего уровня.

Итак, если вы помещаете символическую ссылку из файлов или каталогов в свою папку ресурсов Android, находящуюся прямо под вашей папкой проекта верхнего уровня (то есть параллельно с файлами android, core, desktop и т.д.), то Gdx.files.internal будет работать для обоих.

% cd project
% ln -s android/assets/sound sound
% ln -s android/assets/images images

Бонусный совет - если вы используете окна, вы можете использовать команду mklink в командной строке cmd, чтобы создать их:

mklink /d sound d:\project\android\assets\sound
mklink /d images d:\project\android\assets\images

(обратите внимание, что окна can not обрабатывают относительные пути в символических ссылках, также вы должны запускать cmd как администратор)

убедитесь, что вы синхронизируете свои файлы, если вы это делаете и при работе.

Ответ 4

libGDX Wiki extract:

Настройка папки Asset
Проект Android имеет подпапку с именем assets, которая была создана автоматически. Файлы, доступные для приложения Android, должны быть размещены здесь. Это проблематично, потому что эти же файлы должны быть доступны для настольного приложения. Вместо того, чтобы хранить две копии всех файлов, проект рабочего стола можно настроить для поиска активов в Android-проекте:

Перейдите на вкладку Source, нажмите Link Source, Browse, выберите папку "активы" в своем проекте Android и нажмите OK.
Укажите "активы" для имени папки и нажмите Finish, затем OK.

Примечание. Если ваши настольные и Android-проекты находятся в одной родительской папке, вы можете использовать "PARENT-1-PROJECT_LOC/gamename-android/assets" для расположения папки связанных активов, где "gamename-android" - это имя ваш проект Android. Это лучше, чем жестко закодированный путь, если вы планируете делиться своими проектами с другими.

Ответ 5

Проверьте, находятся ли все ваши файлы в нижнем регистре в папке ресурсов Android.

Ответ 6

Ссылка на папку с ресурсами Android не очень хорошая идея, потому что:

1) Eclipse, скорее всего, скопирует вашу папку с указанными ресурсами в apk проекта Android, дублируя размер 2) пути должны быть агностиками платформы. Как я вижу, это проблема с реализацией JogFiles.

Лучше скопировать следующий класс в свой путь к классу:

package com.badlogic.gdx.backends.jogl;
/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.badlogic.gdx.backends.jogl;

import java.io.File;

import com.badlogic.gdx.Files;
import com.badlogic.gdx.files.FileHandle;

/**
 * Gdx class overrided in order to keep internal files paths platform independent.
 * Android search at "assets/" folder. And so we do here for jogl.
 */
final class JoglFiles implements Files {
    private static final String ASSETS_FOLDER = "assets";
    private final String externalPath = System.getProperty("user.home") + "/";

    @Override public FileHandle getFileHandle (String fileName, FileType type) {
        return new JoglFileHandle(fileName, type);
    }

    @Override public FileHandle classpath (String path) {
        return new JoglFileHandle(path, FileType.Classpath);
    }

    @Override public FileHandle internal (String path) {
        // append "asset/" prefix to those urls who did not already have it.
        if (!path.startsWith(ASSETS_FOLDER)) {
            path = ASSETS_FOLDER + File.separator + path;
        }
        return new JoglFileHandle(path, FileType.Internal);
    }

    @Override public FileHandle external (String path) {
        return new JoglFileHandle(path, FileType.External);
    }

    @Override public FileHandle absolute (String path) {
        return new JoglFileHandle(path, FileType.Absolute);
    }

    @Override public String getExternalStoragePath () {
        return externalPath;
    }

    @Override public boolean isExternalStorageAvailable () {
        return true;
    }
}