You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TileMapLayer调用set_cell时触发瓦片生成动画?

解决方案:TileMapLayer瓦片生成时添加动画效果

针对你需要动态生成瓦片时播放过渡动画的需求,以下是几种可行的实现方案,无需修改引擎源码:

方案一:自定义瓦片生成函数 + 独立TileData控制AnimatedTexture

如果已经使用AnimatedTexture制作了瓦片过渡动画(比如从透明到显示的帧序列),可以通过自定义函数为每个新生成的瓦片创建独立的TileData,避免影响同ID的其他瓦片,并触发一次性动画:

func spawn_tile_with_anim(x: int, y: int, base_tile_id: int):
    # 获取基础瓦片的TileData并创建副本
    var base_tile = get_tile_data(base_tile_id)
    var new_tile = base_tile.duplicate()
    
    # 获取瓦片绑定的AnimatedTexture
    var anim_texture = new_tile.texture as AnimatedTexture
    if anim_texture:
        # 设置动画仅播放一次,播放后停在最后一帧
        anim_texture.loop = false
        anim_texture.play()
    
    # 将带独立动画的瓦片设置到目标位置
    set_cell(x, y, -1, false, false, false, new_tile)

优点:动画和瓦片本身绑定,无需额外管理节点;缺点:仅支持基于帧序列的动画,灵活性有限。

方案二:用AnimatedSprite过渡,完成后替换为瓦片

这种方法完全独立于TileMap的瓦片系统,适合实现更复杂的过渡动画(比如缩放、淡入、旋转等),步骤是先播放动画精灵,结束后再设置瓦片:

func spawn_tile_with_sprite(x: int, y: int, tile_id: int):
    var tile_size = get_tile_size()
    # 计算瓦片对应的世界坐标(对齐精灵中心)
    var world_pos = map_to_world(Vector2(x, y)) + tile_size / 2

    # 创建动画精灵并配置资源
    var anim_sprite = AnimatedSprite.new()
    # 替换为你提前制作好的动画帧资源路径
    anim_sprite.sprite_frames = preload("res://tile_spawn_anim.tres")
    anim_sprite.position = world_pos
    add_child(anim_sprite)

    # 播放动画并监听结束信号
    anim_sprite.play("spawn")
    anim_sprite.connect("animation_finished", self, "_on_anim_done", [x, y, tile_id, anim_sprite])

func _on_anim_done(x: int, y: int, tile_id: int, anim_sprite: AnimatedSprite):
    # 动画结束后设置瓦片
    set_cell(x, y, tile_id)
    # 清理动画节点
    anim_sprite.queue_free()

优点:支持任意类型的2D动画,自由度极高;缺点:需要额外管理动画节点的生命周期。

方案三:继承TileMapLayer重写set_cell方法

如果希望尽可能贴近“绑定到set_cell自动播放”的需求,可以自定义TileMapLayer子类,重写set_cell方法,自动触发动画逻辑:

extends TileMapLayer

func set_cell(x: int, y: int, tile_id: int, flip_h: bool = false, flip_v: bool = false, flip_d: bool = false, tile_data: TileData = null):
    # 先执行父类的set_cell逻辑
    super.set_cell(x, y, tile_id, flip_h, flip_v, flip_d, tile_data)
    
    # 仅当设置有效瓦片时触发动画
    if tile_id != -1:
        var target_tile = tile_data if tile_data else get_cell_tile_data(x, y)
        if target_tile:
            var anim_texture = target_tile.texture as AnimatedTexture
            if anim_texture:
                anim_texture.loop = false
                anim_texture.play()

使用时直接用这个自定义类替代原生TileMapLayer,每次调用set_cell都会自动播放瓦片的动画。注意:如果多个瓦片共享同一个TileData,会导致所有同ID瓦片同时播放动画,建议配合方案一的独立TileData使用。

内容的提问来源于stack exchange,提问作者HippoProgrammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:55:17