From 8c7522e1d3845ab1661a58edb5842a26d8d85699 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Tue, 25 Feb 2020 12:11:58 +0100 Subject: [PATCH] Path finding --- .../leveleditor/api/editor/RawMap.java | 11 +++++ .../java/fr/ynerant/leveleditor/game/Mob.java | 47 +++++++++++++++---- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/main/java/fr/ynerant/leveleditor/api/editor/RawMap.java b/src/main/java/fr/ynerant/leveleditor/api/editor/RawMap.java index 6cfe48d..10af484 100644 --- a/src/main/java/fr/ynerant/leveleditor/api/editor/RawMap.java +++ b/src/main/java/fr/ynerant/leveleditor/api/editor/RawMap.java @@ -4,8 +4,10 @@ import fr.ynerant.leveleditor.editor.Map; import java.awt.image.BufferedImage; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.stream.Collectors; public class RawMap { private List cases; @@ -48,6 +50,15 @@ public class RawMap { return cases_map.get(y * getWidth() + x); } + public Collection getNeighbours(RawCase c) { + List list = new ArrayList<>(); + list.add(getCase(c.getPosX() - 1, c.getPosY())); + list.add(getCase(c.getPosX(), c.getPosY() - 1)); + list.add(getCase(c.getPosX() + 1, c.getPosY())); + list.add(getCase(c.getPosX(), c.getPosY() + 1)); + return list.stream().filter(_c -> _c != null && _c.getCollision() == Collision.ANY).collect(Collectors.toList()); + } + public int getWidth() { return width; } diff --git a/src/main/java/fr/ynerant/leveleditor/game/Mob.java b/src/main/java/fr/ynerant/leveleditor/game/Mob.java index 187f279..4f143af 100644 --- a/src/main/java/fr/ynerant/leveleditor/game/Mob.java +++ b/src/main/java/fr/ynerant/leveleditor/game/Mob.java @@ -5,7 +5,7 @@ import fr.ynerant.leveleditor.api.editor.RawCase; import fr.ynerant.leveleditor.api.editor.sprites.Sprite; import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister; -import java.util.Random; +import java.util.*; public abstract class Mob { private static final Random RANDOM = new Random(); @@ -73,13 +73,44 @@ public abstract class Mob { --tickRemains; else { tickRemains = getSlowness(); - RawCase c = game.getMap().getCase(getX(), getY()); - RawCase other = game.getMap().getCase(getX() - 1, getY()); - if (other == null || other.getCollision() == Collision.ANY) { - c.setCollision(Collision.ANY); - if (other != null) - other.setCollision(Collision.PARTIAL); - move(getX() - 1, getY()); + RawCase current = game.getMap().getCase(getX(), getY()); + current.setCollision(Collision.ANY); + + if (current.getPosX() == 0) { + move(-1, getY()); + return; + } + + List visited = new ArrayList<>(); + Queue queue = new ArrayDeque<>(); + Map pred = new HashMap<>(); + RawCase last = null; + queue.add(current); + while (!queue.isEmpty()) { + RawCase visiting = queue.poll(); + visited.add(visiting); + for (RawCase neighbour : game.getMap().getNeighbours(visiting)) { + if (visited.contains(neighbour)) + continue; + + pred.put(neighbour, visiting); + queue.add(neighbour); + + if (neighbour.getPosX() == 0) { + last = neighbour; + queue.clear(); + break; + } + } + + if (last == null) { + current.setCollision(Collision.PARTIAL); + } + else { + while (pred.get(last) != current) + last = pred.get(last); + move(last.getPosX(), last.getPosY()); + } } } }