使用libgdx和Tiled为每个动画磁贴分别设置计时器

时间:2016-03-09 05:04:34

标签: java animation timer libgdx tiled

对于措辞不好的问题感到抱歉,但这是我能想到的最好的。

所以,我在使用libGDX(Java,桌面)和使用Tiled创建的平铺地图的游戏项目中遇到了一个小问题。

使用Tiled中的新动画磁贴编辑器功能,我创建了我的动画,一个爆炸炸弹。它很棒。

我使用此代码以编程方式将炸弹放置在地图上(在第二层)(简化为仅保留重要部分):

tiledMap = new TmxMapLoader().load("maps/mymap.tmx");
TiledMapTileSet tileset = tiledMap.getTileSets().getTileSet("bombe");
animatedBomb= tileset.getTile(882);

showBomb(my_random_x, my_random_y);

public void showBomb(int x, int y){
 TiledMapTileLayer layer = (TiledMapTileLayer) tiledMap.getLayers().get(1);
 TiledMapTileLayer.Cell cellToChange = layer.getCell(x, y);
 if(cellToChange != null){
      cellToChange.setTile(animatedBomb);
 }
}

正如我所说的那样,效果很好,但是有一个小问题(对我来说很重要)我似乎无法修复:随着每个炸弹的添加,它们似乎共享内部动画计时器。 例如:

动画持续17帧* 100毫秒。如果我在0.0s的游戏时间添加一个炸弹,然后在1.0s再添加一个炸弹,新炸弹将产生并直接改变到它的第10帧,这也是第一个炸弹的当前帧。

我希望每个磁贴都有独立的动画计时器。有可能吗?

我尝试使用Tiled的动画磁贴实现,或使用手动动画(使用AnimatedTiledMapTile及其静态磁贴阵列以编程方式创建),但行为是相同的。

更新

即使我尝试逐帧复制对象,手动间隔为0.2f,炸弹仍在同时爆炸。

        TiledMapTileSet tileset = tiledMap.getTileSets().getTileSet("bombe");
        AnimatedTiledMapTile originalBomb = (AnimatedTiledMapTile)tileset.getTile(882);

        //copying the StaticTiledMapTile array of originalBomb
        Array<StaticTiledMapTile> bombTiles = new Array<StaticTiledMapTile>();
        StaticTiledMapTile[] copyArray = bombeAnimee.getFrameTiles().clone();
        for(StaticTiledMapTile tile : copyArray){
            bombTiles.add(tile);
        }

        AnimatedTiledMapTile anotherBomb = new AnimatedTiledMapTile(0.2f,bombTiles);

        TiledMapTileLayer.Cell cellToChange = layer.getCell(x, y);
        cellToChange.setTile(anotherBomb);

2 个答案:

答案 0 :(得分:1)

我遇到了相同类型的问题,最终创建了一个自定义AnimatedTiledMapTile,删除了该文件中的所有静态变量并更改为私有,创建方式与创建AnimatedTiledMapTile等相同,

public class SimpleAnimatedTile implements TiledMapTile {

private long lastTiledMapRenderTime = 0;

private int id;

private BlendMode blendMode = BlendMode.ALPHA;

private MapProperties properties;

private MapObjects objects;

private StaticTiledMapTile[] frameTiles;

private int[] animationIntervals;
private int frameCount = 0;
private int loopDuration;
private long initialTimeOffset = TimeUtils.millis();

然后我在主GDX中创建了一个这样的数组,当用户选择一个图块时,它将向该数组添加一个新的SimpleAnimatedTile

private Array<SimpleAnimatedTile> animated_tile_array = new Array<SimpleAnimatedTile>();

在用户选择图块时,

animated_tile_array.add(new SimpleAnimatedTile(0.05f,tile_array));

然后用此替换地图图块,

tileCell.setTile(animated_tile_array.get(animated_tile_array.size - 1));

然后在渲染中,您需要调用一个方法,该方法将迭代并更新每个对象,

updateTileAnimations();

调用此方法,

private void updateTileAnimations()
{
    for(int i = 0; i < animated_tile_array.size; i++)
    {
        SimpleAnimatedTile tile = animated_tile_array.get(i);

        //something to be added to sort which tile will animate or not etc <-IMPORTANT
        //or call something in custom SimpleAnimatedTile
        tile.updateAnimationBaseTime();

    }

}

无论如何,这似乎阻止了同时更新所有内容的蜂拥效果。希望这可以帮助您实现一个快速而肮脏的实现,因此欢迎反馈以完善该解决方案。

答案 1 :(得分:0)

我认为你使用的是同一个animatedBomb实例,因为

tileset.getTile(882) 

可能会给你总是相同的实例。您只在不同的单元格上显示对象。

您可以尝试在方法中实例化一个新炸弹:

animatedBomb = new AnimatedBomb();