From 26e663e245479d5a7710b4267cb73f709d3acedc Mon Sep 17 00:00:00 2001 From: Quillraven Date: Thu, 29 May 2025 00:35:02 +0200 Subject: [PATCH] add animation fsm --- assets/maps/objects.tsx | 2 +- .../com/quillraven/ai/AnimationState.java | 59 +++++++++++++++++++ .../github/com/quillraven/component/Fsm.java | 21 +++++++ .../com/quillraven/screen/GameScreen.java | 4 ++ .../com/quillraven/system/FacingSystem.java | 35 +++++++++++ .../com/quillraven/system/FsmSystem.java | 18 ++++++ .../quillraven/tiled/TiledAshleySpawner.java | 2 + 7 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/io/github/com/quillraven/ai/AnimationState.java create mode 100644 core/src/main/java/io/github/com/quillraven/component/Fsm.java create mode 100644 core/src/main/java/io/github/com/quillraven/system/FacingSystem.java create mode 100644 core/src/main/java/io/github/com/quillraven/system/FsmSystem.java diff --git a/assets/maps/objects.tsx b/assets/maps/objects.tsx index 2442ce8..87124f6 100644 --- a/assets/maps/objects.tsx +++ b/assets/maps/objects.tsx @@ -3,7 +3,7 @@ - + diff --git a/core/src/main/java/io/github/com/quillraven/ai/AnimationState.java b/core/src/main/java/io/github/com/quillraven/ai/AnimationState.java new file mode 100644 index 0000000..2400931 --- /dev/null +++ b/core/src/main/java/io/github/com/quillraven/ai/AnimationState.java @@ -0,0 +1,59 @@ +package io.github.com.quillraven.ai; + +import com.badlogic.ashley.core.Entity; +import com.badlogic.gdx.ai.fsm.State; +import com.badlogic.gdx.ai.msg.Telegram; +import io.github.com.quillraven.component.Animation2D; +import io.github.com.quillraven.component.Animation2D.AnimationType; +import io.github.com.quillraven.component.Fsm; +import io.github.com.quillraven.component.Move; + +public enum AnimationState implements State { + IDLE { + @Override + public void enter(Entity entity) { + Animation2D.MAPPER.get(entity).setType(AnimationType.IDLE); + } + + @Override + public void update(Entity entity) { + Move move = Move.MAPPER.get(entity); + if (move != null && !move.getDirection().isZero()) { + Fsm.MAPPER.get(entity).getAnimationFsm().changeState(WALK); + } + } + + @Override + public void exit(Entity entity) { + } + + @Override + public boolean onMessage(Entity entity, Telegram telegram) { + return false; + } + }, + + WALK { + @Override + public void enter(Entity entity) { + Animation2D.MAPPER.get(entity).setType(AnimationType.WALK); + } + + @Override + public void update(Entity entity) { + Move move = Move.MAPPER.get(entity); + if (move.getDirection().isZero()) { + Fsm.MAPPER.get(entity).getAnimationFsm().changeState(IDLE); + } + } + + @Override + public void exit(Entity entity) { + } + + @Override + public boolean onMessage(Entity entity, Telegram telegram) { + return false; + } + } +} diff --git a/core/src/main/java/io/github/com/quillraven/component/Fsm.java b/core/src/main/java/io/github/com/quillraven/component/Fsm.java new file mode 100644 index 0000000..90fa46b --- /dev/null +++ b/core/src/main/java/io/github/com/quillraven/component/Fsm.java @@ -0,0 +1,21 @@ +package io.github.com.quillraven.component; + +import com.badlogic.ashley.core.Component; +import com.badlogic.ashley.core.ComponentMapper; +import com.badlogic.ashley.core.Entity; +import com.badlogic.gdx.ai.fsm.DefaultStateMachine; +import io.github.com.quillraven.ai.AnimationState; + +public class Fsm implements Component { + public static final ComponentMapper MAPPER = ComponentMapper.getFor(Fsm.class); + + private final DefaultStateMachine animationFsm; + + public Fsm(Entity owner) { + this.animationFsm = new DefaultStateMachine<>(owner, AnimationState.IDLE); + } + + public DefaultStateMachine getAnimationFsm() { + return animationFsm; + } +} diff --git a/core/src/main/java/io/github/com/quillraven/screen/GameScreen.java b/core/src/main/java/io/github/com/quillraven/screen/GameScreen.java index a795d2a..af5056d 100644 --- a/core/src/main/java/io/github/com/quillraven/screen/GameScreen.java +++ b/core/src/main/java/io/github/com/quillraven/screen/GameScreen.java @@ -10,6 +10,8 @@ import com.badlogic.gdx.utils.Disposable; import io.github.com.quillraven.GdxGame; import io.github.com.quillraven.asset.MapAsset; import io.github.com.quillraven.system.AnimationSystem; +import io.github.com.quillraven.system.FacingSystem; +import io.github.com.quillraven.system.FsmSystem; import io.github.com.quillraven.system.PhysicDebugRenderSystem; import io.github.com.quillraven.system.PhysicMoveSystem; import io.github.com.quillraven.system.PhysicSystem; @@ -36,6 +38,8 @@ public class GameScreen extends ScreenAdapter { // add ECS systems this.engine.addSystem(new PhysicMoveSystem()); this.engine.addSystem(new PhysicSystem(physicWorld, 1 / 60f)); + this.engine.addSystem(new FacingSystem()); + this.engine.addSystem(new FsmSystem()); this.engine.addSystem(new AnimationSystem(game.getAssetService())); this.engine.addSystem(new RenderSystem(game.getBatch(), game.getViewport(), game.getCamera())); this.engine.addSystem(new TestSystem(this.tiledService)); diff --git a/core/src/main/java/io/github/com/quillraven/system/FacingSystem.java b/core/src/main/java/io/github/com/quillraven/system/FacingSystem.java new file mode 100644 index 0000000..3088e94 --- /dev/null +++ b/core/src/main/java/io/github/com/quillraven/system/FacingSystem.java @@ -0,0 +1,35 @@ +package io.github.com.quillraven.system; + +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.Family; +import com.badlogic.ashley.systems.IteratingSystem; +import com.badlogic.gdx.math.Vector2; +import io.github.com.quillraven.component.Facing; +import io.github.com.quillraven.component.Move; + +public class FacingSystem extends IteratingSystem { + + public FacingSystem() { + super(Family.all(Facing.class, Move.class).get()); + } + + @Override + protected void processEntity(Entity entity, float deltaTime) { + Move move = Move.MAPPER.get(entity); + Vector2 moveDirection = move.getDirection(); + if (moveDirection.isZero()) { + return; + } + + Facing facing = Facing.MAPPER.get(entity); + if (moveDirection.y > 0f) { + facing.setDirection(Facing.FacingDirection.UP); + } else if (moveDirection.y < 0f) { + facing.setDirection(Facing.FacingDirection.DOWN); + } else if (moveDirection.x > 0f) { + facing.setDirection(Facing.FacingDirection.RIGHT); + } else { + facing.setDirection(Facing.FacingDirection.LEFT); + } + } +} diff --git a/core/src/main/java/io/github/com/quillraven/system/FsmSystem.java b/core/src/main/java/io/github/com/quillraven/system/FsmSystem.java new file mode 100644 index 0000000..9c993d7 --- /dev/null +++ b/core/src/main/java/io/github/com/quillraven/system/FsmSystem.java @@ -0,0 +1,18 @@ +package io.github.com.quillraven.system; + +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.Family; +import com.badlogic.ashley.systems.IteratingSystem; +import io.github.com.quillraven.component.Fsm; + +public class FsmSystem extends IteratingSystem { + + public FsmSystem() { + super(Family.all(Fsm.class).get()); + } + + @Override + protected void processEntity(Entity entity, float deltaTime) { + Fsm.MAPPER.get(entity).getAnimationFsm().update(); + } +} diff --git a/core/src/main/java/io/github/com/quillraven/tiled/TiledAshleySpawner.java b/core/src/main/java/io/github/com/quillraven/tiled/TiledAshleySpawner.java index 01fa079..85bd879 100644 --- a/core/src/main/java/io/github/com/quillraven/tiled/TiledAshleySpawner.java +++ b/core/src/main/java/io/github/com/quillraven/tiled/TiledAshleySpawner.java @@ -28,6 +28,7 @@ import io.github.com.quillraven.component.Animation2D; import io.github.com.quillraven.component.Animation2D.AnimationType; import io.github.com.quillraven.component.Facing; import io.github.com.quillraven.component.Facing.FacingDirection; +import io.github.com.quillraven.component.Fsm; import io.github.com.quillraven.component.Graphic; import io.github.com.quillraven.component.Move; import io.github.com.quillraven.component.Physic; @@ -127,6 +128,7 @@ public class TiledAshleySpawner { addEntityAnimation(tile, entity); addEntityMove(tile, entity); entity.add(new Facing(FacingDirection.DOWN)); + entity.add(new Fsm(entity)); entity.add(new Graphic(textureRegion, Color.WHITE.cpy())); this.engine.addEntity(entity);