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

Libgdx开发中if语句内Animation动画仅播放1秒问题咨询

问题根因
  • 动画绘制、雷击碰撞判定的逻辑全部嵌套在「小球碰撞顶部墙体」的单次触发判断块内,只有碰撞发生的那一帧会执行对应逻辑,球反弹后不再满足碰撞条件,后续帧不会再绘制动画,导致动画仅在碰撞帧触发一次,提前结束。
  • 没有独立维护雷击动画的计时状态,全局timepassed参数无法对应单个雷击动画的播放进度,会导致动画帧计算错误。
  • 雷击矩形的清理逻辑条件写反,只要列表非空或者动画未结束就直接删除第一个元素,会导致刚添加的碰撞判定框直接被清空,碰撞判定功能失效。
修复方案
  1. 先在类全局定义动画状态变量,单独记录雷击动画的播放状态和计时:
// 新增类全局变量
private float lightingStrikeTime = 0f;
private boolean isLightingPlaying = false;
private List<Rectangle> LightingStrikeRectArrayList = new ArrayList<>();
  1. 碰撞触发逻辑仅用于启动动画,不要把绘制、判定逻辑嵌套在碰撞判断块内:
// 小球碰撞顶墙触发逻辑
if(ball.getY() + ball.getHeight() > topWall.getY()) {
    if(!isLightingPlaying){
        isLightingPlaying = true;
        lightingStrikeTime = 0f;
        // 记录雷击位置
        LightingStrikeRectArrayList.add(new Rectangle(ball.getX(), Apm.HEIGHT - ball.getY() + ball.getHeight() / 2, topWall.getWidth(), topWall.getHeight()));
    }
    ball.reverseDirectionY();
}
  1. 把动画绘制、碰撞判定、状态清理的逻辑放到render()的全局帧循环中,每一帧都执行:
// 写在render()方法的全局绘制逻辑里,不要嵌套在碰撞判断块内
if(isLightingPlaying){
    // 累计动画播放时长
    lightingStrikeTime += Gdx.graphics.getDeltaTime();
    // 逐帧绘制雷击动画
    game.getBatch().draw(animation.getKeyFrame(lightingStrikeTime, false), ball.getX(), ball.getY() + ball.getHeight(), 0, 0, leftWall.getWidth(), leftWall.getHeight() * -1, 1, 1, 0f);
    // 逐帧判定雷击碰撞
    for (Rectangle rect : LightingStrikeRectArrayList) {
        if (rect.overlaps(playerHitbox)) {
            this.game.setScreen(new GameScreen(this.game));
        }
    }
    // 动画播放完成后清理状态
    if(animation.isAnimationFinished(lightingStrikeTime)){
        isLightingPlaying = false;
        LightingStrikeRectArrayList.clear();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:15:05