Libgdx之Animation 动画
Posted zqiang_55
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Libgdx之Animation 动画相关的知识,希望对你有一定的参考价值。
教程总目录: 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
以上是关于Libgdx之Animation 动画的主要内容,如果未能解决你的问题,请参考以下文章
Android动画之View Animation--alphatranslatescalerotate
android之animator 和animation 的区别