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
- Libgdx之Animation 动画
- Libgdx专题系列:对象篇 Animation动画
- libgdx [Animation]
- CSS3 动画之animation
- CSS3之动画Animation
- Android之Animation动画
- fusioncharts 之animation动画
- 动画Animation之抛物线
- Animation之tween动画
- Animation动画之alpha
- css动画之animation
- CSS3之动画animation
- Unity之Animation动画
- Animation---详解Android动画之Frame Animation
- Animation---详解Android动画之Tween Animation
- libgdx 动画
- CSS3特效之动画animation
- Animation之translate(位移动画)
- 判断单链表是否带环?若带环,求环的长度?求环的入口点?(C语言)
- 码农小汪-设计模式之-观察者模式 依赖倒置原则
- Leetcode-关于二叉树的对称性
- epoll介绍
- R语言求解线性方程组
- Libgdx之Animation 动画
- Python学习
- 阻塞队列实现生产者消费者模式
- 判断两个链表是否相交,若相交,求交点。(假设链表不带环)(C语言)
- 基数排序
- const用法
- 判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】(C语言)
- Oracle VM + centos7.1+openstack kilo 多结点安装教程---keystone的安装(2)
- 回文链表