使用单个精灵动画精灵 sheet
Animating sprites using single sprite sheet
我之前通过为每个状态设置一个单独的 .png 和一个 textureAtlas 文件来为 sprite (standing/walking/jumping) 的不同状态设置动画。它工作正常。现在我将这些单独的工作表组合成一个 png 并生成了一个 .pack
文件。现在我可以按区域访问这些状态,但它们不再具有动画效果?只绘制每个状态的第一个精灵,而不是整个动画。
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
private SpriteBatch batch;
private TextureAtlas textureAtlas;
private TextureAtlas textureAtlas2;
private Animation animation;
private Animation animation2;
private Animation currentAnimation;
private float elapsedTime = 0;
@Override
public void create() {
batch = new SpriteBatch();
textureAtlas = new TextureAtlas(Gdx.files.internal("Wolverine.txt"));
animation = new Animation(1/7f, textureAtlas.findRegion("Standing"));
animation2 = new Animation(1/7f, textureAtlas.findRegion("Walking"));
currentAnimation = animation;
Gdx.input.setInputProcessor(this);
}
@Override
public void dispose() {
batch.dispose();
textureAtlas.dispose();
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
//sprite.draw(batch);
elapsedTime += Gdx.graphics.getDeltaTime();
batch.draw(currentAnimation.getKeyFrame(elapsedTime, true), 0, 0);
batch.end();
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public boolean keyDown(int keycode) {
if (keycode == Input.Keys.LEFT) {
currentAnimation = animation2;
}
return true;
}
@Override
public boolean keyUp(int keycode) {
return false;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
}
这是我在 spritesheet 中使用的数据文件
Wolverine.png
size: 256, 256
format: RGBA8888
filter: Linear,Linear
repeat: none
Standing
rotate: false
xy: 0, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 1
Standing
rotate: false
xy: 64, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 2
Standing
rotate: false
xy: 128, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 3
Walking
rotate: false
xy: 192, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 1
Walking
rotate: false
xy: 0, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 2
Walking
rotate: false
xy: 64, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 3
Walking
rotate: false
xy: 128, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 4
Walking
rotate: false
xy: 192, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 5
Walking
rotate: false
xy: 0, 128
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 6
问题是您只向 Animation
构造函数提供了一个动画帧。准确地说,您正在使用此构造函数:
public Animation(float frameDuration, TextureRegion... keyFrames)
只有一帧。您需要将要包含在动画中的所有帧传递给 Animation。
在你的 textureAtlas
中,所有 Standing 或 Walking 精灵都被命名为 Standing 或 Walking 实际上他们应该被命名为例如
Standing0
Standing1
Standing2
...
和
Walking0
Walking1
Walking2
Walking3
...
他们在动画中的顺序。像这样重命名你的动画文件,然后将它们打包到纹理图集或作为热修复,你可以在你的 .pack
文件中重命名它们。
然后你可以使用
public Array<TextureAtlas.AtlasRegion> findRegions(java.lang.String name)
方法获取所有Standing/Walking like帧以将它们传递给动画所以:
textureAtlas.findRegions("Standing")
我之前通过为每个状态设置一个单独的 .png 和一个 textureAtlas 文件来为 sprite (standing/walking/jumping) 的不同状态设置动画。它工作正常。现在我将这些单独的工作表组合成一个 png 并生成了一个 .pack
文件。现在我可以按区域访问这些状态,但它们不再具有动画效果?只绘制每个状态的第一个精灵,而不是整个动画。
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
private SpriteBatch batch;
private TextureAtlas textureAtlas;
private TextureAtlas textureAtlas2;
private Animation animation;
private Animation animation2;
private Animation currentAnimation;
private float elapsedTime = 0;
@Override
public void create() {
batch = new SpriteBatch();
textureAtlas = new TextureAtlas(Gdx.files.internal("Wolverine.txt"));
animation = new Animation(1/7f, textureAtlas.findRegion("Standing"));
animation2 = new Animation(1/7f, textureAtlas.findRegion("Walking"));
currentAnimation = animation;
Gdx.input.setInputProcessor(this);
}
@Override
public void dispose() {
batch.dispose();
textureAtlas.dispose();
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
//sprite.draw(batch);
elapsedTime += Gdx.graphics.getDeltaTime();
batch.draw(currentAnimation.getKeyFrame(elapsedTime, true), 0, 0);
batch.end();
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public boolean keyDown(int keycode) {
if (keycode == Input.Keys.LEFT) {
currentAnimation = animation2;
}
return true;
}
@Override
public boolean keyUp(int keycode) {
return false;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
}
这是我在 spritesheet 中使用的数据文件
Wolverine.png
size: 256, 256
format: RGBA8888
filter: Linear,Linear
repeat: none
Standing
rotate: false
xy: 0, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 1
Standing
rotate: false
xy: 64, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 2
Standing
rotate: false
xy: 128, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 3
Walking
rotate: false
xy: 192, 0
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 1
Walking
rotate: false
xy: 0, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 2
Walking
rotate: false
xy: 64, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 3
Walking
rotate: false
xy: 128, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 4
Walking
rotate: false
xy: 192, 64
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 5
Walking
rotate: false
xy: 0, 128
size: 64, 64
orig: 64, 64
offset: 0, 0
index: 6
问题是您只向 Animation
构造函数提供了一个动画帧。准确地说,您正在使用此构造函数:
public Animation(float frameDuration, TextureRegion... keyFrames)
只有一帧。您需要将要包含在动画中的所有帧传递给 Animation。
在你的 textureAtlas
中,所有 Standing 或 Walking 精灵都被命名为 Standing 或 Walking 实际上他们应该被命名为例如
Standing0
Standing1
Standing2
...
和
Walking0
Walking1
Walking2
Walking3
...
他们在动画中的顺序。像这样重命名你的动画文件,然后将它们打包到纹理图集或作为热修复,你可以在你的 .pack
文件中重命名它们。
然后你可以使用
public Array<TextureAtlas.AtlasRegion> findRegions(java.lang.String name)
方法获取所有Standing/Walking like帧以将它们传递给动画所以:
textureAtlas.findRegions("Standing")