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

LibGDX开发中如何为Array存储的多个Sprite角色实现帧动画

实现敌人数组批量动画播放方案

原有实现参考

你之前单角色动画的切帧、初始化逻辑可以直接复用,核心是把动画能力下沉到Enemy类本身,再通过遍历数组统一更新绘制即可。

之前的单角色动画实现代码

spidey = new Texture("spidey.png");
TextureRegion[][] tmpFrames = 
TextureRegion.split(spidey,spidey.getWidth()/3,spidey.getHeight()/5);
animationFrames = new TextureRegion[15];
int index = 0;
for (int i=0; i<5; i++){
    for (int j=0; j<3; j++){
        animationFrames[index++] = tmpFrames[i][j];
    }
}
animation = new Animation(0.15f, (Object[]) animationFrames);

当前的敌人数组初始化代码

public void characters() {
enemies = new Array<Enemy>();
enemies.add(new Enemy(new Sprite(new Texture("img1.png")), spawn));
enemies.add(new Enemy(new Sprite(new Texture("img2.png")), spawn));
enemies.add(new Enemy(new Sprite(new Texture("img3.png")), spawn));
enemies.add(new Enemy(new Sprite(new Texture("img4.png")), spawn));      
}

具体实现步骤

  • 改造Enemy类,内置动画能力
    给Enemy类添加动画实例、帧时间记录字段,把切帧、动画初始化逻辑放到Enemy的构造方法中,避免每个敌人都写重复的切帧代码:
    public class Enemy {
        // 动画实例
        public Animation<TextureRegion> animation;
        // 动画播放状态时间
        public float stateTime;
        // 位置、尺寸属性
        public Vector2 position;
        public float width, height;
    
        /**
         * 带动画初始化的敌人构造方法
         * @param spriteSheet 敌人的精灵动画图集
         * @param frameCols 精灵图横向帧数
         * @param frameRows 精灵图纵向帧数
         * @param frameDuration 单帧持续时间
         * @param spawnPos 出生点位
         */
        public Enemy(Texture spriteSheet, int frameCols, int frameRows, float frameDuration, Vector2 spawnPos) {
            this.position = spawnPos;
            // 切分精灵图,逻辑和你之前单角色实现完全一致
            TextureRegion[][] tmpFrames = TextureRegion.split(
                    spriteSheet,
                    spriteSheet.getWidth() / frameCols,
                    spriteSheet.getHeight() / frameRows
            );
            TextureRegion[] animFrames = new TextureRegion[frameCols * frameRows];
            int index = 0;
            for (int i = 0; i < frameRows; i++) {
                for (int j = 0; j < frameCols; j++) {
                    animFrames[index++] = tmpFrames[i][j];
                }
            }
            animation = new Animation<>(frameDuration, animFrames);
            stateTime = 0f;
            // 初始化帧宽高
            width = spriteSheet.getWidth() / frameCols;
            height = spriteSheet.getHeight() / frameRows;
        }
    }
    
  • 调整敌人数组初始化逻辑
    替换原来传入单张静态纹理的写法,初始化每个敌人时传入对应精灵图集、帧数、帧间隔参数,每个敌人实例会自己生成独立的动画:
    public void characters() {
        enemies = new Array<Enemy>();
        // 注意参数要和每个敌人精灵图的实际帧数匹配,帧间隔可以根据效果调整
        enemies.add(new Enemy(new Texture("img1.png"), 3, 5, 0.15f, spawn));
        enemies.add(new Enemy(new Texture("img2.png"), 3, 5, 0.15f, spawn));
        enemies.add(new Enemy(new Texture("img3.png"), 3, 5, 0.15f, spawn));
        enemies.add(new Enemy(new Texture("img4.png"), 3, 5, 0.15f, spawn));
    }
    
  • 在渲染循环中批量更新、绘制所有敌人动画
    每帧遍历enemies数组,累加每个敌人的动画播放时间,获取当前应该显示的帧后绘制到屏幕即可:
    @Override
    public void render(float delta) {
        // 常规清屏操作
        ScreenUtils.clear(0.1f, 0.1f, 0.1f, 1);
        batch.begin();
        // 遍历所有敌人更新动画状态并绘制
        for (Enemy enemy : enemies) {
            // 累加状态时间,delta是两帧间隔,保证动画速度和帧率无关
            enemy.stateTime += delta;
            // 获取当前播放帧,第二个参数true表示循环播放
            TextureRegion currentFrame = enemy.animation.getKeyFrame(enemy.stateTime, true);
            // 绘制当前帧到敌人对应位置
            batch.draw(currentFrame, enemy.position.x, enemy.position.y, enemy.width, enemy.height);
        }
        batch.end();
    }
    

注意:如果不同敌人的动画帧数、尺寸、播放速度有差异,只需要在初始化对应Enemy实例时传入匹配的参数即可,不需要修改核心逻辑。记得在dispose()方法中统一释放所有加载的Texture资源,避免内存泄漏。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:06:07