From 4d074bee4af263925c4f805c6f06b56da7834d16 Mon Sep 17 00:00:00 2001 From: Jeasonfire Date: Sun, 17 May 2015 21:36:53 +0300 Subject: [PATCH 1/2] Added AI react distance debug rendering. --- .../saltosion/gladiator/level/EntityFactory.java | 12 ++++++++---- .../gladiator/level/premade/Round1Level.java | 2 +- .../gladiator/level/premade/Round2Level.java | 4 ++-- .../gladiator/systems/RenderingSystem.java | 15 +++++++++++++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/core/src/com/saltosion/gladiator/level/EntityFactory.java b/core/src/com/saltosion/gladiator/level/EntityFactory.java index cb16790..ce38029 100644 --- a/core/src/com/saltosion/gladiator/level/EntityFactory.java +++ b/core/src/com/saltosion/gladiator/level/EntityFactory.java @@ -44,11 +44,15 @@ public class EntityFactory { return player; } - public Entity createDummy(Vector2 pos) { - return createDummy(pos, Direction.RIGHT); + public Entity createEnemy(Vector2 pos) { + return createEnemy(pos, Direction.RIGHT); } - public Entity createDummy(Vector2 pos, Direction initialDirection) { + public Entity createEnemy(Vector2 pos, Direction initialDirection) { + return createEnemy(pos, initialDirection, new CAI().setReactDistance(5).setAIListener(new DummyAI())); + } + + public Entity createEnemy(Vector2 pos, Direction initialDirection, CAI cai) { Entity dummy = new Entity(); dummy.flags |= Global.FLAG_ALIVE; @@ -61,7 +65,7 @@ public class EntityFactory { // Combat dummy.add(new CCombat().setBaseDamage(100).setHealth(1000).setSwingCD(.5f) .setCombatListener(new BasicDeathListener())); - dummy.add(new CAI().setReactDistance(5).setAIListener(new DummyAI())); + dummy.add(cai); AppUtil.engine.addEntity(dummy); diff --git a/core/src/com/saltosion/gladiator/level/premade/Round1Level.java b/core/src/com/saltosion/gladiator/level/premade/Round1Level.java index 19ba2f2..0ed9e37 100644 --- a/core/src/com/saltosion/gladiator/level/premade/Round1Level.java +++ b/core/src/com/saltosion/gladiator/level/premade/Round1Level.java @@ -37,7 +37,7 @@ public class Round1Level implements Level { public void generate() { AppUtil.levelFactory.createLevelBase(); player = AppUtil.entityFactory.createPlayer(new Vector2(-10, 2), Direction.RIGHT); - enemies.add(AppUtil.entityFactory.createDummy(new Vector2(10, 2), Direction.LEFT)); + enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(10, 2), Direction.LEFT)); } } diff --git a/core/src/com/saltosion/gladiator/level/premade/Round2Level.java b/core/src/com/saltosion/gladiator/level/premade/Round2Level.java index d05a039..9e95f65 100644 --- a/core/src/com/saltosion/gladiator/level/premade/Round2Level.java +++ b/core/src/com/saltosion/gladiator/level/premade/Round2Level.java @@ -37,8 +37,8 @@ public class Round2Level implements Level { public void generate() { AppUtil.levelFactory.createLevelBase(); player = AppUtil.entityFactory.createPlayer(new Vector2(0, 2), Direction.RIGHT); - enemies.add(AppUtil.entityFactory.createDummy(new Vector2(10, 2), Direction.LEFT)); - enemies.add(AppUtil.entityFactory.createDummy(new Vector2(-10, 2), Direction.RIGHT)); + enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(10, 2), Direction.LEFT)); + enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(-10, 2), Direction.RIGHT)); } } diff --git a/core/src/com/saltosion/gladiator/systems/RenderingSystem.java b/core/src/com/saltosion/gladiator/systems/RenderingSystem.java index 3e78ae2..7bd1b94 100644 --- a/core/src/com/saltosion/gladiator/systems/RenderingSystem.java +++ b/core/src/com/saltosion/gladiator/systems/RenderingSystem.java @@ -18,6 +18,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Vector2; +import com.saltosion.gladiator.components.CAI; import com.saltosion.gladiator.components.CCombat; import com.saltosion.gladiator.components.CParticle; import com.saltosion.gladiator.components.CPhysics; @@ -28,7 +29,6 @@ import com.saltosion.gladiator.gui.nodes.TextNode; import com.saltosion.gladiator.gui.properties.TextProperty; import com.saltosion.gladiator.util.AppUtil; import com.saltosion.gladiator.util.Global; -import com.saltosion.gladiator.util.Log; import com.saltosion.gladiator.util.Name; import com.saltosion.gladiator.util.SpriteLoader; import com.saltosion.gladiator.util.SpriteSequence; @@ -40,6 +40,7 @@ public class RenderingSystem extends EntitySystem { private final ComponentMapper rom = ComponentMapper.getFor(CRenderedObject.class); private final ComponentMapper pm = ComponentMapper.getFor(CPhysics.class); private final ComponentMapper cm = ComponentMapper.getFor(CCombat.class); + private final ComponentMapper aim = ComponentMapper.getFor(CAI.class); private final ComponentMapper pam = ComponentMapper.getFor(CParticle.class); private ImmutableArray entities; @@ -53,7 +54,7 @@ public class RenderingSystem extends EntitySystem { public int screenWidth = 0; private boolean debug = false; - private final Color debugColor = new Color(0, 1, 0, 1); + private final Color debugColor = new Color(0, 1, 0, 1), debugAIColor = new Color(1, 0, 0, 1); private float deltaDelay = 0; private double deltaAvgSum; @@ -326,6 +327,16 @@ public class RenderingSystem extends EntitySystem { debugRenderer.line(x1, y0, x1, y1); debugRenderer.line(x1, y1, x0, y1); debugRenderer.line(x0, y1, x0, y0); + + CAI ai = aim.get(entities.get(i)); + if (ai == null) { + continue; + } + float x = physics.getPosition().x + getCameraOffset(playerPhys, physics).x; + float y = physics.getPosition().y + getCameraOffset(playerPhys, physics).y; + + debugRenderer.setColor(debugAIColor); + debugRenderer.circle(x, y, ai.getReactDistance()); } debugRenderer.end(); } From ea3efb220541aec258c84aaa503168dc59b6265b Mon Sep 17 00:00:00 2001 From: Jeasonfire Date: Sun, 17 May 2015 23:26:03 +0300 Subject: [PATCH 2/2] Added AI's. --- .../gladiator/level/EntityFactory.java | 24 ++++---- .../gladiator/level/premade/Round1Level.java | 5 +- .../gladiator/level/premade/Round2Level.java | 9 ++- .../gladiator/listeners/ai/HunterAI.java | 60 +++++++++++++++++++ .../gladiator/listeners/ai/PanicAI.java | 46 ++++++++++++++ .../gladiator/listeners/ai/ScaredAI.java | 47 +++++++++++++++ .../saltosion/gladiator/systems/AISystem.java | 6 +- 7 files changed, 182 insertions(+), 15 deletions(-) create mode 100644 core/src/com/saltosion/gladiator/listeners/ai/HunterAI.java create mode 100644 core/src/com/saltosion/gladiator/listeners/ai/PanicAI.java create mode 100644 core/src/com/saltosion/gladiator/listeners/ai/ScaredAI.java diff --git a/core/src/com/saltosion/gladiator/level/EntityFactory.java b/core/src/com/saltosion/gladiator/level/EntityFactory.java index ce38029..0d994b2 100644 --- a/core/src/com/saltosion/gladiator/level/EntityFactory.java +++ b/core/src/com/saltosion/gladiator/level/EntityFactory.java @@ -32,7 +32,8 @@ public class EntityFactory { player.add(createPlayerRenderedObject()); // Physics - player.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y).setDirection(initialDirection)); + player.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y) + .setDirection(initialDirection).setMoveSpeed(15f)); // Combat player.add(new CCombat().setBaseDamage(100).setHealth(1000) @@ -53,23 +54,24 @@ public class EntityFactory { } public Entity createEnemy(Vector2 pos, Direction initialDirection, CAI cai) { - Entity dummy = new Entity(); - dummy.flags |= Global.FLAG_ALIVE; + Entity enemy = new Entity(); + enemy.flags |= Global.FLAG_ALIVE; // Graphics - dummy.add(createPlayerRenderedObject()); + enemy.add(createPlayerRenderedObject()); // Physics - dummy.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y).setDirection(initialDirection)); + enemy.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y) + .setDirection(initialDirection).setMoveSpeed(14f)); // Combat - dummy.add(new CCombat().setBaseDamage(100).setHealth(1000).setSwingCD(.5f) + enemy.add(new CCombat().setBaseDamage(100).setHealth(1000).setSwingCD(.5f) .setCombatListener(new BasicDeathListener())); - dummy.add(cai); + enemy.add(cai); - AppUtil.engine.addEntity(dummy); + AppUtil.engine.addEntity(enemy); - return dummy; + return enemy; } private CRenderedObject createPlayerRenderedObject() { @@ -91,11 +93,11 @@ public class EntityFactory { renderedObject.addChannel("torso"); // Idle animations - SpriteSequence torsoIdleRightSequence = new SpriteSequence(IDLE_ANIMATION_SPEED).addSprite(playerSprites[0][1][0]); + SpriteSequence torsoIdleRightSequence = new SpriteSequence(IDLE_ANIMATION_SPEED).addSprite(playerSprites[0][0][0]).addSprite(playerSprites[0][1][0]); renderedObject.addSequence("Torso-Idle-Right", torsoIdleRightSequence); SpriteSequence legsIdleRightSquence = new SpriteSequence(IDLE_ANIMATION_SPEED).addSprite(playerSprites[1][0][0]).addSprite(playerSprites[1][1][0]); renderedObject.addSequence("Legs-Idle-Right", legsIdleRightSquence); - SpriteSequence torsoIdleLeftSequence = new SpriteSequence(IDLE_ANIMATION_SPEED).addSprite(playerSprites[0][1][1]); + SpriteSequence torsoIdleLeftSequence = new SpriteSequence(IDLE_ANIMATION_SPEED).addSprite(playerSprites[0][0][1]).addSprite(playerSprites[0][1][1]); renderedObject.addSequence("Torso-Idle-Left", torsoIdleLeftSequence); SpriteSequence legsIdleLeftSquence = new SpriteSequence(IDLE_ANIMATION_SPEED).addSprite(playerSprites[1][0][1]).addSprite(playerSprites[1][1][1]); renderedObject.addSequence("Legs-Idle-Left", legsIdleLeftSquence); diff --git a/core/src/com/saltosion/gladiator/level/premade/Round1Level.java b/core/src/com/saltosion/gladiator/level/premade/Round1Level.java index 0ed9e37..bd3f86a 100644 --- a/core/src/com/saltosion/gladiator/level/premade/Round1Level.java +++ b/core/src/com/saltosion/gladiator/level/premade/Round1Level.java @@ -2,7 +2,9 @@ package com.saltosion.gladiator.level.premade; import com.badlogic.ashley.core.Entity; import com.badlogic.gdx.math.Vector2; +import com.saltosion.gladiator.components.CAI; import com.saltosion.gladiator.level.Level; +import com.saltosion.gladiator.listeners.ai.PanicAI; import com.saltosion.gladiator.util.AppUtil; import com.saltosion.gladiator.util.Direction; import com.saltosion.gladiator.util.Global; @@ -37,7 +39,8 @@ public class Round1Level implements Level { public void generate() { AppUtil.levelFactory.createLevelBase(); player = AppUtil.entityFactory.createPlayer(new Vector2(-10, 2), Direction.RIGHT); - enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(10, 2), Direction.LEFT)); + enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(10, 2), Direction.LEFT, + new CAI().setReactDistance(12f).setAIListener(new PanicAI()))); } } diff --git a/core/src/com/saltosion/gladiator/level/premade/Round2Level.java b/core/src/com/saltosion/gladiator/level/premade/Round2Level.java index 9e95f65..fe2d5c2 100644 --- a/core/src/com/saltosion/gladiator/level/premade/Round2Level.java +++ b/core/src/com/saltosion/gladiator/level/premade/Round2Level.java @@ -2,7 +2,10 @@ package com.saltosion.gladiator.level.premade; import com.badlogic.ashley.core.Entity; import com.badlogic.gdx.math.Vector2; +import com.saltosion.gladiator.components.CAI; import com.saltosion.gladiator.level.Level; +import com.saltosion.gladiator.listeners.ai.HunterAI; +import com.saltosion.gladiator.listeners.ai.ScaredAI; import com.saltosion.gladiator.util.AppUtil; import com.saltosion.gladiator.util.Direction; import com.saltosion.gladiator.util.Global; @@ -37,8 +40,10 @@ public class Round2Level implements Level { public void generate() { AppUtil.levelFactory.createLevelBase(); player = AppUtil.entityFactory.createPlayer(new Vector2(0, 2), Direction.RIGHT); - enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(10, 2), Direction.LEFT)); - enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(-10, 2), Direction.RIGHT)); + enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(10, 2), Direction.LEFT, + new CAI().setReactDistance(10f).setAIListener(new ScaredAI()))); + enemies.add(AppUtil.entityFactory.createEnemy(new Vector2(-10, 2), Direction.RIGHT, + new CAI().setReactDistance(10f).setAIListener(new HunterAI()))); } } diff --git a/core/src/com/saltosion/gladiator/listeners/ai/HunterAI.java b/core/src/com/saltosion/gladiator/listeners/ai/HunterAI.java new file mode 100644 index 0000000..d8a99dd --- /dev/null +++ b/core/src/com/saltosion/gladiator/listeners/ai/HunterAI.java @@ -0,0 +1,60 @@ +package com.saltosion.gladiator.listeners.ai; + +import com.badlogic.ashley.core.ComponentMapper; +import com.badlogic.ashley.core.Entity; +import com.badlogic.gdx.Gdx; +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; + +public class HunterAI implements AIListener { + + private static final ComponentMapper pm = ComponentMapper.getFor(CPhysics.class); + private static final ComponentMapper cm = ComponentMapper.getFor(CCombat.class); + + private float lastRush = 0; + private final float rushInterval; + + public HunterAI() { + this.rushInterval = 1f; + } + + public HunterAI(float rushInterval) { + this.rushInterval = rushInterval; + } + + @Override + public void react(ArrayList closeEntities, Entity host) { + lastRush += Gdx.graphics.getDeltaTime(); + if (lastRush > rushInterval) { + lastRush = 0; + } else { + return; + } + + CCombat c0 = cm.get(host); + CPhysics p0 = pm.get(host); + + p0.movingLeft = false; + p0.movingRight = false; + 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) { + p0.movingRight = true; + c0.inputs.put(Direction.RIGHT, true); + } else if (p0.getPosition().x - p0.getSize().x / 3 > p1.getPosition().x + p1.getSize().x / 3) { + p0.movingLeft = true; + c0.inputs.put(Direction.LEFT, true); + } + } + } + +} diff --git a/core/src/com/saltosion/gladiator/listeners/ai/PanicAI.java b/core/src/com/saltosion/gladiator/listeners/ai/PanicAI.java new file mode 100644 index 0000000..47ae9c5 --- /dev/null +++ b/core/src/com/saltosion/gladiator/listeners/ai/PanicAI.java @@ -0,0 +1,46 @@ +package com.saltosion.gladiator.listeners.ai; + +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; + +public class PanicAI implements AIListener { + + @Override + public void react(ArrayList closeEntities, Entity host) { + CPhysics po = host.getComponent(CPhysics.class); + CCombat co = host.getComponent(CCombat.class); + co.inputs.put(Direction.UP, false); + co.inputs.put(Direction.DOWN, false); + co.inputs.put(Direction.RIGHT, false); + co.inputs.put(Direction.LEFT, false); + if (closeEntities.isEmpty()) { + po.jumping = false; + return; + } + + if (po.isGrounded()) { + po.jumping = true; + } + + switch ((int) Math.ceil(Math.random() * 4)) { + default: + case 1: + co.inputs.put(Direction.LEFT, true); + break; + case 2: + co.inputs.put(Direction.RIGHT, true); + break; + case 3: + co.inputs.put(Direction.DOWN, true); + break; + case 4: + co.inputs.put(Direction.UP, true); + break; + } + } + +} diff --git a/core/src/com/saltosion/gladiator/listeners/ai/ScaredAI.java b/core/src/com/saltosion/gladiator/listeners/ai/ScaredAI.java new file mode 100644 index 0000000..4f52575 --- /dev/null +++ b/core/src/com/saltosion/gladiator/listeners/ai/ScaredAI.java @@ -0,0 +1,47 @@ +package com.saltosion.gladiator.listeners.ai; + +import com.badlogic.ashley.core.ComponentMapper; +import com.badlogic.ashley.core.Entity; +import com.badlogic.gdx.Gdx; +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; + +public class ScaredAI 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) { + CCombat c0 = cm.get(host); + CPhysics p0 = pm.get(host); + + p0.movingLeft = false; + p0.movingRight = false; + c0.inputs.put(Direction.UP, false); + c0.inputs.put(Direction.DOWN, false); + c0.inputs.put(Direction.LEFT, false); + c0.inputs.put(Direction.RIGHT, false); + + Direction dir = Direction.DOWN; + if (Math.random() < 0.5) { + dir = Direction.UP; + } + if (Math.random() < 2 * Gdx.graphics.getDeltaTime()) { + c0.inputs.put(dir, true); + } + for (Entity other : closeEntities) { + CPhysics p1 = pm.get(other); + + if (p0.getPosition().x + p0.getSize().x / 3 < p1.getPosition().x - p1.getSize().x / 3) { + p0.movingLeft = true; + } else if (p0.getPosition().x - p0.getSize().x / 3 > p1.getPosition().x + p1.getSize().x / 3) { + p0.movingRight = true; + } + } + } + +} diff --git a/core/src/com/saltosion/gladiator/systems/AISystem.java b/core/src/com/saltosion/gladiator/systems/AISystem.java index 8cab3d7..4bc046f 100644 --- a/core/src/com/saltosion/gladiator/systems/AISystem.java +++ b/core/src/com/saltosion/gladiator/systems/AISystem.java @@ -9,6 +9,7 @@ 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 com.saltosion.gladiator.listeners.AIListener; import java.util.ArrayList; public class AISystem extends EntitySystem { @@ -49,7 +50,10 @@ public class AISystem extends EntitySystem { reactEntities.add(entities.get(j)); } } - cai.getAIListener().react(reactEntities, entities.get(i)); + AIListener listener = cai.getAIListener(); + if (listener != null) { + listener.react(reactEntities, entities.get(i)); + } } }