http://www.gamefromscratch.com/post/2014/06/18/LibGDX-Tutorial-11-Tiled-Maps-Part-3-Using-Properties-and-Tile-Map-animations.aspx
In this part we are going to look at how to add animations to a TileMap in LibGDX. Along the way we are going to look at using Properties a very important part of using Tile maps, as properties contain your games “data”. First let’s take a look at setting properties in Tiled. I am adding a second Tileset to my existing map called “Water” using the following graphic I download from Google Images. Tiled doesn’t support animations, so we are going to hack support in using properties.
You can get more details on working with Tiled here.
Properties are set in the Tile, not the Cell in TileEd. Load the above image as a new Tileset in Tiled named Water. We are working with just 3 of the water tiles:
Right click on a tile and select Tile Properties...
Now we want to set a property “Water Frame” and give it the value of 1.
Now repeat for the next two water tiles, with the values 2 and 3 respectively.
In addition to Tile properties, you can also set properties at the Layer and Map level. Properties are just a name value pair of strings when imported into LibGDX. Let’s take a look at that process now.
Save your tiled map and add it to the assets folder of your project. Also add all the various texture maps used for tiles. Let’s look at some ( heavily commented ) code that builds on our earlier tile map example:
package com.gamefromscratch;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.*;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import java.util.*;
public class TiledTest extends ApplicationAdapter implements InputProcessor {
Texture img;
TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer tiledMapRenderer;
SpriteBatch sb;
Texture texture;
Sprite sprite;
ArrayList<TiledMapTileLayer.Cell> waterCellsInScene;
Map<String,TiledMapTile> waterTiles;
floatelapsedSinceAnimation = 0.0f;
@Override public void create () {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false,w,h);
// Position the camera over 100pixels and up 400 to capture more interesting part of map
camera.translate(100,400);
camera.update();
//Load our tile map
tiledMap = new TmxMapLoader().load("MyCrappyMap.tmx");
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
Gdx.input.setInputProcessor(this);
// We created a second set of tiles for Water animations
// For the record, this is bad for performance, use a single tileset if you can help it
// Get a reference to the tileset named "Water"
TiledMapTileSet tileset = tiledMap.getTileSets().getTileSet("Water");
// Now we are going to loop through all of the tiles in the Water tileset
// and get any TiledMapTile with the property "WaterFrame" set
// We then store it in a map with the frame as the key and the Tile as the value
waterTiles = new HashMap<String,TiledMapTile>();
for(TiledMapTile tile:tileset){
Object property = tile.getProperties().get("WaterFrame");
if(property != null)
waterTiles.put((String)property,tile);
}
// Now we want to get a reference to every single cell ( Tile instance ) in the map
// that refers to a water cell. Loop through the entire world, checking if a cell's tile
// contains the WaterFrame property. If it does, add to the waterCellsInScene array
// Note, this only pays attention to the very first layer of tiles.
// If you want to support animation across multiple layers you will have to loop through each
waterCellsInScene = new ArrayList<TiledMapTileLayer.Cell>();
TiledMapTileLayer layer = (TiledMapTileLayer) tiledMap.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);
Object property = cell.getTile().getProperties().get("WaterFrame");
if(property != null){
waterCellsInScene.add(cell);
}
}
}
}
@Override public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
tiledMapRenderer.setView(camera);
tiledMapRenderer.render();
// Wait for half a second to elapse then call updateWaterAnimations
// This could certainly be handled using an Action if you are using Scene2D
elapsedSinceAnimation += Gdx.graphics.getDeltaTime();
if(elapsedSinceAnimation > 0.5f){
updateWaterAnimations();
elapsedSinceAnimation = 0.0f;
}
}
// This is the function called every half a second to update the animated water tiles
// Loop through all of the cells containing water. Find the current frame and increment it
// then update the cell's tile accordingly
// NOTE! This code depends on WaterFrame values being sequential in Tiled
private void updateWaterAnimations(){
for(TiledMapTileLayer.Cell cell : waterCellsInScene){
String property = (String) cell.getTile().getProperties().get("WaterFrame");
Integer currentAnimationFrame = Integer.parseInt(property);
currentAnimationFrame++;
if(currentAnimationFrame > waterTiles.size())
currentAnimationFrame = 1;
TiledMapTile newTile = waterTiles.get(currentAnimationFrame.toString());
cell.setTile(newTile);
}
}
@Override public boolean keyDown(int keycode) {
return false;
}
@Override public boolean keyUp(int keycode) {
if(keycode == Input.Keys.LEFT)
camera.translate(-32,0);
if(keycode == Input.Keys.RIGHT)
camera.translate(32,0);
if(keycode == Input.Keys.UP)
camera.translate(0,-32);
if(keycode == Input.Keys.DOWN)
camera.translate(0,32);
if(keycode == Input.Keys.NUM_1)
tiledMap.getLayers().get(0).setVisible(!tiledMap.getLayers().get(0).isVisible());
if(keycode == Input.Keys.NUM_2)
tiledMap.getLayers().get(1).setVisible(!tiledMap.getLayers().get(1).isVisible());
return false;
}
@Override public boolean keyTyped(char character) {
return false;
}
@Override public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
@Override public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override public boolean scrolled(int amount) {
return false;
}
}
Basically what we do is load our map, then we loop through the “Water” tile set and grab a reference to any tile marked as a Waterframe. We then perform the same action, looping through all of the cells in our map ( on the first layer! ) and if the cells tile has a reference to a tile that has the Waterframe property defined. Then every half a second we update each cell to the next available frame of animation, or loop back to the first frame if none are available.
Now if you run this code, voila! Animated water:
In this case we manually updated tiles in the map. LibGDX does however present another option. They have recently added an Animated tile class. That said, this functionality is very new so warning ,there be dragons. In fact, I didn’t find a single implementation online, so this may in fact be the first!
Here is a code example using AnimatedTiledMapTile to achieve the same effect:
package com.gamefromscratch;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.*;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.maps.tiled.tiles.AnimatedTiledMapTile;
import com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile;
import com.badlogic.gdx.utils.Array;
public class TiledTest extends ApplicationAdapter{
Texture img;
TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer tiledMapRenderer;
SpriteBatch sb;
Texture texture;
Sprite sprite;
Array<AnimatedTiledMapTile> waterTilesInScene;
Array<StaticTiledMapTile> waterTiles;
floatelapsedSinceAnimation = 0.0f;
@Override public void create () {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false,w,h);
camera.translate(100,400);
camera.update();
tiledMap = new TmxMapLoader().load("MyCrappyMap.tmx");
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
TiledMapTileSet tileset = tiledMap.getTileSets().getTileSet("Water");
waterTiles = new Array<StaticTiledMapTile>();
for(TiledMapTile tile:tileset){
Object property = tile.getProperties().get("WaterFrame");
if(property != null) {
waterTiles.add(new StaticTiledMapTile(tile.getTextureRegion()));
}
}
waterTilesInScene = new Array<AnimatedTiledMapTile>();
TiledMapTileLayer layer = (TiledMapTileLayer) tiledMap.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);
Object property = cell.getTile().getProperties().get("WaterFrame");
if(property != null){
cell.setTile(new AnimatedTiledMapTile(0.5f,waterTiles));
}
}
}
}
@Override public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
tiledMapRenderer.setView(camera);
tiledMapRenderer.render();
}
}
Ultimately the logic is very similar. Here however we actually replace the tile type of for each water instance we find in our map with a AnimatedTiledMapTile. It is passed an interval to update ( 0.5 second again ) as well as an array of tiles to use as part of the animation. The logic is basically identical, you just have slightly less control and no longer have to handle the updating on your own!
相关推荐
使用TileMap快速构造2D关卡项目素材
TileMap地图游戏资源
Super Tilemap Editor is a powerful and easy to use tile editor with everything you need to create any game based on tiles. Use it not only to create tilemaps but also as a powerful level editor ...
tilemap资源
Super Tilemap Editor 1.4.3.8.unitypackage Tilemap 制作插件
Super Tilemap Editor 1.3.0.unitypackage,下载导入工程即可
unity 插件 Super Tilemap Editor 1.6.3 2d瓦片绘图插件 仅供学习...版本比较新,尽量用新版unity.
Super Tilemap Editor 1.4.3.8
移相器-tilemap-plus 一个游戏框架插件,可为从游戏框架内的 JSON映射文件...将Tiled地图导出为JSON格式以供库使用时,请确保在Maps> Properties> Tile Layer Format中设置以下格式之一: XML格式 Base64未压缩 CSV
cocos2dx 3.3 tilemap 缩放滑动并且准确点击对象 附件 http://blog.csdn.net/goodeveningbaby/article/details/42408387
Unity3d 商店付费资源 适用于2d方形格子 和 2D菱形格子的Tile Map地图编辑插件 运行效率高,同屏支持超多格子 在Unity3d 2022.1版本中亲测可用
谷歌地图瓦片下载器,能够免费下载全部高清谷歌地图瓦片
unity tileMap扩展包,官方出品,实现各种高级功能,提升地图编辑速度,包含编程tile,动画tile等等最新炫酷功能
ersi tilemap的四叉树详解与研究
2d-extras:unity tilemap 瓦片地图扩展。里面包含有很多实用的瓦片和笔刷。版本unity2018
Tile Based Map and Nav 是一款瓦片状网格辅助开发组件,采用C#语言编写。 该工具能够方便灵活地设置参数,从而帮助开发者快速生成地图和视窗布局。Tile Based Map and Nav提供一些示例场景,能够完美支持iOS和...
unity 上面rpg回合地图tile based map and nav 的插件
Super Tilemap Editor is a powerful and easy to use tile editor with everything you need to create any game based on tiles. Use it not only to create tilemaps but also as a powerful level editor ...
TileMap 编辑器(后缀名丢失,下载请自行添加.zip,再解压)
碰撞3d-tilemap 一种用于对象和tilemap之间的用户定义的碰撞检测的api。 var my_tilemap = [ 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 ]var collisions = require ( 'collide-3d-tilemap' ) ...