Libgdx之Animation 动画

来源:互联网 发布:淘宝女装上下架时间 编辑:程序博客网 时间:2024/05/23 02:20

教程总目录: http://blog.csdn.net/zqiang_55/article/details/50878524

一个好的游戏总归需要动画,Libgdx提供了Animation类来管理控制动画。
Animation: 储存了一组TextureRegion,然后顺序播放。例如在主角奔跑、跳跃的时候都需要用到Animation。每一个TextureRegion都是一帧,多帧组成了一组动画。

Animation的简单说明

这里写图片描述    这里写图片描述
上面的两幅图来自官方的wiki。 每个红色方框代表这一帧动画,代表了一个角色的一个跑步过程。我们将会用TextureRegion中split方法来切割这个图片。
在Animation中有一个参数 frameDuration 这个代表了每一帧图片在屏幕上显示的时间。1/frameDuration 就是帧率,也就是一秒钟显示多少幅图片。

Animationd 播放模式

  • NORMAL:这个不用说了,就是正常的播放模式。
  • REVERSED:反向播放,从后向前播放,这个就像人物倒退的跑。
  • LOOP:持续播放,这个比较常用。
  • LOOP_REVERSED:持续倒退播放。
  • LOOP_PINGPONG: 向前播放几张图片,再向后播放几帧图片。
    这里要注意一下,默认的初始化方法中只有一个是要初始化播放模式的,其余的默认都是PlayMode.NORMAL。这时可以通过setPlayMode方法来设置或者要通过获取关键帧的时候指定public TextureRegion getKeyFrame (float stateTime, boolean looping),如果此处设置为true,那么就设置PlayMode.LOOP

stateTime 的说明

在很多示例代码中都设置了这个stateTime,现在说说我的理解,stateTime就是一个时间计数器,初始化为stateTime=0

    /** Returns the current frame number.     * @param stateTime     * @return current frame number */    public int getKeyFrameIndex (float stateTime) {        if (keyFrames.length == 1) return 0;        int frameNumber = (int)(stateTime / frameDuration);        switch (playMode) {        case NORMAL:            frameNumber = Math.min(keyFrames.length - 1, frameNumber);            break;        case LOOP:            frameNumber = frameNumber % keyFrames.length;            break;        case LOOP_PINGPONG:            frameNumber = frameNumber % ((keyFrames.length * 2) - 2);            if (frameNumber >= keyFrames.length) frameNumber = keyFrames.length - 2 - (frameNumber - keyFrames.length);            break;        case LOOP_RANDOM:            int lastFrameNumber = (int) ((lastStateTime) / frameDuration);            if (lastFrameNumber != frameNumber) {                frameNumber = MathUtils.random(keyFrames.length - 1);            } else {                frameNumber = this.lastFrameNumber;            }            break;        case REVERSED:            frameNumber = Math.max(keyFrames.length - frameNumber - 1, 0);            break;        case LOOP_REVERSED:            frameNumber = frameNumber % keyFrames.length;            frameNumber = keyFrames.length - frameNumber - 1;            break;        }        lastFrameNumber = frameNumber;        lastStateTime = stateTime;        return frameNumber;    }

通过源码可以指定stateTime计算从开始播放动画开始,我们要计算经过多少个FPS时我们应该显示下一帧动画。

下面是测试代码

private static final String TAG = AnimationTest.class.getSimpleName();    private static final int FRAME_COLS = 6; // 用来做动画的图片有6*5    private static final int FRAME_ROWS = 5; // #2    Animation walkAnimation; // 定义Animation对象,用来装载TextureRegion    Animation reverseWalkAnimation;    Texture walkSheet; // 装载6*5的图片    TextureRegion[] walkFrames;    SpriteBatch spriteBatch;    TextureRegion currentFrame; // 记录关键帧,即当前要在batch画出的TextureRegion    Vector2 postion;    Direction direction;    float stateTime; // 记录动画时间    @Override    public void create() {        walkSheet = new Texture(Gdx.files.internal("sprite-animation1.png")); // #9        TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight() / FRAME_ROWS); // #10        walkFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS];        int index = 0;        for (int i = 0; i < FRAME_ROWS; i++) {            for (int j = 0; j < FRAME_COLS; j++) {                walkFrames[index++] = tmp[i][j];            }        }        walkAnimation = new Animation(0.025f, walkFrames); // #11        spriteBatch = new SpriteBatch(); // #12        postion = new Vector2(50, 50);        direction = Direction.RIGHT;        stateTime = 0f; // #13        Gdx.app.log(TAG, "frameDuration=" + walkAnimation.getFrameDuration());        Gdx.app.log(TAG, "frameDuration=" + walkAnimation.getAnimationDuration());    }    @Override    public void render() {        Gdx.gl.glClearColor(0.39f, 0.58f, 0.92f, 1.0f);        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);// #14        stateTime += Gdx.graphics.getDeltaTime(); // #15        if (direction == Direction.RIGHT) {            postion.x += 50 * Gdx.graphics.getDeltaTime();            walkAnimation.setPlayMode(PlayMode.LOOP);        } else if (direction == Direction.LEFT) {            postion.x -= 50 * Gdx.graphics.getDeltaTime();            walkAnimation.setPlayMode(PlayMode.REVERSED);        }        if (postion.x + walkFrames[0].getRegionWidth() > Gdx.graphics.getWidth() - 50) {            direction = Direction.LEFT;        } else if (postion.x < 50) {            direction = Direction.RIGHT;        }        currentFrame = walkAnimation.getKeyFrame(stateTime, true); // #16        spriteBatch.begin();        spriteBatch.draw(currentFrame, postion.x, postion.y); // #17        spriteBatch.end();    }    @Override    public void dispose() {        walkSheet.dispose();    }    enum Direction {        LEFT, RIGHT    }

动画比较难展示,大家自己来运行就可以。下面是log输出

AnimationTest: frameDuration=0.025
AnimationTest: frameDuration=0.75

1 0
原创粉丝点击