From 3ce24529640a1e65db8630c4842360974df13a63 Mon Sep 17 00:00:00 2001 From: Jeasonfire Date: Mon, 11 May 2015 23:18:38 +0300 Subject: [PATCH] Added AI system + a basic AI. --- .../saltosion/gladiator/GladiatorBrawler.java | 19 ++++-- .../saltosion/gladiator/components/CAI.java | 33 ++++++++++ .../gladiator/components/CPhysics.java | 10 +++ .../gladiator/listeners/AIListener.java | 19 ++++++ .../gladiator/listeners/ai/DummyAI.java | 43 +++++++++++++ .../saltosion/gladiator/systems/AISystem.java | 63 +++++++++++++++++++ .../gladiator/systems/PhysicsSystem.java | 5 +- 7 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 core/src/com/saltosion/gladiator/components/CAI.java create mode 100644 core/src/com/saltosion/gladiator/listeners/AIListener.java create mode 100644 core/src/com/saltosion/gladiator/listeners/ai/DummyAI.java create mode 100644 core/src/com/saltosion/gladiator/systems/AISystem.java diff --git a/core/src/com/saltosion/gladiator/GladiatorBrawler.java b/core/src/com/saltosion/gladiator/GladiatorBrawler.java index 1d17de8..9194d1c 100644 --- a/core/src/com/saltosion/gladiator/GladiatorBrawler.java +++ b/core/src/com/saltosion/gladiator/GladiatorBrawler.java @@ -8,6 +8,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.math.Vector2; +import com.saltosion.gladiator.components.CAI; import com.saltosion.gladiator.components.CCombat; import com.saltosion.gladiator.components.CPhysics; import com.saltosion.gladiator.components.CRenderedObject; @@ -15,6 +16,8 @@ import com.saltosion.gladiator.gui.ButtonNode; import com.saltosion.gladiator.gui.GUIManager; import com.saltosion.gladiator.input.InputHandler; import com.saltosion.gladiator.listeners.CombatListener; +import com.saltosion.gladiator.listeners.ai.DummyAI; +import com.saltosion.gladiator.systems.AISystem; import com.saltosion.gladiator.systems.CombatSystem; import com.saltosion.gladiator.systems.MiscManagerSystem; import com.saltosion.gladiator.systems.PhysicsSystem; @@ -45,6 +48,7 @@ public class GladiatorBrawler extends ApplicationAdapter { engine.addSystem(new RenderingSystem()); engine.addSystem(new CombatSystem()); engine.addSystem(new MiscManagerSystem()); + engine.addSystem(new AISystem()); engine.addEntityListener(new EntityListener() { @Override public void entityAdded(Entity entity) { @@ -56,6 +60,8 @@ public class GladiatorBrawler extends ApplicationAdapter { cs.updateEntities(engine); MiscManagerSystem mms = engine.getSystem(MiscManagerSystem.class); mms.updateEntities(engine); + AISystem ais = engine.getSystem(AISystem.class); + ais.updateEntities(engine); } @Override @@ -68,6 +74,8 @@ public class GladiatorBrawler extends ApplicationAdapter { cs.updateEntities(engine); MiscManagerSystem mms = engine.getSystem(MiscManagerSystem.class); mms.updateEntities(engine); + AISystem ais = engine.getSystem(AISystem.class); + ais.updateEntities(engine); } }); @@ -75,7 +83,7 @@ public class GladiatorBrawler extends ApplicationAdapter { guiManager = new GUIManager(); AppUtil.guiManager = this.guiManager; initializeTestGUI(); - + // Initialize stuff in the world initializePlayer(); initializeTestDummy(); @@ -107,7 +115,7 @@ public class GladiatorBrawler extends ApplicationAdapter { AppUtil.player = player; } - + public void initializeTestDummy() { Entity dummy = new Entity(); CRenderedObject renderedObject = new CRenderedObject(); @@ -129,8 +137,9 @@ public class GladiatorBrawler extends ApplicationAdapter { public void damageTaken(Entity source, int damageTaken) { System.out.println(String.format("I took %d damage! Damnit!", damageTaken)); } - - })); + + })); + dummy.add(new CAI().setReactDistance(5).setAIListener(new DummyAI())); engine.addEntity(dummy); dummy.getComponent(CCombat.class).inputs.put(Direction.UP, true); } @@ -171,7 +180,7 @@ public class GladiatorBrawler extends ApplicationAdapter { engine.addEntity(wall0); engine.addEntity(wall1); } - + public void initializeTestGUI() { Sprite img = SpriteLoader.loadSprite(Name.GROUNDIMG); ButtonNode button = new ButtonNode("test-button", img, img) { diff --git a/core/src/com/saltosion/gladiator/components/CAI.java b/core/src/com/saltosion/gladiator/components/CAI.java new file mode 100644 index 0000000..fba0c75 --- /dev/null +++ b/core/src/com/saltosion/gladiator/components/CAI.java @@ -0,0 +1,33 @@ +package com.saltosion.gladiator.components; + +import com.badlogic.ashley.core.Component; +import com.saltosion.gladiator.listeners.AIListener; + +/** + * + * @author Jens "Jeasonfire" Pitkänen + */ +public class CAI extends Component { + + private AIListener listener; + private float reactDistance = 1; + + public CAI setReactDistance(float reactDistance) { + this.reactDistance = reactDistance; + return this; + } + + public float getReactDistance() { + return reactDistance; + } + + public CAI setAIListener(AIListener listener) { + this.listener = listener; + return this; + } + + public AIListener getAIListener() { + return listener; + } + +} diff --git a/core/src/com/saltosion/gladiator/components/CPhysics.java b/core/src/com/saltosion/gladiator/components/CPhysics.java index 0279400..131cead 100644 --- a/core/src/com/saltosion/gladiator/components/CPhysics.java +++ b/core/src/com/saltosion/gladiator/components/CPhysics.java @@ -80,6 +80,16 @@ public class CPhysics extends Component { return this; } + public CPhysics setVelocity(float x, float y) { + this.velocity.set(x, y); + return this; + } + + public CPhysics setVelocity(Vector2 pos) { + this.velocity.set(pos); + return this; + } + public CPhysics setMoveSpeed(float movespeed) { this.movespeed = movespeed; return this; diff --git a/core/src/com/saltosion/gladiator/listeners/AIListener.java b/core/src/com/saltosion/gladiator/listeners/AIListener.java new file mode 100644 index 0000000..d32975b --- /dev/null +++ b/core/src/com/saltosion/gladiator/listeners/AIListener.java @@ -0,0 +1,19 @@ +package com.saltosion.gladiator.listeners; + +import com.badlogic.ashley.core.Entity; +import java.util.ArrayList; + +/** + * + * @author Jens "Jeasonfire" Pitkänen + */ +public interface AIListener { + + /** + * @param closeEntities A list of entities that are close to the host entity + * than the host entity's reactDistance. + * @param host The host entity of this listener + */ + public void react(ArrayList closeEntities, Entity host); + +} diff --git a/core/src/com/saltosion/gladiator/listeners/ai/DummyAI.java b/core/src/com/saltosion/gladiator/listeners/ai/DummyAI.java new file mode 100644 index 0000000..9ce8224 --- /dev/null +++ b/core/src/com/saltosion/gladiator/listeners/ai/DummyAI.java @@ -0,0 +1,43 @@ +package com.saltosion.gladiator.listeners.ai; + +import com.badlogic.ashley.core.ComponentMapper; +import com.badlogic.ashley.core.Entity; +import com.saltosion.gladiator.components.CCombat; +import com.saltosion.gladiator.components.CPhysics; +import com.saltosion.gladiator.listeners.AIListener; +import com.saltosion.gladiator.util.Direction; +import java.util.ArrayList; + +/** + * + * @author Jens "Jeasonfire" Pitkänen + */ +public class DummyAI implements AIListener { + + private static final ComponentMapper pm = ComponentMapper.getFor(CPhysics.class); + private static final ComponentMapper cm = ComponentMapper.getFor(CCombat.class); + + @Override + public void react(ArrayList closeEntities, Entity host) { + CPhysics p0 = pm.get(host); + CCombat c0 = cm.get(host); + c0.inputs.put(Direction.UP, false); + c0.inputs.put(Direction.DOWN, false); + c0.inputs.put(Direction.LEFT, false); + c0.inputs.put(Direction.RIGHT, false); + for (Entity other : closeEntities) { + CPhysics p1 = pm.get(other); + + if (p0.getPosition().x + p0.getSize().x / 3 < p1.getPosition().x - p1.getSize().x / 3) { + c0.inputs.put(Direction.RIGHT, true); + } else if (p0.getPosition().x - p0.getSize().x / 3 > p1.getPosition().x + p1.getSize().x / 3) { + c0.inputs.put(Direction.LEFT, true); + } else if (p0.getPosition().y + p0.getSize().y / 3 < p1.getPosition().y - p1.getSize().y / 3) { + c0.inputs.put(Direction.UP, true); + } else if (p0.getPosition().y - p0.getSize().y / 3 > p1.getPosition().y + p1.getSize().y / 3) { + c0.inputs.put(Direction.DOWN, true); + } + } + } + +} diff --git a/core/src/com/saltosion/gladiator/systems/AISystem.java b/core/src/com/saltosion/gladiator/systems/AISystem.java new file mode 100644 index 0000000..1441b93 --- /dev/null +++ b/core/src/com/saltosion/gladiator/systems/AISystem.java @@ -0,0 +1,63 @@ +package com.saltosion.gladiator.systems; + +import com.badlogic.ashley.core.ComponentMapper; +import com.badlogic.ashley.core.Engine; +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.EntitySystem; +import com.badlogic.ashley.core.Family; +import com.badlogic.ashley.utils.ImmutableArray; +import com.saltosion.gladiator.components.CAI; +import com.saltosion.gladiator.components.CCombat; +import com.saltosion.gladiator.components.CPhysics; +import java.util.ArrayList; + +/** + * + * @author Jens "Jeasonfire" Pitkänen + */ +public class AISystem extends EntitySystem { + + private static final ComponentMapper pm = ComponentMapper.getFor(CPhysics.class); + private static final ComponentMapper aim = ComponentMapper.getFor(CAI.class); + private ImmutableArray entities; + + @Override + public void addedToEngine(Engine engine) { + updateEntities(engine); + } + + @Override + public void update(float deltaTime) { + // Loop through all entities that have CCombat + for (int i = 0; i < entities.size(); i++) { + // If current entity doesn't have CAI, skip current entity + if (aim.get(entities.get(i)) == null) { + continue; + } + + CPhysics cp0 = pm.get(entities.get(i)); + CAI cai = aim.get(entities.get(i)); + + // React + ArrayList reactEntities = new ArrayList(); + // Loop through all entities with CCombat + for (int j = 0; j < entities.size(); j++) { + if (i == j) { + continue; + } + CPhysics cp1 = pm.get(entities.get(j)); + float x = cp1.getPosition().x - cp0.getPosition().x; + float y = cp1.getPosition().y - cp0.getPosition().y; + float len = (float) Math.sqrt(x * x + y * y); + if (len <= cai.getReactDistance()) { + reactEntities.add(entities.get(j)); + } + } + cai.getAIListener().react(reactEntities, entities.get(i)); + } + } + + public void updateEntities(Engine engine) { + entities = engine.getEntitiesFor(Family.getFor(CCombat.class)); + } +} diff --git a/core/src/com/saltosion/gladiator/systems/PhysicsSystem.java b/core/src/com/saltosion/gladiator/systems/PhysicsSystem.java index a2f2d0f..2ad7812 100644 --- a/core/src/com/saltosion/gladiator/systems/PhysicsSystem.java +++ b/core/src/com/saltosion/gladiator/systems/PhysicsSystem.java @@ -17,8 +17,9 @@ import com.saltosion.gladiator.util.Direction; public class PhysicsSystem extends EntitySystem { private static final float MAX_VEL = 0.5f; - private ComponentMapper pm = ComponentMapper.getFor(CPhysics.class); - private ComponentMapper cm = ComponentMapper.getFor(CCombat.class); + + private static final ComponentMapper pm = ComponentMapper.getFor(CPhysics.class); + private static final ComponentMapper cm = ComponentMapper.getFor(CCombat.class); private ImmutableArray entities; @Override