Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [LibGDX] TiledMapTile IDs or something else to determine...  (Read 3050 times)
0 Members and 1 Guest are viewing this topic.
Offline kutucuk
« Posted 2013-05-12 12:49:10 »

Hi,
So I am trying to get my characters to respect to the tiledmap I created, and detect the collision when it happens.

I thought I could make a collision layer, mark the tiles I want for collision and then read them in the code. I don't know if this is doable or a good way of doing it, but that is how I thought I will achieve this if I can.

I created a map with Tiled software. Here is my map and the pictures I used for it: https://dl.dropboxusercontent.com/u/19432607/TiledMap.zip

I thought I could read the tile info from map.tmx and get the collision tile with its id. But it is encoded with Base64 Smiley So, that failed.
I tried to get all of the tiles, then list their ids etc. But that failed too as the ids are something like this: com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile@69acd952

I realized that I could use XML to create map.tmx. I did it and my collision tile has an id: 121. But I cannot use it. Because libgdx does not support XML with maps, or I couldn't get it to do so.

What is the direction I should be heading now?
Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 136
Projects: 4
Exp: 3 years



« Reply #1 - Posted 2013-05-12 14:48:56 »

What's your code to load the .tmx?
Offline kutucuk
« Reply #2 - Posted 2013-05-12 15:14:27 »

Hi,
For now, it is very simple. The whole class is here: http://www.java-gaming.org/?action=pastebin&id=577
I call loadMap from my WorldRendering class. Then render it with an OrthogonalTiledMapRenderer.

I used to render it layer by layer. But I couldn't see any benefits to that (Except for, characters could hide behind trees etc) for now.

In the beginning, I just loaded and rendered it in the WorldRendering class, but when I started to try map collision detection, I decided to move it to another class. I thought I could modify it without messing with other stuff.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Axeman

Senior Duke


Medals: 7



« Reply #3 - Posted 2013-05-12 15:21:49 »

I made a class called Wall and I set a tileproperty for my walltile to "solid" in my tilemap editor. Then when I read the .tmx file I made a new Wall object and stored it in a list. That way I had a list of bounding boxes to test collision against.
Offline kutucuk
« Reply #4 - Posted 2013-05-12 17:56:10 »

Hi Axeman,
I think I am not as experienced as you are with tile maps. Can you explain it in more detail or if you don't mind, can you share the code?
I felt like I needed to change something in the editor but I was not sure.
Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #5 - Posted 2013-05-12 18:28:41 »

I thought I could read the tile info from map.tmx and get the collision tile with its id. But it is encoded with Base64 Smiley So, that failed.
I tried to get all of the tiles, then list their ids etc. But that failed too as the ids are something like this: com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile@69acd952

Ough... that's not the tile id Wink It's the output of the tile with the default toString() method. (what's after the @ is the heap space location of the instance, if I remember that correctly... try out
System.out.println(new Object());
to get what I mean.

Moving on. This is you would get the ID of a Tile with libgdx:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
// First, we need to get the layer in which you create the tiles.
// In this case I assume you call the layer 'collision' layer in Tiled.
private int computeCollisionLayerIndex(TiledMap map) {
    for (int i = 0; i < map.getLayers().getCount(); i++) {
        // This is used to get the layer with the name "collision" from all layers
        // (The layers name in Tiled)
        if (map.getLayers().get(i).getName().equalsIgnoreCase("collision")) {
            return i;
        }
    }
    return -1;
}

// Now we surround getting the layer from the index
// with a little error handling:
public void whatevername(TiledMap map) {
    int collisionLayerIndex = computeCollisionLayerIndex(map);
    if (collisionLayerIndex != -1) {
        MapLayer layer = map.getLayers().get(collisionLayerIndex
        if (layer instanceof TiledMapTileLayer) {
            getCollisionTilesFrom((TiledMapTileLayer) layer);
        } else throw some kind of error
    } else throw some kind of error
}

// And finally we print the ID of each tile in the layer
// I don't know what you would do with the tiles in the end,
// and since I don't know what tile ID's your tiles have,
// I simply print them.
public void getCollisionTilesFrom(TiledMapTileLayer layer) {
    for (int x = 0; x < layer.getWidth(); x++) {
        for (int y = 0; y < layer.getHeight(); y++) {
            TiledMapTileLayer.Cell cell = layer.getCell(x, y);
            if (cell == null) continue; // There is no cell
            if (cell.getTile() == null) continue; // No tile inside cell
           
            System.out.println(cell.getTile().getID()); // Get the ID.
        }
    }
}

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline kutucuk
« Reply #6 - Posted 2013-05-12 18:40:30 »

matheus23, I thank you.
I think I'll have to look into your code a little bit and get back to you if I have questions Smiley In the first look, what makes your code complex to me looks like your error handling codes. So it should be fine.

Honestly, I am not sure what to do with tile ids Smiley I think I was going to do this:
1- Get the collision layer in which I only have two or three tiles filled. These tiles are my collision layers, the player won't pass through these.
2- Get the id of the tiles I filled in the collision layer in the Tiled software. I'm assuming this will give me some clues as to where these tiles are in the map.
3- Draw rectangles around these tiles so that I become able to use them as normal rectangles in the map.
4- Perform basic rectangle based collision detection.

Does that seem doable to you guys?
Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #7 - Posted 2013-05-12 18:47:22 »

Honestly, I am not sure what to do with tile ids Smiley I think I was going to do this:
1- Get the collision layer in which I only have two or three tiles filled. These tiles are my collision layers, the player won't pass through these.
2- Get the id of the tiles I filled in the collision layer in the Tiled software. I'm assuming this will give me some clues as to where these tiles are in the map.
3- Draw rectangles around these tiles so that I become able to use them as normal rectangles in the map.
4- Perform basic rectangle based collision detection.

Does that seem doable to you guys?
Yes. Definitely possible. Did that myself already with RuinsOfRevenge (see signature)... (though I did it somehow different)

The error handling (i. e. "
throw some kind of error
") is pseudocode, It's not actual code, it was some kind of comment...

You could run my code over the tiles you have in your collision layer and look what ID's they return. Or simply allow each tile in the collision layer to be a collidable. Finally with the x and y position in the loop, you have the position of the tiles and you finally create Rectangle's out of them.

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline kutucuk
« Reply #8 - Posted 2013-05-12 18:50:56 »

Thanks man. I'll look into it and get back this thread about whether I did it or failed.
Offline Axeman

Senior Duke


Medals: 7



« Reply #9 - Posted 2013-05-12 19:43:58 »

Hi Axeman,
I think I am not as experienced as you are with tile maps. Can you explain it in more detail or if you don't mind, can you share the code?
I felt like I needed to change something in the editor but I was not sure.

I was using Tiled as my tilemap editor. I right clicked my tile representing my wall and set tile properties for that specific tile. Notice I´m not setting the property for the layer or anything in the map: I´m using the specific tile. That way all tiles on the map have the same property. I had a property name "checkCollision", since different tiles reacted differently to collision. Walls were solid and Conveyor belt sped up the entity checking for collision.

Anyway, in my levelloader I wrote something like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
int tileHeight = 32;
int tileWidth = 32;
String type = "";
Array<Wall> wallTiles  = new Array<Wall>();
     
for(int layers = 0; layers < map.layers.size(); layers++) {
   for(int y = 0; y < map.height; y++)
      for(int x = 0; x < map.width; x++) {
           
              type = (map.getTileProperty(map.layers.get(layers).tiles[y][x], "CheckCollision"));
              if(type != null && type.equals("solid")) {
                 Wall wall = new Wall(x * tileWidth, y * tileHeight, tileHeight, tileWidth);
                 wallTiles.add(wall);
               }}


Note that this code is based on the old TiledMap API in LibGDX, but I figured it might be easier to read in code...

So basically I read the tilemap and check each tile if it has the property name "CheckCollision". If it returns the property value "solid" I create a new wall with position and tilesize and store it in the list.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kutucuk
« Reply #10 - Posted 2013-05-13 10:55:36 »

Thank you guys. I finally can detect my collision tiles and draw a rectangle around them.

It seems I should read a lot about tiled maps. Because I was not aware of a cell concept. I mean, I thought a tile is also a cell. So, if you guys direct me to a nice beginner documentation, it would be appreciated.

So I modified matheus23's code, because I already knew what layer and what name my collision layer had. This is what I have:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public void getCollisionTilesFrom() {
      TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(0);
      for (int x = 0; x < layer.getWidth(); x++) {
         for (int y = 0; y < layer.getHeight(); y++) {
            TiledMapTileLayer.Cell cell = layer.getCell(x, y);
            if (cell == null) {
               continue; // There is no cell
            }
            if (cell.getTile() == null) {
               continue; // No tile inside cell
            }
            // Get the ID
            System.out.println(cell.getTile().getId() + " x:" + x + " y:" + y);
         }
      }
   }


Then I thought assuming I want to draw a rectangle around one of these tiles, the position would be: x * tilewidth, y * tileheight, and the other parameters would be tilewidth, and tileheight So; Rectangle rect = new Rectangle(x *tilewidth, y * tileheight, tilewidth, tileheight);
That is right.

So, in a loop;
1  
2  
3  
4  
rend = new ShapeRenderer(); 
rend.begin(ShapeType.Filled);
rend.rect(x * tileWidth, y * tileHeight, tileWidth, tileHeight);
rend.end();


If anyone read, most of my problems I mentioned here (Deleted now) are gone.
I was trying to make camera movement and rectangle positions work as it should since this morning. It turns out I forgot to set projection matrix for the boxes. That was why it did not draw rectangles out of the viewport. It was also why the rectangles moved as the camera moved.
Offline dime26

Senior Duke


Medals: 2
Projects: 3
Exp: 5 years


Should traffic wardens be armed?


« Reply #11 - Posted 2013-05-13 16:59:23 »

I am using the same tile editor and decided to use the object layer to draw all sorts of objects including walls, when loading a map I load in all the objects then use this when moving, I did this as I don't want to mark each tile as passable.

This is a cut down version of my can_move function as there are other types of objects. So I am saying if the next move creates a collision don't allow it, so you stop a pixel or so away from a wall. 

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
   
public boolean can_move(float move_x, float move_y){
      boolean next_move_allowed = true;
     
      ArrayList<Collision> objArray = renderer.objArray;
      Rectangle player = hero.getHitbox();
      player.y = player.y + move_y;
      player.x = player.x + move_x;
           
      for (Collision obj : objArray) {      
         if (obj.getBounds().overlaps(player) && obj.isSolid()){
            next_move_allowed = false;      
         }  
      }  
     
      return next_move_allowed;
   }


Part of the code for loading my objects in:

1  
2  
3  
4  
5  
for (TiledObjectGroup group : this.getWorld().getMap().objectGroups) {
         for (TiledObject object : group.objects) {
            //System.out.println("Load: " + object.name + " type: " + object.type);
                        }
}


Under this I check what type of object it is and load it, also I flip the Y position as the co-ords between the map objects and screen are different.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (45 views)
2014-10-17 03:59:02

Norakomi (36 views)
2014-10-16 15:22:06

Norakomi (27 views)
2014-10-16 15:20:20

lcass (31 views)
2014-10-15 16:18:58

TehJavaDev (61 views)
2014-10-14 00:39:48

TehJavaDev (61 views)
2014-10-14 00:35:47

TehJavaDev (51 views)
2014-10-14 00:32:37

BurntPizza (67 views)
2014-10-11 23:24:42

BurntPizza (39 views)
2014-10-11 23:10:45

BurntPizza (81 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!