使用 LibGdx 在 Java 中为 Sprite 表设置动画
Posted
技术标签:
【中文标题】使用 LibGdx 在 Java 中为 Sprite 表设置动画【英文标题】:Animating Sprite Sheets in Java using LibGdx 【发布时间】:2020-03-16 09:33:17 【问题描述】:我在这里有一些代码,它获取一个精灵表,并通过获取我的图像的长度和宽度并将其按行和列进行划分,将其划分为单独的精灵。这适用于我的测试精灵表,但不适用于我将实际用于我的游戏的那个。
我的动画课在这里:
package Simple;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.Animation;
public class RunningMan
private Texture texture;
private TextureRegion[] walkFrames;
private Animation walkAnimation;
private float stateTime = 0f;
private TextureRegion currentFrame;
int rows = 5;
int cols = 6;
public RunningMan(Texture texture)
this.texture = texture;
TextureRegion[][] tmp = TextureRegion.split(texture, texture.getWidth() / cols, texture.getHeight() / rows); // split the sprite sheet up into its 30 different frames
walkFrames = new TextureRegion[rows * cols];
int index = 0;
for(int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
walkFrames[index++] = tmp[i][j]; // Put the 30 frames into a 1D array from the 2d array
walkAnimation = new Animation(0.06f, walkFrames); // initialize the animation class
stateTime = 0f;
public void draw(Batch batch)
stateTime += Gdx.graphics.getDeltaTime(); // stateTime is used to determine which frame to show
if(stateTime > walkAnimation.getAnimationDuration()) stateTime -= walkAnimation.getAnimationDuration(); // when we reach the end of the animation, reset the stateTime
currentFrame = walkAnimation.getKeyFrame(stateTime); // Get the current Frame
batch.draw(currentFrame,50,50); // draw the frame
运行动画的班级在这里:
package Simple;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Animation extends ApplicationAdapter
SpriteBatch batch;
RunningMan man;
@Override
public void create ()
batch = new SpriteBatch();
man = new RunningMan(new Texture(Gdx.files.internal("WalkingMan.png")));
@Override
public void render ()
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
man.draw(batch);
batch.end();
当我使用WalkingMan.png 时,代码可以完美运行。但是当我去使用任何其他精灵表时,例如WalkingWoman.jpg(我不担心这个不透明),当相应地调整列和行时,对齐是关闭的。有什么建议?
WalkingMan.png
WalkingWoman.jpg
【问题讨论】:
如果您尝试使用这样的精灵表而不是 TextureAtlases/TexturePacker 来制作整个游戏,您将陷入痛苦的世界。 是否有一个论坛可以帮助我开始使用它? 首先阅读 libGDX github 页面上有关 TexturePacker 的 wiki 说明。然后,这些天获得帮助的最佳地点是 LibGDX Discord 服务器。挺热闹的。官方留言板论坛有点死了。 【参考方案1】:动画类似乎通过假设 spritesheet 图像中的所有帧均等间隔将源图像分割成帧。因此,对于 WalkingMan 图像,512x512px 的原始图像被分成 30 帧,每帧 85.33px 宽(512 / 6 列)和 102.4px 高(512 / 5 行)。
如您所说,如果您调整 WalkingWoman 图像(1300x935)的列号和行号,您将获得 36 帧,每帧宽 144.44 像素(1300 / 9 列),高 233.75 像素(935 / 4 行) )。
问题在于,WalkingWoman spritesheet 的每个帧的间距不均匀。如果你从图像中分割出第一帧,你会得到:
see how her foot is cut off on the right
WalkingMan 图像的每个图像都放置在 spritesheet 中的大小相同的边界框中。您只需要确保 WalkingWoman 工作表的每一帧以相同的方式均匀分布即可。
【讨论】:
我明白你在说什么。当我咨询朋友时,我得到了类似的答案,感谢您的帮助! 在旁注中,您是如何/您建议如何进行像素测量的简单方法,以便我以后可以仔细检查? 我在 Photoshop 中查看了目标精灵的固定选择大小 (144.44 x233.75),以查看纸张将被切断的位置。根据您的 spritesheets 的来源,完整的工作表可能带有元数据,详细说明了用于切片的偏移量。以上是关于使用 LibGdx 在 Java 中为 Sprite 表设置动画的主要内容,如果未能解决你的问题,请参考以下文章
(Java LibGDX) 如何在 LibGDX 中调整纹理的大小?
libGDX 设置允许我使用在 Android 中崩溃的 Java 8
如何在 Java 中将 libGDX 的纹理转换为字节数组并再次返回