2D動(dòng)畫是一種用于使用靜態(tài)圖像創(chuàng)建運(yùn)動(dòng)錯(cuò)覺(jué)的技術(shù)韧衣。 本文介紹如何使用LibGDX的動(dòng)畫類來(lái)創(chuàng)建動(dòng)畫盅藻。
動(dòng)畫由多個(gè)幀組成,以設(shè)定的間隔以序列顯示畅铭。 運(yùn)行 人的動(dòng)畫可以通過(guò)循環(huán)運(yùn)行并播放這些圖像來(lái)實(shí)現(xiàn)氏淑。
以下“sprite sheet”圖像顯示一個(gè)男人跑步的完整循環(huán)。 每個(gè)框包含一個(gè)動(dòng)畫幀硕噩。 當(dāng)這些幀在一段時(shí)間內(nèi)順序顯示時(shí)假残,它們就成了動(dòng)畫。
幀速率是每秒更改幀的頻率炉擅。 示例精靈表的完整運(yùn)行周期有30幀(6列和5行)辉懒。 如果該動(dòng)畫在一秒鐘內(nèi)完成一個(gè)周期阳惹,則每秒必須顯示30幀,因此幀速率為30 FPS眶俩。 每幀的時(shí)間(稱為幀時(shí)間或間隔時(shí)間)是FPS的倒數(shù)穆端,在這種情況下為每幀0.033秒。
動(dòng)畫是一個(gè)非常簡(jiǎn)單的狀態(tài)機(jī)仿便。 跑步的人根據(jù)精靈畫面有30個(gè)狀態(tài)。 編號(hào)的框架代表一個(gè)正在跑步的人經(jīng)歷的狀態(tài)攒巍,一次只有一個(gè)嗽仪。 當(dāng)前狀態(tài)由動(dòng)畫開(kāi)始以來(lái)的時(shí)間量決定。 如果少于0.033秒柒莉,我們?cè)跔顟B(tài)1闻坚,所以第一個(gè)sprite被繪制。 如果我們?cè)?.033和0.067秒之間兢孝,那么我們?cè)跔顟B(tài)2窿凤,依此類推。 如果動(dòng)畫循環(huán)跨蟹,則在顯示所有幀后返回到第一幀雳殊。
動(dòng)畫類
LibGDX's Animation (code) 類可用于輕松管理動(dòng)畫。 它的構(gòu)造函數(shù) 具有圖像列表和幀間隔時(shí)間窗轩。 在播放過(guò)程中夯秃,其getKeyFrame方法會(huì)根據(jù) 已用時(shí)間參數(shù),返回該時(shí)間的適當(dāng)圖像痢艺。
TextureAtlas使用示例
LibGDX's TextureAtlas (code)通常用于將許多單獨(dú)的紋理區(qū)域組合成的紋理集合,以減少昂貴的繪圖調(diào)用仓洼。 (details here).。
TexturePacker和TextureAtlas提供了一種方便的方法來(lái)生成動(dòng)畫堤舒。 動(dòng)畫的所有源圖像應(yīng)以最后的下劃線和幀號(hào)命名色建,如running_0.png,running_1.png舌缤,running_2.png等箕戳。TexturePacker將自動(dòng)使用這些數(shù)字作為幀號(hào)(只要將參數(shù)useIndexes設(shè)置為真)。
加載TextureAtlas之后友驮,可以立即獲取完整的框架數(shù)組漂羊,并將其傳遞到Animation構(gòu)造函數(shù)中:
public Animation<TextureRegion> runningAnimation;
//...
runningAnimation =
new Animation<TextureRegion>(0.033f, atlas.findRegions("running"), PlayMode.LOOP);
精靈示例演示
以下代碼片段將使用animation_sheet.png sprite-sheet創(chuàng)建一個(gè)動(dòng)畫,并將動(dòng)畫渲染到屏幕卸留。
public class Animator implements ApplicationListener {
// Constant rows and columns of the sprite sheet
private static final int FRAME_COLS = 6, FRAME_ROWS = 5;
// Objects used
Animation<TextureRegion> walkAnimation; // Must declare frame type (TextureRegion)
Texture walkSheet;
SpriteBatch spriteBatch;
// A variable for tracking elapsed time for the animation
float stateTime;
@Override
public void create() {
// Load the sprite sheet as a Texture
walkSheet = new Texture(Gdx.files.internal("animation_sheet.png"));
// Use the split utility method to create a 2D array of TextureRegions. This is
// possible because this sprite sheet contains frames of equal size and they are
// all aligned.
TextureRegion[][] tmp = TextureRegion.split(walkSheet,
walkSheet.getWidth() / FRAME_COLS,
walkSheet.getHeight() / FRAME_ROWS);
// Place the regions into a 1D array in the correct order, starting from the top
// left, going across first. The Animation constructor requires a 1D array.
TextureRegion[] 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];
}
}
// Initialize the Animation with the frame interval and array of frames
walkAnimation = new Animation<TextureRegion>(0.025f, walkFrames);
// Instantiate a SpriteBatch for drawing and reset the elapsed animation
// time to 0
spriteBatch = new SpriteBatch();
stateTime = 0f;
}
@Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Clear screen
stateTime += Gdx.graphics.getDeltaTime(); // Accumulate elapsed animation time
// Get current frame of animation for the current stateTime
TextureRegion currentFrame = walkAnimation.getKeyFrame(stateTime, true);
spriteBatch.begin();
spriteBatch.draw(currentFrame, 50, 50); // Draw current frame at (50, 50)
spriteBatch.end();
}
@Override
public void dispose() { // SpriteBatches and Textures must always be disposed
spriteBatch.dispose();
walkSheet.dispose();
}
}
使用以下的構(gòu)造函數(shù)可以快速創(chuàng)建動(dòng)畫
Method signature | Description |
---|---|
Animation (float frameDuration, TextureRegion... keyFrames) | 第一個(gè)參數(shù)是幀時(shí)間走越,第二個(gè)參數(shù)是構(gòu)成動(dòng)畫的區(qū)域(幀)數(shù)組 |
最佳做法
將幀與其他精靈一起打包成一個(gè)紋理,以優(yōu)化渲染耻瑟。 這用TexturePacker很容易完成旨指。
根據(jù)游戲類型確定合理數(shù)量的幀赏酥。 對(duì)于復(fù)古的街機(jī)風(fēng)格,10 fps可能就足夠了谆构,而更逼真的運(yùn)動(dòng)需要更多的幀裸扶。
資源
在這里獲取 sprite-sheet 資源 here.