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

如何正确使用LibGdx的isAnimationFinished()方法控制动画时序

LibGDX非循环动画播放问题修复

你的三个问题根源完全一致:误用了全局累计的elapsedTime作为动画的stateTime参数。LibGDX的Animation类需要的是从动画启动那一刻开始计时的专属时间,不是游戏启动到现在的总时长。

逐个对应你的问题:

  • 动画播放极慢/等待过久无法播放:全局elapsedTime数值太大,动画直接判定为已完成,或者直接跳到最后几帧,自然看起来慢或不播放
  • 动画仅播放一帧就被覆盖:大概率是你误以为被覆盖,实际是动画瞬间完成不再绘制,或者绘制顺序有问题(动画必须在所有地图元素之后画)

下面是具体修复步骤:

  1. 给动画加专属计时器
    在你的类里新增两个变量,分别控制动画的播放状态和运行时间:
private float sparkleTimer = 0f;
private boolean isPlayingSparkle = false;
  1. 触发动画时重置计时器
    在拾取物品或关卡完成的逻辑里,启动动画并把计时器归零:
// 比如拾取物品的触发代码里
levelComplete = true;
isPlayingSparkle = true;
sparkleTimer = 0f; // 必须重置,不然直接用累计时间会导致动画直接结束
  1. 只在播放时更新计时器
    在渲染循环里,只有当动画需要播放时才累加时间,同时判断是否播放完毕:
// 全局elapsedTime继续留着给其他逻辑用
elapsedTime += Gdx.graphics.getDeltaTime();

// 仅播放动画时更新专属计时器
if (isPlayingSparkle) {
    sparkleTimer += Gdx.graphics.getDeltaTime();
    // 动画播放完就关掉状态
    if (game.gameAnimations.itemPickUp.isAnimationFinished(sparkleTimer)) {
        isPlayingSparkle = false;
    }
}
  1. 调整绘制逻辑(确保层级正确)
    把动画绘制放在所有地图元素之后,保证它显示在最上层:
game.batch.begin();
// 先画所有底层元素:地板、墙、门
game.batch.draw(floor,160,160);
game.batch.draw(walls,128,160);
game.batch.draw(door,370,640);

if(!levelComplete){
    game.batch.draw(gate,384,640);
}else{
    // 只有在播放状态时才绘制动画
    if(isPlayingSparkle){
        game.batch.draw((TextureRegion) game.gameAnimations.itemPickUp.getKeyFrame(sparkleTimer, false),400,500);
    }
}

// 如果有角色、道具这类上层元素,要放在动画之前画,避免覆盖动画
game.batch.end();

最后再明确几个关键点:

  • isAnimationFinished和getKeyFrame接收的stateTime,必须是从动画启动开始的相对时间,不能用全局累计时间
  • getKeyFrame第二个参数传false,确保动画只播放一次,不会循环
  • 绘制顺序严格遵循“先底后上”,后画的元素会覆盖先画的,所以动画一定要放在所有需要显示在它下面的元素之后

内容的提问来源于stack exchange,提问作者Nicolás Miranda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:20:35