【问题标题】:Separate timer for each animated tile with libgdx and Tiled使用 libgdx 和 Tiled 为每个动画图块提供单独的计时器
【发布时间】:2016-06-23 08:07:08
【问题描述】:

很抱歉这个措辞不好的问题,但这是我能想到的最好的问题。

所以,我在使用 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.0 秒添加一个炸弹,然后在 1.0 秒添加另一个,新炸弹将生成并直接更改到第 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);

【问题讨论】:

    标签: java animation timer libgdx tiled


    【解决方案1】:

    我认为您使用的是相同的 animatedBomb 实例,因为

    tileset.getTile(882) 
    

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

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

    animatedBomb = new AnimatedBomb();
    

    【讨论】:

    • 不幸的是,我似乎无法让它工作。我尝试了多种方法,甚至用帧的副本和手动间隔制作另一个新对象,但它不想工作。我会在我的主要帖子中发布我尝试过的内容。
    【解决方案2】:

    我遇到了同样类型的问题,最终创建了一个自定义 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();
    
        }
    
    }
    

    无论如何,这似乎阻止了同时更新的群体效应。希望这会有所帮助,这是一个快速而肮脏的实现,因此欢迎提供反馈以完善解决方案。

    【讨论】:

    • 我无法访问原始项目,但这似乎很有意义。我会接受你的解决方案,因为它解决了问题!
    猜你喜欢
    • 2014-10-07
    • 2021-09-23
    • 2019-09-19
    • 2010-10-27
    • 2020-01-11
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多