`

Using Properties and Tile Map animations

 
阅读更多

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.

 

WaterTiles

 

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:

Te1

 

Right click on a tile and select Tile Properties...

Te2

Now we want to set a property “Water Frame” and give it the value of 1.

Te3

 

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:

Te4

 

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素材_使用TileMap快速构造2D关卡_

    TileMap(瓷砖地图)是一种高效且灵活的工具,常用于构建2D游戏的环境和场景。本素材包主要围绕如何使用TileMap来快速构造2D关卡,帮助开发者节省时间和精力,专注于游戏玩法的创新。 1. TileMap简介: TileMap是2...

    TileMap地图游戏资源

    TileMap是一种广泛应用于游戏开发中的技术,特别是在2D游戏领域,它允许开发者通过组合小块图形(称为“瓷砖”或“瓦片”)来构建大而复杂的游戏世界。这种技术可以高效地创建和管理游戏环境,同时保持低内存占用和...

    Super Tilemap Editor 1.7.0.unitypackage

    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 ...

    2d-extras插件unity Tilemap扩展

    2d-extras:unity tilemap 瓦片地图扩展。里面包含有很多实用的瓦片和笔刷。版本unity2018

    tilemap资源

    在游戏开发和图形设计领域,"Tilemap资源"是一个重要的概念,它涉及到地图构建和场景设计。Tilemap,顾名思义,就是“瓷砖地图”,是通过一系列小的图形(通常称为“瓷砖”或“图块”)拼接起来创建大地图的方法。...

    Unity3d Tile Map Accelerator 1.4 2D地图插件

    Unity3d 商店付费资源 适用于2d方形格子 和 2D菱形格子的Tile Map地图编辑插件 运行效率高,同屏支持超多格子 在Unity3d 2022.1版本中亲测可用

    Super Tilemap Editor 1.4.3.8.unitypackage

    Super Tilemap Editor 1.4.3.8.unitypackage Tilemap 制作插件

    Super Tilemap Editor 1.4.3.8

    "Super Tilemap Editor 1.4.3.8"就是这样一款强大的地图编辑软件,专为Unity引擎设计,旨在提供专业级的2D游戏地图制作体验。 首先,我们来详细了解一下"Super Tilemap Editor"的核心特性。这个版本1.4.3.8的更新,...

    tileMap.rar

    《Unity中的TileMap技术详解》 在Unity游戏引擎中,TileMap是一个强大的工具,用于创建和管理基于网格的游戏世界。这种技术广泛应用于2D游戏设计,允许开发者高效地构建复杂且可交互的地图环境。本文将深入探讨...

    高级主题(一) esri tilemap 四叉树索引研究

    ### 高级主题(一) esri tilemap 四叉树索引研究 #### 四叉树索引:esri tilemap与Google Map的区别 在地理信息系统(GIS)领域,地图切片技术是将地球表面的大面积地理信息切割成小块进行存储、传输和展示的一种...

    瓦片地图编辑工具Tilemap Editing Tools

    瓦片地图编辑工具Tilemap Editing Tools . 用TileMap制作了一张地图,是按照480 * 320制作的,但build到真机的时候,在ipod4上显示宽高只有原来的一半,不会自动拉伸自适应。那如果这样,我就按照960 * 480 来制作...

    TileMap 编辑器(后缀名丢失,下载请自行添加.zip,再解压)

    TileMap编辑器是一种用于创建和编辑游戏地图的工具,尤其在2D游戏开发中非常常见。TileMap,顾名思义,就是“瓦片地图”,它通过将一系列小的图像块(瓦片)拼接起来形成一个大的地图场景。这种技术在游戏设计中广泛...

    phaser-tilemap-plus:Tiled JSON映射文件的Tilemap动画,物理特性,事件和自定义属性增强

    移相器-tilemap-plus 一个游戏框架插件,可为从游戏框架内的 JSON映射文件...将Tiled地图导出为JSON格式以供库使用时,请确保在Maps&gt; Properties&gt; Tile Layer Format中设置以下格式之一: XML格式 Base64未压缩 CSV

    unity tileMap扩展包.zip

    Unity的TileMap系统是2D游戏开发中的一个重要组成部分,它允许开发者通过拼接小块图形(tiles)来创建复杂的2D场景。这个“unity tileMap扩展包.zip”提供了官方的额外功能,旨在增强TileMap的编辑能力和表现力,...

    Super Tilemap Editor 1.7.0

    《Super Tilemap Editor 1.7.0:Unity中的高效地图编辑工具》 在游戏开发领域,Unity引擎因其强大的功能和易用性而备受青睐。其中,地图编辑是游戏场景设计的重要环节,对于2D游戏尤其如此。Super Tilemap Editor ...

    unity 2d tilemap

    Unity 2D Tilemap是Unity引擎中的一个强大工具,它允许开发者创建出丰富的2D游戏场景,通过使用各种瓷砖(Tiles)进行拼接。在2D游戏开发中,Tilemap是一个不可或缺的部分,它能帮助我们高效地管理大量背景、角色和...

    MapTileLoader.rar_Map tile_maptile 下载_tile map_地图 瓦片_谷歌地图

    谷歌地图瓦片下载器,能够免费下载全部高清谷歌地图瓦片

    cocos2dx 3.3 tilemap 缩放滑动并且准确点击对象

    在Cocos2d-x 3.3版本中,开发2D游戏时经常使用TileMap(瓷砖地图)来构建游戏场景。TileMap允许开发者通过拼接小的图片(瓷砖)来创建复杂的地图,同时提供了高效的渲染和操作性能。在这个场景中,我们需要实现的...

    Super Tilemap Editor 1.3.0.unitypackage

    Super Tilemap Editor 1.3.0.unitypackage,下载导入工程即可

    3.1 Tilemap与Phy物理引擎接口测试

    在游戏开发领域,Tilemap和物理引擎的交互是至关重要的组成部分。Cocos2d-x是一个广泛使用的开源2D游戏开发框架,它集成了多种功能,包括Tilemap和物理引擎支持。"3.1 Tilemap与Phy物理引擎接口测试"项目就是针对这...

Global site tag (gtag.js) - Google Analytics