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
相关产品推荐
相关产品推荐

