最新消息:热烈庆祝IT小记上线!

LibGDX_4.9: 动画(Animation)

本文链接: http://blog.csdn.net/xietansheng/article/details/50187539

LibGDX 基础教程(总目录)

1. 概述

这里所说的动画是 2D 动画(com.badlogic.gdx.graphics.g2d.Animation),2D 动画由多个静态图片组成,将静态图片一张一张播放便成了动画。一个 Animation 对象存储了一个纹理区域(静态图片)列表代表动画序列。一个 Animation 对象中的每一个纹理区域被称为一个关键帧,多个关键帧组成了动画。

2. 代码示例

该示例中需要用到的图片如下(保存到本地,重命名为指定名称,放到 assets 资源文件夹中)。

文件名:animation_sheet.png (256*256):

animation_sheet.png

游戏主程序的启动入口类:

package com.libgdx.test;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

/**
 * 游戏主程序的启动入口类
 */
public class MainGame extends ApplicationAdapter {

    private SpriteBatch batch;

    private Texture walkSheetTexture;

    // 行走动画
    private Animation walkAnimation;

    private TextureRegion currentFrame;

    // 状态时间, 渲染时间步 delta 的累加值
    private float stateTime;

    @Override
    public void create() {
        // 创建 Batch
        batch = new SpriteBatch();

        // 创建纹理, animation_sheet.png 图片的宽高为 256 * 256, 由 5 行 6列 个不同状态的小人单元格组成
        walkSheetTexture = new Texture(Gdx.files.internal("animation_sheet.png"));

        int frameRows = 5;  // 小人单元格的行数
        int frameCols = 6;  // 小人单元格的列数

        int perCellWidth = walkSheetTexture.getWidth() / frameCols;     // 计算每一个小人单元格的宽度
        int perCellHeight = walkSheetTexture.getHeight() / frameRows;   // 计算每一个小人单元格的高度

        // 按照指定的宽高作为一个单元格分割大图纹理, 分割后的结果为一个 5 * 6 的纹理区域二维数组, 数组中的元素是分割出来的小人单元格
        TextureRegion[][] cellRegions = TextureRegion.split(walkSheetTexture, perCellWidth, perCellHeight);

        // 把二维数组变为一维数组, 因为 Animation 只能接收一维数组作为关键帧序列, 数组中的一个元素(小人单元格的纹理区域)表示一个关键帧
        TextureRegion[] walkFrames = new TextureRegion[frameRows * frameCols];
        int index = 0;
        for (int row = 0; row < frameRows; row++) {
            for (int col = 0; col < frameCols; col++) {
                walkFrames[index++] = cellRegions[row][col];
            }
        }

        // 使用关键帧(纹理区域)数组 walkFrames 创建一个动画实例, 每一帧(一个小人单元格/纹理区域)播放 0.05 秒
        walkAnimation = new Animation(0.05F, walkFrames);

        /*
         * 设置播放模式:
         * 
         * Animation.PlayMode.NORMAL: 正常播放一次(默认)
         * Animation.PlayMode.REVERSED: 倒序播放一次
         * 
         * Animation.PlayMode.LOOP: 正常循环播放
         * Animation.PlayMode.LOOP_REVERSED: 倒序循环播放
         * 
         * Animation.PlayMode.LOOP_RANDOM: 随机循环播放
         * Animation.PlayMode.LOOP_PINGPONG: 开关式(先正序再倒序)循环播放
         */
        walkAnimation.setPlayMode(Animation.PlayMode.LOOP);
    }

    @Override
    public void render() {
        // 黑色清屏
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        // 累加时间步(stateTime 也可表示游戏的运行时间)
        stateTime += Gdx.graphics.getDeltaTime();

        // 根据当前 播放模式 获取当前关键帧, 就是在 stateTime 这个时刻应该播放哪一帧
        currentFrame = walkAnimation.getKeyFrame(stateTime);

        batch.begin();

        // 绘制当前关键帧
        batch.draw(currentFrame, 50, 100);

        batch.end();
    }

    @Override
    public void dispose() {
        // 释放资源
        if (walkSheetTexture != null) {
            walkSheetTexture.dispose();
        }
        if (batch != null) {
            batch.dispose();
        }
    }

}

展示动画较麻烦,自行运行代码查看效果。

猜您喜欢

备案号:苏ICP备12016861号-4