diff --git a/src/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandler.java b/src/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandler.java index e27e61a8a..4106a8e76 100644 --- a/src/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandler.java +++ b/src/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandler.java @@ -4,6 +4,8 @@ import java.io.FileReader; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.awt.Dimension; import java.awt.Image; import java.awt.image.BufferedImage; @@ -11,6 +13,7 @@ import java.util.Map; import java.util.HashMap; import java.util.List; +import java.util.Arrays; import javax.imageio.ImageIO; import com.google.gson.Gson; @@ -43,7 +46,6 @@ public ImportAnimationException(String message) { /** * Imports an Aseprite animation (.json + sprite sheet). - * Note: searches for sprite sheet path through .json metadata, specifically 'image' element. This should be an absolute path in system. * * @param jsonPath path (including filename) to Aseprite JSON. * @@ -57,11 +59,11 @@ public static Animation importAnimation(String jsonPath) throws IOException, Fil throw new FileNotFoundException("FileNotFoundException: Could not find .json file " + jsonPath); } - String spriteSheetPath = getSpriteSheetPath(rootElement); - File spriteSheetFile = new File(spriteSheetPath); - if(!spriteSheetFile.exists()) { + File spriteSheetFile = null; + try { spriteSheetFile = getSpriteSheetFile(rootElement, jsonPath); } + catch(FileNotFoundException e) { throw new FileNotFoundException("FileNotFoundException: Could not find sprite sheet file. " + - "Expected location is 'image' in .json metadata, which evaluates to: " + spriteSheetPath); + "Expected location is 'image' in .json metadata, or same folder as .json file."); } Dimension keyFrameDimensions = getKeyFrameDimensions(rootElement); @@ -74,7 +76,7 @@ public static Animation importAnimation(String jsonPath) throws IOException, Fil } Spritesheet spriteSheet = new Spritesheet(image, - spriteSheetPath, + spriteSheetFile.getPath().toString(), (int)keyFrameDimensions.getWidth(), (int)keyFrameDimensions.getHeight()); @@ -100,6 +102,51 @@ private static JsonElement getRootJsonElement(String jsonPath) throws FileNotFou catch(FileNotFoundException e) { throw e; } } + /** + * Searches for sprite sheet path through .json metadata, or same folder as .json file. + * @param rootElement root element of JSON data. + * @param jsonPath path (including filename) to .json Aseprite file. + * + * @return sprite sheet file if it can be found, else an exception is thrown. + * */ + private static File getSpriteSheetFile(JsonElement rootElement, String jsonPath) throws FileNotFoundException { + + //try searching path supplied in .json data + JsonElement metaData = rootElement.getAsJsonObject().get("meta"); + String spriteSheetPath = metaData.getAsJsonObject().get("image").getAsString(); + + File spriteSheetFile = new File(spriteSheetPath); + + if(spriteSheetFile.exists()) + return spriteSheetFile; + + //try searching local directory + Path jsonFilePath = Paths.get(jsonPath); + String dirPath = jsonFilePath.getParent().toString(); + String fileName1 = jsonFilePath.getFileName().toString(); + String alternative1 = fileName1.substring(0, fileName1.lastIndexOf(".")); //same file name as .json + + Path spriteSheetFilePath = Paths.get(spriteSheetPath); + String fileName2 = spriteSheetFilePath.getFileName().toString(); + String alternative2 = fileName2.substring(0, fileName2.lastIndexOf(".")); //same file name as 'image' element + + List suffixes = Arrays.asList(".png", ".jpg", ".jpeg"); + for(String suffix : suffixes) { + + String alternativeFile1 = dirPath + "/" + alternative1 + suffix; + spriteSheetFile = new File(alternativeFile1); + if(spriteSheetFile.exists()) + return spriteSheetFile; + + String alternativeFile2 = dirPath + "/" + alternative2 + suffix; + spriteSheetFile = new File(alternativeFile2); + if(spriteSheetFile.exists()) + return spriteSheetFile; + } + + throw new FileNotFoundException(); + } + /** * @param rootElement root element of JSON data. * @@ -370,4 +417,4 @@ public Layer(String name, int opacity, String blendMode){ } } -} \ No newline at end of file +} diff --git a/tests/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandlerTests.java b/tests/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandlerTests.java index 3c337b4f5..a330552c4 100644 --- a/tests/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandlerTests.java +++ b/tests/de/gurkenlabs/litiengine/graphics/animation/AsepriteHandlerTests.java @@ -74,7 +74,7 @@ public void FileNotFoundExceptionTest(){ Throwable exception_withoutJsonFile = assertThrows(FileNotFoundException.class, () -> AsepriteHandler.importAnimation("tests/de/gurkenlabs/litiengine/graphics/animation/aseprite_test_animations/Sprite-0003.json")); assertEquals("FileNotFoundException: Could not find .json file tests/de/gurkenlabs/litiengine/graphics/animation/aseprite_test_animations/Sprite-0003.json", exception_withoutJsonFile.getMessage()); Throwable exception_withoutSpriteSheet = assertThrows(FileNotFoundException.class, () -> AsepriteHandler.importAnimation("tests/de/gurkenlabs/litiengine/graphics/animation/aseprite_test_animations/Sprite-0004.json")); - assertEquals("FileNotFoundException: Could not find sprite sheet file. Expected location is 'image' in .json metadata, which evaluates to: tests/de/gurkenlabs/litiengine/graphics/animation/aseprite_test_animations/Sprite-0002-sheet.png", exception_withoutSpriteSheet.getMessage()); + assertEquals("FileNotFoundException: Could not find sprite sheet file. Expected location is 'image' in .json metadata, or same folder as .json file.", exception_withoutSpriteSheet.getMessage()); } /**