In the current (as of about 2 weeks ago) build of Slick, the Tilemap class does not perform any kind of input validation and outright dies if the format is not what it expects. Specifically, a NumberFormatException is thrown when attempting to load objects with no width or height.
Code:
org.newdawn.slick.SlickException: Failed to parse tilemap
at org.newdawn.slick.tiled.TiledMap.load(TiledMap.java:480)
at org.newdawn.slick.tiled.TiledMap.<init>(TiledMap.java:90)
at org.newdawn.slick.tiled.TiledMap.<init>(TiledMap.java:77)
at au.edu.csu.bofsa.GameLevel.<init>(GameLevel.java:127)
at au.edu.csu.bofsa.InGameState.enter(InGameState.java:85)
at org.newdawn.slick.state.StateBasedGame.update(StateBasedGame.java:261)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:657)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:408)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:318)
at au.edu.csu.bofsa.Main.main(Main.java:42)
Caused by: java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at org.newdawn.slick.tiled.TiledMap$GroupObject.<init>(TiledMap.java:823)
at org.newdawn.slick.tiled.TiledMap$ObjectGroup.<init>(TiledMap.java:779)
at org.newdawn.slick.tiled.TiledMap.load(TiledMap.java:473)
... 9 more
I've created a map with an object layer where each object has 0 width and 0 height. I only need to position information as these represent points.
In the GroupObject constructor around lines 817-826 are where the error occurs.
Code:
public GroupObject(Element element) throws SlickException {
name = element.getAttribute("name");
type = element.getAttribute("type");
x = Integer.parseInt(element.getAttribute("x"));
y = Integer.parseInt(element.getAttribute("y"));
width = Integer.parseInt(element.getAttribute("width"));
height = Integer.parseInt(element.getAttribute("height"));
//Snip
}
TilED does not include an attribute if it is = 0 as far as I can tell, which results in a file where the XML structure resembles:
Code:
<object name="Goal" type="Goal" x="832" y="448"/>
Because no width or height attribute exist, element.getAttribute("width") returns an empty string. Integer.parseInt("") throws an invalid number format exception (as an empty string is not a number).
To fix this each call to Integer.parseInt() needs to be surrounded by a try/catch block which sets appropriate defaults.
I've checked the current version of this document in SVN and the bug is still present there.
A simple fix would be to modify the code as shown:
Code:
public GroupObject(Element element) throws SlickException {
// The name and type attributes can be omitted, but as the variables are strings anyway the presence of an empty string is not an error.
name = element.getAttribute("name");
type = element.getAttribute("type");
// The x and y attributes are not omitted in testing, even with a 0 value.
x = Integer.parseInt(element.getAttribute("x"));
y = Integer.parseInt(element.getAttribute("y"));
try {
width = Integer.parseInt(element.getAttribute("width"));
} catch (NumberFormatException e) {
width = 0;
}
try {
height = Integer.parseInt(element.getAttribute("height"));
} catch (NumberFormatException e) {
height = 0;
}
//Snip
}