Tiled Integration - RotcivOcnarb/libgdx-helper-library GitHub Wiki
Introduction
Tiled is a free open source level editor that works on XML, and has integration with LibGDX to read map information. Awesome-LibGDX has gone even further to faster even more your work in designing levels with Tiled.
Tutorial
Lets reset the StateOne
class with its default empty state, and just keep the physics, gravity and debugdraw method calls:
public class StateOne extends State{
public StateOne(StateManager manager) {
super(manager);
}
public void create() {
enablePhysics(new StateOneListener(this));
enableDebugDraw();
setGravity(new Vector2(0, -20));
}
public void render(SpriteBatch sb) {
}
public void update(float delta) {
}
public void dispose() {
}
}
Don't remove the MyPlayer
class used in the first tutorial.
For now, let's create a new Tiled Map inside the assets folder of our project:
The only required thing here are setting a Fixed tile map, and Orthogonal orientation (Isometric and Hexagonal maps not supported yet), and remember to save inside the assets folder of your game.
For now lets import a tileset and put some tiles.
Here i created two tiled layers, one for blocks i want to have collision, and other one for blocks i dont want the player to collide.
The next thing is adding the player to the game. But how do we add a custom class we created to a tiled map?
First let's tweek a little in the MyPlayer
class. Because now we are dealing with TiledMap object instancing, we can override the other PlatformPlayer constructor, that is made specifically for this purpose:
public class MyPlayer extends PlatformPlayer{
public MyPlayer(ObjectInfo info, Vector2 position, Vector2 size) {
super(info, position, size);
}
public MyPlayer(ObjectInfo info, MapProperties properties) {
super(info, properties);
}
public void create() {
}
public void dispose() {
}
public void render(SpriteBatch sb, ShapeRenderer sr, OrthographicCamera camera) {
}
}
This new constructor deals with things a little different. It reads the "parameters" of the player, as Object Properties that we put inside the object in Tiled Editor.
Here we don't need to add anything because all information about the player (like position and size) will be passed via object properties in Tiled. So let's create an Object Layer inside tiled and put a rectangle object in the position we want:
We want the player to be the same size as before, so we put at Width and Height, 30 and 40, but we instantly see that the player gets too big for the map. Here we can do a little trick: First reduce the player to the size you think is proportional to the size, in that case i'm going to divide it by 2, making it 15 units in width, and 20 units in height. Remember the number 2 here, because we are going to scale the whole TiledMap by 2 when we load it on the game.
Let's continue by telling Awesome-LibGDX that this object in fact is an instance of MyPlayer
class. We do this by adding a property called class
wich is a String type. Inside the class value, we put the full class name, like com.mygdx.game.test.MyPlayer
(with package and all).
And that's it, now the map has all the information needed to load the class. The next step is tell Awesome-LibGDX WICH map to load in the StateOne
state.
This can be done simply by calling on the create
method:
setTmxMap("maps/text.tmx", 2);
Remember that we scaled down by 2 the size of our player? This is the time to tell the state that we want the map to be 2x bigger, so our player can be the size we expect it to be.
The first thing you notice is that the player simply passes through the tiles, that's why we never told the game wich tiles need to be blocked and wich don't. By default Awesome-LibGDX always treats tiles as non collidable, to enable collision we need to go to the Tiled Layer that has the tiles we want to collide, and add a boolean property called "block" and set it to true:
Now things should work as expected.
But again, our player is too fast to move. So let's add some more properties in the player object so we can control how it moves.
Here i added some more properties, but those properties are not things that PlatformPlayer
knows what to do, so we need to tell him manually how to interpret those properties.
In the MyPlayer
class, we can access those properties using a very simple method call:
get(String parameter name, Class class_cast);
So we can get those parameters and use them to give information about the player, like this:
public class MyPlayer extends PlatformPlayer{
public MyPlayer(ObjectInfo info, Vector2 position, Vector2 size) {
super(info, position, size);
}
public MyPlayer(ObjectInfo info, MapProperties properties) {
super(info, properties);
setTotalJumps(get("jumps", Integer.class));
setSpeed(get("speed", Float.class));
setJumpStrength(get("strength", Float.class));
}
public void create() {
}
public void dispose() {
}
public void render(SpriteBatch sb, ShapeRenderer sr, OrthographicCamera camera) {
}
}
And after doing this, we can now set the player parameters in the TiledMap itself!
But now, let's assume that you didn't want to make a TileBased platform anyway, you just wanted to do some physics calculations!
How do you put collisions and bodies without a GridBased structure?
Lets remove all the Tiled layers of the TiledMap, and work only with the Object Layer, wich we will also remove the player object. Let's also disable the grid for the sake of cleaness. Then lets add some rectangle, circles, and polygon objects on the map
To tell Awesome-LibGDX that those are physical bodies, we simply use the type
parameter (underneath the Name) to tell it its an object
. By default, the loader interpret objects as StaticBodies, and to set them to DynamicBodies, we need to explicitly set them, using the property bodyType: DynamicBody
Save and run the game, and voilá, physics working.
Obs: Image objects also work, as long as the image files are also in the assets folder.