Implement simple follow & attack AI for enemies

This commit is contained in:
2022-08-17 19:12:00 +02:00
parent f581805efd
commit 785e1ac524
6 changed files with 83 additions and 2 deletions

Binary file not shown.

View 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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}