Implement simple follow & attack AI for enemies
This commit is contained in:
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
Binary file not shown.
43
src/main/java/com/bartlomiejpluta/demo/ai/SimpleEnemyAI.java
Normal file
43
src/main/java/com/bartlomiejpluta/demo/ai/SimpleEnemyAI.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.bartlomiejpluta.demo.ai;
|
||||
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
|
||||
import com.bartlomiejpluta.base.util.pathfinder.*;
|
||||
import com.bartlomiejpluta.base.api.ai.*;
|
||||
import com.bartlomiejpluta.base.lib.ai.*;
|
||||
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.entity.Character;
|
||||
|
||||
public class SimpleEnemyAI extends FollowEntityAI<Enemy, Character> {
|
||||
private static final int ASTAR_MAX_NODES = 100;
|
||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||
private final AI idle;
|
||||
private final int range;
|
||||
|
||||
public SimpleEnemyAI(Enemy enemy, Character target, int range) {
|
||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target);
|
||||
this.range = range;
|
||||
this.idle = new RandomMovementAI(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean sees(Enemy enemy, Character target, ObjectLayer layer, int distance) {
|
||||
return distance < range;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void interact(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
||||
enemy.attack();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void follow(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void idle(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
||||
idle.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,21 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.ai.NPC;
|
||||
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
||||
|
||||
import com.bartlomiejpluta.base.lib.ai.NoopAI;
|
||||
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.database.model.EnemyModel;
|
||||
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||
import com.bartlomiejpluta.demo.ai.*;
|
||||
|
||||
|
||||
public class Enemy extends Character implements NPC {
|
||||
private final EnemyModel template;
|
||||
@@ -41,10 +45,23 @@ public class Enemy extends Character implements NPC {
|
||||
setZIndex(-1);
|
||||
|
||||
ai = NoopAI.INSTANCE;
|
||||
|
||||
getLayer().handleEvent(new EnemyDiedEvent(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return template.getName() + "@" + hashCode();
|
||||
}
|
||||
|
||||
public Enemy followAndAttack(Character target, int range) {
|
||||
var ai = new SimpleEnemyAI(this, target, range);
|
||||
|
||||
addEventListener(MoveEvent.TYPE, e -> ai.recomputePath());
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
|
||||
this.ai = ai;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.bartlomiejpluta.demo.event;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import com.bartlomiejpluta.base.api.event.*;
|
||||
import com.bartlomiejpluta.base.lib.event.*;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class EnemyDiedEvent extends BaseEvent {
|
||||
public static final EventType<EnemyDiedEvent> TYPE = new EventType<>("ENEMY_DIED_EVENT");
|
||||
|
||||
private final Enemy enemy;
|
||||
|
||||
@Override
|
||||
public EventType<EnemyDiedEvent> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
@@ -75,9 +75,10 @@ public abstract class BaseMapHandler implements MapHandler {
|
||||
cameraController.update();
|
||||
}
|
||||
|
||||
public void enemy(int x, int y, @NonNull String id) {
|
||||
public Enemy enemy(int x, int y, @NonNull String id) {
|
||||
var enemy = new Enemy(context, runner.getEnemyDAO().get(id));
|
||||
enemy.setCoordinates(x, y);
|
||||
mainLayer.addEntity(enemy);
|
||||
return enemy;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user