LibGDX游戏引擎-5-动画绘制(Animation)

一个游戏的动态展示是非常重要的,这期间必定对动画的定义要深入底层,我们都知道动画其实也就是由一张一张图片快速播放形成的,libgdx给我们提供了一个专门负责管理动画的Animation类,是专门负责做动画的管理和放映的。

Animation类 (动画容器)


Api定义:动画是由多个帧,在设定的时间间隔序列显示。比如,一个跑步的人一个动画可以通过运行时播放这些图像无限拍照他了。


功能用法:管理动画,设置随即播放模式和播放顺序。


使用方法: walkAnimation = new Animation(float fDuration, keyFrames)


第一个参数是播放每一帧的时间,后面是一个TestureRegion。下面我给大家介绍下,Animation的原理,下图显示了一个完整的运行一个周期。它被称为精灵表。每个矩形是一个精灵,它被称为一个框架。先创建运行动画,在精灵要绘制后,随着时间的推移,绘制另一个矩形内的图片。
一般动画都是用一张图片,然后配合TextureRegion来实现的。下面我们官方的动画来做演示


代码解读:

由于代码比较繁多,而且许多都是土豆之前讲解过的,所以这里土豆挑一些比较重要的来讲解下。这里我列举了几个,如:TextureRegion[][]数组、setPlayMode()方法、statetime的设置、

(1)TextureRegion[][]数组

代码:TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight() /FRAME_ROWS);

这个段代码是怎么回事呢?他是采用分离式的方法分分割传入的纹理,将获得的纹理分为一个二维数组。记住,前提是分割的矩形大小相等。然后使用临时变量,填充walkframes数组。这是样使用起来很方便。

(2) SetPlayMode()方法

它是Animation类自己封装的一个方法,是用来设置播放模式的,其中它提供的模式有6种:NORMAL、REVERSED、LOOP、LOOP_REVERSED、LOOP_PINGPONG、LOOP_RANDOM、。
NORMAL:这个不用说了,就是正常的播放模式。
REVERSED:反向播放,从后向前播放,这个就像人物倒退的跑。
LOOP:持续播放,这个比较常用。
LOOP_REVERSED:持续倒退播放。
LOOP_PINGPONG: 向前播放几张图片,再向后播放几帧图片。

(3) StateTime 使用

代码stateTime += Gdx.graphics.getDeltaTime(),他是一个获取一个状态下所持续的一个时间。就像我们在现实世界使用的时间一样,一般配合系统时间使用Gdx.graphics.getDeltaTime():获取系统渲染时间,一般默认是0.173秒。


详细实现:

 

 

package com.potato;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeBitmapFontData;
import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;
import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;
import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;
import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;

public class Map implements ApplicationListener {
   private static final int FRAME_COLS = 6;
   private static final int FRAME_ROWS = 5;

   Animation walkAnimation;
   Texture walkSheet;
   TextureRegion[] walkFrames;
   SpriteBatch batch;
   TextureRegion currentFrame;
   float stateTime;

   @Override
   public void create() {
       walkSheet = new Texture(Gdx.files.internal("animation_sheet.png"));
       TextureRegion[][] tmp = TextureRegion.split(walkSheet,
               walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight()
                       / FRAME_ROWS);
       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);
       walkAnimation.setPlayMode(walkAnimation.LOOP_PINGPONG);
       batch = new SpriteBatch();
       stateTime = 0f;
   }

   @Override
   public void render() {
       Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
       stateTime += Gdx.graphics.getDeltaTime();

       currentFrame = walkAnimation.getKeyFrame(stateTime, true);

       batch.begin();
       batch.draw(currentFrame, Gdx.graphics.getWidth() / 2,
               Gdx.graphics.getHeight() / 2);
       batch.end();
   }
   @Override
   public void resize(int width, int height) {
       // TODO Auto-generated method stub
   }
   @Override
   public void pause() {
       // TODO Auto-generated method stub
   }
   @Override
   public void resume() {
       // TODO Auto-generated method stub
   }
   @Override
   public void dispose() {
       // TODO Auto-generated method stub
   }
}
**例子:**
package com.qsuron;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class MyDemo implements ApplicationListener{
private static final int ROW = 5;
private static final int COL = 6;

private SpriteBatch batch;
private Animation animation;
private Texture texture;
private TextureRegion currentFrame;
private TextureRegion[] walkFrame;
private TextureRegion[][] array;
private BitmapFont font;
private float stateTime;

@Override
public void create() {
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("data/animation.png"));
walkFrame = new TextureRegion[ROW*COL];
array = TextureRegion.split(texture,texture.getWidth()/COL, texture.getHeight()/ROW);//图片是5行6列
for(int i=0;i<ROW;i++){
for(int j=0;j<COL;j++){
walkFrame[i*COL+j] = array[i][j];
}
}
animation = new Animation(0.05f,walkFrame);
animation.setPlayMode(Animation.LOOP_PINGPONG);
stateTime = 0;
font = new BitmapFont();
font.setColor(Color.RED);
font.setScale(3.0f);
}

@Override
public void dispose() {
batch.dispose();
}

@Override
public void render() {
Gdx.gl.glClearColor(0,0,0, 0);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stateTime += Gdx.graphics.getRawDeltaTime();
currentFrame = animation.getKeyFrame(stateTime,true);
batch.begin();
batch.draw(currentFrame,0,200);
batch.draw(texture,50,20);
font.draw(batch,"X", currentFrame.getRegionX()+55,currentFrame.getRegionY()+65);
font.draw(batch,"LibGDX - Animation Demo By qsuron", 0,320);
batch.end();
}

@Override
public void resize(int width, int height) {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

}