把草稿删了,没想到也把发表的文章给删了,只好重新写了。不得不吐槽一下CSDN的博客系统。

简介

在我们开发游戏过程中,我们需要设置不同的关卡,如果我们直接使用使用图片来加载游戏,这将会使我们的游戏安装包本身变得非常臃肿。不过好在Libgdx给我们提供了瓦片地图,我们可以直接使用编辑器来编辑地图,然后使用Libgdx提供的API解析加载,而且地图图片还可以在不同地图上重复使用,节约了游戏安装包的空间。

瓦片地图介绍

地图编辑器 Tiled: http://www.mapeditor.org/download.html

TMX文件介绍:

注意:在这个文件中( image source=”tileset.png” trans=”5e81a2” width=”692” height=”692”/) image source默认是地图编辑器的绝对路径,只需要用笔记本修改为相对路径,然后吧对应的图片文件放到同一个目录下面就OK

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="30" height="12" tilewidth="21" tileheight="21"><tileset firstgid="1" name="tileset" tilewidth="21" tileheight="21" spacing="2" margin="2"><image source="tileset.png" trans="5e81a2" width="692" height="692"/></tileset><tileset firstgid="901" name="backgrounds" tilewidth="21" tileheight="21"><image source="backgrounds.png" trans="5e81a2" width="231" height="189"/></tileset><layer name="background" width="30" height="12"><data encoding="base64">加密的数据,太长,省略了</data></layer><layer name="terrain" width="30" height="12"><data encoding="base64">加密的数据,太长,省略了</data></layer><layer name="foreground" width="30" height="12"><data encoding="base64">加密的数据,太长,省略了</data></layer><objectgroup name="objects" width="30" height="12"><object name="player" x="63" y="126" width="21" height="21"/><object name="item.chest" x="147" y="63" width="21" height="21"/><object name="item.coin" x="252" y="21" width="21" height="21"/><object name="item.key" x="567" y="126" width="21" height="21"/><object name="trigger.exit" x="609" y="0" width="21" height="252"/><object name="item.coin" x="273" y="21" width="21" height="21"/><object name="item.coin" x="357" y="21" width="21" height="21"/><object name="item.coin" x="378" y="21" width="21" height="21"/><object name="trigger.exit" x="420" y="0" width="21" height="252"/></objectgroup><objectgroup name="physics" width="30" height="12"><object x="0" y="168"><polyline points="0,0 63,0 63,-21 105,-21 105,84 0,84 0,0"/></object><object x="378" y="189"><polyline points="0,-21 -21,0 -21,63 -105,63 -105,0 -126,-21"/></object><object x="252" y="168"><polyline points="0,0 21,0 21,-21 42,-21 42,-42 84,-42 84,-21 105,-21 105,0 126,0"/></object><object x="420" y="252"><polyline points="0,0 0,-63 21,-63 21,-84 42,-84 42,-126 63,-126 63,-105 84,-105 84,0 0,0"/></object><object x="546" y="252"><polyline points="0,0 0,-42 21,-42 21,-105 42,-105 42,-126 84,-126 84,0 0,0"/></object></objectgroup>
</map>

Libgdx 相关API介绍

1.com.badlogic.gdx.maps.Map implements Disposable
Map代表了我们用地图编辑器编辑完之后的TMX文件,实际上是其子类TiledMap来具体实现。主要包含1. MapProperties TMX文件的各种属性。2. MapLayers,Map layers是有序的并且是可索引的,可通过index来访问, MapLayer包含MapObject对象,可以通过方法来获取访问,Libgdx中有不同的MapObject可供使用,比如CircleMapObject, RectangleMapObject

方法、属性 描述
layers : MapLayers 地图中所包含的图层
properties : MapProperties 地图中所包含的对象
getLayers() : MapLayers 获取地图中所包含的图层
getProperties() : MapProperties 获取地图中的对象

2.com.badlogic.gdx.maps.tiled.TiledMap extends Map
TiledMap是Libgdx中真正承载TMX地图的类,代表了tiled map,增加了tiles 和 tiledsets
3.com.badlogic.gdx.maps.tiled.TiledMapTile : interface
代表了TiledMap中每个网格(瓦片),留意其方法就可以了

方法 描述
getId() : int 瓦片的ID
getTextureRegion() : TextureRegion 瓦片使用的TextureRegion
setTextureRegion(TextureRegion textureRegion) 设置瓦片的纹理
getOffsetX() : float 瓦片相对于x轴的位置
getProperties() : MapProperties 单个瓦片的属性

4.com.badlogic.gdx.maps.tiled.TiledMapTileSet implements Iterable<TiledMapTile>
TiledMapTile的实例,通常用来组成TiledMapLayer

方法、属性 描述
name : String 瓦片的name
tiles : IntMap<TiledMapTile> 瓦片
getTile (int id) : TiledMapTile 获取瓦片实例
iterator () : Iterator<TiledMapTile> 便利所有瓦片
removeTile (int id) 移除指定瓦片
size () 瓦片的数量

5.com.badlogic.gdx.maps.tiled.TiledMapTileSets implements Iterable<TiledMapTileSet>
其实看类名就知道是TiledMapTileSet的集合类,主要是提供工具帮助访问处理TiledMapTileSet。不做过多解释,可看源码。
6.com.badlogic.gdx.maps.MapLayer
MapLayer就是我们在地图编辑器中创建的Layer(普通Layer和ObjectLayer)对应,包含了Layer对应的object和properties

   // 下面列出的就是类中常用的属性,方法就是对属性的读写private String name = "";  // 图层的名字private float opacity = 1.0f;  // 透明度private boolean visible = true;  // 是否可见private MapObjects objects = new MapObjects();  // 包含的对象private MapProperties properties = new MapProperties();// 包含的属性  

7.com.badlogic.gdx.maps.tiled.TiledMapTileLayer extends MapLayer
TiledMap的Layer,具体的实现类


// Layer的高度和宽度
private int width;
private int height;
// 瓦片的高度和宽度
private float tileWidth;
private float tileHeight;
// 内部类,里面包含了private TiledMapTile tile
private Cell[][] cells;

8.com.badlogic.gdx.maps.MapLayers implements Iterable<MapLayer>
可被遍历的MapLayer合集,方便访问操作MapLayer,主要是TMX文件也是很多MapLayer的集合。

方法、属性 描述
get (int index) : MapLayer 根据索引获取MapLayer
get (String name) : MapLayer 根据名字返回找到的第一个匹配MapLayer
getIndex (String name) : int 根据名字返回查找到的第一个图片的位置
getCount () : int 获取TiledMap中Layer的数量
remove (int index) 移除指定TiledMapLayer
iterator () : Iterator<MapLayer> 迭代访问

9.com.badlogic.gdx.maps.MapObject
TiledMap里面包含的对象的基本属性,比如: name, opacity, color

private String name = "";
private float opacity = 1.0f;
private boolean visible = true;
private MapProperties properties = new MapProperties();
private Color color = Color.WHITE.cpy();

10.com.badlogic.gdx.maps.MapObjects implements Iterable<MapObject>
MapObject的集合,不做过多解释,可自己查询源码。
11.com.badlogic.gdx.maps.MapProperties
可索引的(indexed)string值,代表了Map中元素的属性,可以被递归访问,修改,和添加属性。

方法、属性 描述
get (int index) : MapLayer 根据索引获取MapLayer
get (String name) : MapLayer 根据名字返回找到的第一个匹配MapLayer
getIndex (String name) : int 根据名字返回查找到的第一个图片的位置
getCount () : int 获取TiledMap中Layer的数量
remove (int index) 移除指定TiledMapLayer
iterator () : Iterator<MapLayer> 迭代访问

12.com.badlogic.gdx.maps.tiled.TmxMapLoader
地图加载去,使用方法简单,可参考后面的源码
13.com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer
渲染地图, 使用方法简单,可参考后面源码

代码用例展示

1.TiledMapSample这个用例只是简单的展示加载和渲染地图,以及操作照相机,来展示地图的不同部分。

public class TiledMapSample extends ApplicationAdapter {private static final float VIRTUAL_WIDTH = 384.0f;private static final float VIRTUAL_HEIGHT = 216.0f; private static final float CAMERA_SPEED = 100.0f;private OrthographicCamera camera;
private Viewport viewport;private TiledMap map;
private TmxMapLoader loader;
private OrthogonalTiledMapRenderer renderer;private Vector2 direction;@Override
public void create() {      camera = new OrthographicCamera();viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, camera);loader = new TmxMapLoader();map = loader.load("p/platformer.tmx");renderer = new OrthogonalTiledMapRenderer(map);direction = new Vector2();
}@Override
public void dispose() {map.dispose();renderer.dispose();
}@Override
public void render() {Gdx.gl.glClearColor(0.8f, 0.8f, 0.8f, 1.0f);Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);updateCamera();renderer.setView(camera);renderer.render();
}@Override
public void resize(int width, int height) {viewport.update(width, height);
}private void updateCamera() {direction.set(0.0f, 0.0f);int mouseX = Gdx.input.getX();int mouseY = Gdx.input.getY();int width = Gdx.graphics.getWidth();int height = Gdx.graphics.getHeight();if (Gdx.input.isKeyPressed(Keys.LEFT) || (Gdx.input.isTouched() && mouseX < width * 0.25f)) {direction.x = -1;}else if (Gdx.input.isKeyPressed(Keys.RIGHT) || (Gdx.input.isTouched() && mouseX > width * 0.75f)) {direction.x = 1;}if (Gdx.input.isKeyPressed(Keys.UP) || (Gdx.input.isTouched() && mouseY < height * 0.25f)) {direction.y = 1;}else if (Gdx.input.isKeyPressed(Keys.DOWN) || (Gdx.input.isTouched() && mouseY > height * 0.75f)) {direction.y = -1;}direction.nor().scl(CAMERA_SPEED * Gdx.graphics.getDeltaTime());;camera.position.x += direction.x;camera.position.y += direction.y;TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().get(0);float cameraMinX = viewport.getWorldWidth() * 0.5f;float cameraMinY = viewport.getWorldHeight() * 0.5f;float cameraMaxX = layer.getWidth() * layer.getTileWidth() - cameraMinX;float cameraMaxY = layer.getHeight() * layer.getTileHeight() - cameraMinY;camera.position.x = MathUtils.clamp(camera.position.x, cameraMinX, cameraMaxX);camera.position.y= MathUtils.clamp(camera.position.y, cameraMinY, cameraMaxY);camera.update();
}
}

2. TiledMapObjectsSample示例不仅加载渲染地图也解析了里面包含的对象

public class TiledMapObjectsSample extends ApplicationAdapter {
private static final float SCALE = 0.2916f;
private static final int VIRTUAL_WIDTH = (int) (1280 * SCALE);
private static final int VIRTUAL_HEIGHT = (int) (720 * SCALE);

private static final float CAMERA_SPEED = 100.0f;private OrthographicCamera camera;
private Viewport viewport;
private SpriteBatch batch;private TiledMap map;
private TmxMapLoader loader;
TiledMapTileLayer layer;
private OrthogonalTiledMapRenderer renderer;private Vector2 direction;private Array<Sprite> enemies;
private Array<Sprite> items;
private Array<Sprite> triggers;
private Sprite player;
private TextureAtlas atlas;@Override
public void create() {camera = new OrthographicCamera();viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, camera);batch = new SpriteBatch();loader = new TmxMapLoader();map = loader.load("p/tiled-objects.tmx");renderer = new OrthogonalTiledMapRenderer(map, batch);atlas = new TextureAtlas(Gdx.files.internal("p/sprites.atlas"));direction = new Vector2();processMapMetadata();
}@Override
public void dispose() {map.dispose();renderer.dispose();atlas.dispose();batch.dispose();
}@Override
public void render() {Gdx.gl.glClearColor(0.8f, 0.8f, 0.8f, 1.0f);Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);updateCamera();renderer.setView(camera);renderer.render();batch.begin();for (Sprite enemy : enemies) {enemy.draw(batch);}for (Sprite item : items) {item.draw(batch);}for (Sprite trigger : triggers) {trigger.draw(batch);}player.draw(batch);batch.end();
}@Override
public void resize(int width, int height) {viewport.update(width, height);
}private void updateCamera() {direction.set(0.0f, 0.0f);int mouseX = Gdx.input.getX();int mouseY = Gdx.input.getY();int width = Gdx.graphics.getWidth();int height = Gdx.graphics.getHeight();if (Gdx.input.isKeyPressed(Keys.LEFT) || (Gdx.input.isTouched() && mouseX < width * 0.25f)) {direction.x = -1;} else if (Gdx.input.isKeyPressed(Keys.RIGHT) || (Gdx.input.isTouched() && mouseX > width * 0.75f)) {direction.x = 1;}if (Gdx.input.isKeyPressed(Keys.UP) || (Gdx.input.isTouched() && mouseY < height * 0.25f)) {direction.y = 1;} else if (Gdx.input.isKeyPressed(Keys.DOWN) || (Gdx.input.isTouched() && mouseY > height * 0.75f)) {direction.y = -1;}direction.nor().scl(CAMERA_SPEED).scl(Gdx.graphics.getDeltaTime());;camera.position.x += direction.x;camera.position.y += direction.y;// 获取Map编辑器里面最底层的Layer,同时也是tml文件里面最上面的一层layerfloat cameraMinX = viewport.getWorldWidth() * 0.5f;float cameraMinY = viewport.getWorldHeight() * 0.5f;float cameraMaxX = layer.getWidth() * layer.getTileWidth() - cameraMinX;float cameraMaxY = layer.getHeight() * layer.getTileHeight() - cameraMinY;camera.position.x = MathUtils.clamp(camera.position.x, cameraMinX, cameraMaxX);camera.position.y = MathUtils.clamp(camera.position.y, cameraMinY, cameraMaxY);camera.update();
}private void processMapMetadata() {// Load entitiesSystem.out.println("Searching for game entities...\n");enemies = new Array<Sprite>();items = new Array<Sprite>();triggers = new Array<Sprite>();layer = (TiledMapTileLayer) map.getLayers().get(0);MapObjects objects = map.getLayers().get("objects").getObjects();System.out.println("width=" + layer.getWidth() +"  tileWidth" + layer.getTileWidth());for (MapObject object : objects) {String name = object.getName();;String[] parts = name.split("[.]");RectangleMapObject rectangleObject = (RectangleMapObject) object;Rectangle rectangle = rectangleObject.getRectangle();System.out.println("Object found");System.out.println("- name: " + name);System.out.println("- position: (" + rectangle.x + ", " + rectangle.y + ")");System.out.println("- size: (" + rectangle.width + ", " + rectangle.height + ")");if (name.equals("enemy")) {Sprite enemy = new Sprite(atlas.findRegion("enemy"));enemy.setPosition(rectangle.x, rectangle.y);enemies.add(enemy);} else if (name.equals("player")) {player = new Sprite(atlas.findRegion("player"));player.setPosition(rectangle.x, rectangle.y);} else if (parts.length > 1 && parts[0].equals("item")) {Sprite item = new Sprite(atlas.findRegion(parts[1]));item.setPosition(rectangle.x, rectangle.y);items.add(item);} else if (parts.length > 0 && parts[0].equals("trigger")) {Sprite trigger = new Sprite(atlas.findRegion("pixel"));trigger.setColor(1.0f, 1.0f, 1.0f, 0.5f);trigger.setScale(rectangle.width, rectangle.height);trigger.setPosition(rectangle.x - rectangle.width * 0.5f, rectangle.y + rectangle.height * 0.5f);triggers.add(trigger);}}
}
}

libgdx之瓦片地图(TiledMap)相关推荐

  1. 转:瓦片地图TiledMap

    标签:tiledMap 3.x cocos tmx tile 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://shahdza.bl ...

  2. cocos2dx3.x加载瓦片地图TiledMap

    1.瓦片地图 就我个人理解所谓瓦片地图即由许多地图砖块拼成的整体的地图,这样的好处就是对不同地貌的地图块可以设置不同的属性,比如墙壁和河流显然是不能直接穿过的,而整体的地图显然要设置这样的属性就显得非 ...

  3. Cocos2d-x 3.x基础学习:瓦片地图TiledMap

    有谁还记得小时候玩的小霸王里的游戏?比如坦克大战.冒险岛.魂斗罗.吞食天地等,他们大部分都是基于Tile地图的游戏.但在手游中,基于瓦片地图的游戏很常见.如:<保卫萝卜>. 瓦片地图有专门 ...

  4. LibGDX游戏引擎-10-游戏地图(TiledMap)

    转载自:http://www.qiushurong.cn/2014/03/23/tiledmap/ 要做游戏地图,在libgdx中我们使用到的工具是TiledMap Editor,官方网址是:链接 T ...

  5. 【Cocos Creator实战教程(3)】——TiledMap(瓦片地图)组件

    1. 前言 瓦片地图是由一张一张的正方形小图片拼接成的地图,例如炸弹人,QQ堂都是非常典型的瓦片游戏.瓦片地图(Tile Map) 不但生成简单,并且可以灵活的用于Cocos2d-x引擎.不论你的游戏 ...

  6. Android访问瓦片地图 费流量,瓦片地图注意事项

    瓦片地图(Tiled Map)系列文章: 承接上一篇文章,再来聊聊一些coding方面的tips: TileMapAtlas.FastTMX和TMXTiledMap的选择 我们看到cocos2d-x提 ...

  7. Tiled 瓦片地图

    glory原创,首发于泰然,转载请注明出处 https://github.com/chukong/cocos-docs/blob/master/manual/framework/native/v3/t ...

  8. 瓦片地图 cocos

    [前言] 还记得我们小时候玩的小霸王里面的游戏吗?大部分都是基于Tile地图的游戏,如坦克大战.冒险岛.魂斗罗.吞食天地等.而在手游中,基于瓦片地图的游戏也很常见.如:<保卫萝卜>. 瓦片 ...

  9. Tiled结合Unity实现瓦片地图

    前段时间应公司需求做瓦片地图,cocos与瓦片地图的结合案例很多,但unity的却少之又少,做瓦片地图少不了Tiled Map Editor(下载地址),这个教程很多,也自带例子,关于怎么拼地图,这里 ...

  10. 从零开始实现自己的Kalimba——Cocos Creator新手教程系列(一)使用瓦片图Tiledmap设计游戏地图

    瓦片图Tiledmap可能是很多2d游戏开发者的偏爱,本节就Cocos Creator如何使用瓦片图进行详细的讲解. Tiled地图编辑器的下载安装不再赘述.下面介绍如何使用地图编辑器. 创建新地图. ...

最新文章

  1. 查看mysql是否安装成功和mysql的版本信息
  2. mysql编写完怎么执行_面试官:一条MySQL更新语句是如何执行的?
  3. js除法与C语言除法,JS算术运算符及用法
  4. python语言流程控制语句的格式_Python流程控制语句的深入讲解
  5. 华为交换机带宽不足会丢包吗_华为岳伟:品质家宽,释放F5G网络体验红利
  6. 音视频开发入门基础及视频会议即时通讯开源技术选择
  7. 沧海的孤塔-chimera
  8. 163邮箱登录不了Outlook解决方案
  9. excel启动时显示“操作系统当前的配置不能运行此应用程序”
  10. vue3关闭语法检测
  11. MDK V5.28来了,STM32G4也来了
  12. BOM系列之Navigator对象
  13. android 基础 materia design 设计
  14. dhu 1.2 链表的中间结点
  15. 免费分享我的匿名邮件群发系统,可匿名发送: 163 126 139 gmail qq 21cn 263 及各类企业级邮件
  16. 联诚发(LCF)教你LED租赁屏知识
  17. Android9.0 如何精准区分SDK接口和非 SDK接口
  18. 2019数学建模国赛Apython代码
  19. 极限编程的幻想与真实
  20. 【自动驾驶-3D目标检测】3DSSD:基于点的3D单级目标检测器

热门文章

  1. vba mysql 3706_Excel、VBA与MySQL交互
  2. 算法设计与分析 (知识点总结)
  3. 使用串口打印系统时间
  4. 机械工程专业英语复习
  5. VC6-VC2008转移到VC2015问题记录
  6. granfana 使用cdn模式加速页面加载
  7. NeatUpload IIS6.0注册问题
  8. 轻量级Java EE企业应用实战(第4版) Struts 2+Spring 4+Hibernate整合开发 含CD光盘1
  9. 天锐绿盾防泄密软件6.0新版本功能已优化!!!
  10. android 模拟gps坐标,android中模拟器中实现GPS坐标改变