package net.alcuria.umbracraft.engine.components;
import net.alcuria.umbracraft.Game;
import net.alcuria.umbracraft.definitions.anim.AnimationCollectionDefinition;
import net.alcuria.umbracraft.engine.components.AnimationGroupComponent.Direction;
import net.alcuria.umbracraft.engine.entities.Entity;
import net.alcuria.umbracraft.util.O;
import com.badlogic.gdx.utils.ObjectMap;
/** A component containing a collection of groups. Handles logic for updating the
* reference to the current group based on the entity's velocity, position, and
* so on.
* @author Andrew Keturi */
public class AnimationCollectionComponent implements Component {
public static enum Pose {
FALLING, IDLE, INSPECT, JUMPING, RUNNING, WALKING
}
private MapCollisionComponent collision;
private Direction currentDirection;
private AnimationGroupComponent currentGroup;
private Pose currentPose;
private final AnimationCollectionDefinition definition;
private ObjectMap<Pose, AnimationGroupComponent> groups;
private boolean visible = true;
public AnimationCollectionComponent(AnimationCollectionDefinition definition) {
this.definition = definition;
}
@Override
public void create(Entity entity) {
if (definition != null) {
groups = new ObjectMap<Pose, AnimationGroupComponent>();
groups.put(Pose.IDLE, new AnimationGroupComponent(definition.idle != null ? Game.db().animGroup(definition.idle) : null, definition.template, Pose.IDLE, definition.templateX, definition.templateY));
groups.put(Pose.WALKING, new AnimationGroupComponent(definition.idle != null ? Game.db().animGroup(definition.walking) : null, definition.template, Pose.WALKING, definition.templateX, definition.templateY));
groups.put(Pose.FALLING, new AnimationGroupComponent(definition.idle != null ? Game.db().animGroup(definition.falling) : null, definition.template, Pose.FALLING, definition.templateX, definition.templateY));
groups.put(Pose.JUMPING, new AnimationGroupComponent(definition.idle != null ? Game.db().animGroup(definition.jumping) : null, definition.template, Pose.JUMPING, definition.templateX, definition.templateY));
groups.put(Pose.RUNNING, new AnimationGroupComponent(definition.idle != null ? Game.db().animGroup(definition.running) : null, definition.template, Pose.RUNNING, definition.templateX, definition.templateY));
groups.put(Pose.INSPECT, new AnimationGroupComponent(definition.idle != null ? Game.db().animGroup(definition.inspect) : null, definition.template, Pose.INSPECT, definition.templateX, definition.templateY));
for (AnimationGroupComponent anim : groups.values()) {
anim.create(entity);
anim.setCardinalOnly(definition.cardinalOnly);
}
currentGroup = groups.get(Pose.IDLE);
collision = entity.getComponent(MapCollisionComponent.class);
}
}
@Override
public void dispose(Entity entity) {
}
public AnimationGroupComponent getGroup() {
return currentGroup;
}
private boolean isJumping(Entity entity) {
return collision != null && !collision.isOnGround();
}
private boolean isMoving(Entity entity) {
if (collision != null && collision.isOnStairs() && entity.velocity.z != 0) {
return true;
}
return entity.velocity.x != 0 || entity.velocity.y != 0;
}
@Override
public void render(Entity entity) {
if (currentGroup != null && visible) {
currentGroup.render(entity);
}
}
/** Sets a direction for the current active group in the collection.
* @param direction the {@link Direction} we want to change to */
public void setDirection(Direction direction) {
O.notNull(direction);
currentGroup.setDirection(direction);
}
/** Sets the current {@link Pose} and marks the
* {@link AnimationCollectionComponent} as visible.
* @param pose */
public void setPose(Pose pose) {
setVisible(true);
currentGroup = groups.get(pose);
currentGroup.setDirection(currentDirection);
}
/** @param visible whether or not the {@link AnimationCollectionComponent}
* gets rendered */
public void setVisible(boolean visible) {
this.visible = visible;
}
@Override
public void update(Entity entity) {
//save off last pose and get current pose/direction
Pose lastPose = currentPose;
if (lastPose != Pose.INSPECT) {
if (!isMoving(entity)) {
currentPose = Pose.IDLE;
} else if (isJumping(entity)) {
currentPose = Pose.JUMPING;
} else {
currentPose = Pose.WALKING;
}
currentDirection = currentGroup.getDirection();
}
// if the pose has updated, update reference to currentGroup and set direction
if (currentPose != lastPose) {
currentGroup = groups.get(currentPose);
currentGroup.setDirection(currentDirection);
} else {
currentGroup.update(entity);
}
}
}