Thats precisely the thing i have problem with. Im using animation state with multiple animations and it works. Sometimes. It pisses me off to no end. It works and it breaks for no reason. Also i need to reset root position every frame or it goes to 0.0. Im using AnimationStateTest as base. Here the relevant code:
public class Character extends GameObject{
public static enum CharacterState {IDLE, ATTACKING, DEFENDING, DYING, DONE}
protected Skeleton skeleton;
protected Animation idleAnimation;
protected Animation attackAnimation;
protected Animation defendAnimation;
protected Animation deathAnimation;
protected AnimationState animationState;
public Character(Assets assets, Rectangle bounds, int level) {
super(assets, bounds);
this.level = level;
}
protected void updateBones(){
final Bone root = skeleton.getRootBone();
root.setX(bounds.x+64);
root.setY(bounds.y);
root.setScaleX(Assets.SCALE*0.5f);
root.setScaleY(Assets.SCALE*0.5f);
skeleton.updateWorldTransform();
}
protected void loadAnims(String name){
SkeletonJson json = new SkeletonJson(assets.atlas);
SkeletonData skeletonData = json.readSkeletonData(Gdx.files.internal("data/SD/anim/"+name+"-skeleton.json"));
idleAnimation = json.readAnimation(Gdx.files.internal("data/SD/anim/"+name+"-idle.json"), skeletonData);
attackAnimation = json.readAnimation(Gdx.files.internal("data/SD/anim/"+name+"-attack.json"), skeletonData);
defendAnimation = json.readAnimation(Gdx.files.internal("data/SD/anim/"+name+"-hit.json"), skeletonData);
deathAnimation = json.readAnimation(Gdx.files.internal("data/SD/anim/"+name+"-dead.json"), skeletonData);
AnimationStateData mixing = new AnimationStateData();
mixing.setMixing(idleAnimation, attackAnimation, 0.5f);
mixing.setMixing(attackAnimation, idleAnimation, 0.5f);
mixing.setMixing(defendAnimation, idleAnimation, 0.5f);
mixing.setMixing(idleAnimation, defendAnimation, 0.5f);
mixing.setMixing(defendAnimation, attackAnimation, 0.5f);
mixing.setMixing(attackAnimation, defendAnimation, 0.5f);
mixing.setMixing(deathAnimation, defendAnimation, 0.5f);
mixing.setMixing(defendAnimation, deathAnimation, 0.5f);
mixing.setMixing(deathAnimation, idleAnimation, 0.5f);
mixing.setMixing(idleAnimation, deathAnimation, 0.5f);
animationState = new AnimationState(mixing);
animationState.setAnimation(idleAnimation, true);
skeleton = new Skeleton(skeletonData);
updateBones();
}
public void draw(SpriteBatch batch) {
skeleton.getColor().set(1, 1, 1, 1);
switch (state) {
case IDLE:
if (name.equals("zombie")){
skeleton.getColor().set(0,1,0,1);
}
break;
case ATTACKING:
skeleton.getColor().set(Character.attackColor);
break;
case DEFENDING:
skeleton.getColor().set(Character.deffendColor);
break;
case DYING:
skeleton.getColor().set(Character.deadColor);
break;
case DONE:
skeleton.getColor().set(Character.deaddColor);
break;
default:
break;
}
updateBones();
skeleton.draw(batch);
}
public void update(float delta) {
delta = delta/3;
animationState.update(delta);
switch (state) {
case IDLE:
if (animationState.getAnimation()!=idleAnimation)
animationState.setAnimation(idleAnimation, true);
break;
case ATTACKING:
if (animationState.getAnimation()!=attackAnimation)
animationState.setAnimation(attackAnimation, true);
if (animationState.getTime() >= attackAnimation.getDuration()){
if (actedOn == null){
state = CharacterState.IDLE;
} else {
state = CharacterState.DEFENDING;
actedOn = null;
}
}
break;
case DEFENDING:
if (animationState.getAnimation()!=defendAnimation)
animationState.setAnimation(defendAnimation, true);
if (animationState.getTime() >= defendAnimation.getDuration()){
if (actedOn != null){
attack(actedOn);
} else {
state = CharacterState.IDLE;
}
actedOn = null;
}
break;
case DYING:
if (animationState.getAnimation()!=deathAnimation)
animationState.setAnimation(deathAnimation, true);
if (animationState.getTime() >= deathAnimation.getDuration()){
state = CharacterState.DONE;
}
break;
}
animationState.apply(skeleton);
}
Ive trimmed this a little. Suggestions are welcome.