From a11773e60c1dd95070b033157f1a2d29e257c5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Sun, 4 Apr 2021 23:55:14 +0200 Subject: [PATCH] Transform Path class to interface This is necessary to introduce a MovementPath, which is a special Path implementation that contains only non-ignore MoveSegments specialized to include also a target coordinates. Thanks to that, the PathFinder can create a path with consecutive directions as well as the coordinates that can be iterated in order to find, if no other Entity is blocking the path (`contains()` method in MovementPath). --- .../lib/animation/BulletAnimationRunner.java | 9 +-- .../base/util/path/BasePath.java | 44 +++++++++++++ .../base/util/path/MovementPath.java | 47 ++++++++++++++ .../base/util/path/NPCPath.java | 65 ++++++++++--------- .../bartlomiejpluta/base/util/path/Path.java | 40 +----------- .../base/util/path/PathExecutor.java | 2 +- .../base/util/pathfinder/AstarPathFinder.java | 23 ++++--- .../base/util/pathfinder/PathFinder.java | 4 +- 8 files changed, 147 insertions(+), 87 deletions(-) create mode 100644 api/src/main/java/com/bartlomiejpluta/base/util/path/BasePath.java create mode 100644 api/src/main/java/com/bartlomiejpluta/base/util/path/MovementPath.java diff --git a/api/src/main/java/com/bartlomiejpluta/base/lib/animation/BulletAnimationRunner.java b/api/src/main/java/com/bartlomiejpluta/base/lib/animation/BulletAnimationRunner.java index c91bf40f..2783491a 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/lib/animation/BulletAnimationRunner.java +++ b/api/src/main/java/com/bartlomiejpluta/base/lib/animation/BulletAnimationRunner.java @@ -7,6 +7,7 @@ import com.bartlomiejpluta.base.api.map.layer.base.Layer; import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.api.move.Direction; import com.bartlomiejpluta.base.api.move.Movable; +import com.bartlomiejpluta.base.util.path.BasePath; import com.bartlomiejpluta.base.util.path.Path; import org.joml.Vector2fc; import org.joml.Vector2i; @@ -16,10 +17,10 @@ import java.util.function.Consumer; import static java.util.Objects.requireNonNull; public class BulletAnimationRunner implements AnimationRunner { - private static final Path UP = new Path().move(Direction.UP); - private static final Path DOWN = new Path().move(Direction.DOWN); - private static final Path LEFT = new Path().move(Direction.LEFT); - private static final Path RIGHT = new Path().move(Direction.RIGHT); + private static final Path UP = new BasePath().move(Direction.UP); + private static final Path DOWN = new BasePath().move(Direction.DOWN); + private static final Path LEFT = new BasePath().move(Direction.LEFT); + private static final Path RIGHT = new BasePath().move(Direction.RIGHT); private final String animationUid; diff --git a/api/src/main/java/com/bartlomiejpluta/base/util/path/BasePath.java b/api/src/main/java/com/bartlomiejpluta/base/util/path/BasePath.java new file mode 100644 index 00000000..7bc3c987 --- /dev/null +++ b/api/src/main/java/com/bartlomiejpluta/base/util/path/BasePath.java @@ -0,0 +1,44 @@ +package com.bartlomiejpluta.base.util.path; + +import com.bartlomiejpluta.base.api.move.Direction; +import com.bartlomiejpluta.base.api.move.Movable; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +public class BasePath implements Path { + + @Getter + private final List> path = new ArrayList<>(); + + public Path add(PathSegment segment) { + path.add(segment); + return this; + } + + public Path addFirst(PathSegment segment) { + path.add(0, segment); + return this; + } + + public Path move(Direction direction) { + path.add(new MoveSegment<>(direction)); + return this; + } + + public Path move(Direction direction, boolean ignore) { + path.add(new MoveSegment<>(direction, ignore)); + return this; + } + + public Path wait(float seconds) { + path.add(new WaitSegment<>(seconds)); + return this; + } + + public Path run(Runnable runnable) { + path.add(new RunSegment<>(runnable)); + return this; + } +} diff --git a/api/src/main/java/com/bartlomiejpluta/base/util/path/MovementPath.java b/api/src/main/java/com/bartlomiejpluta/base/util/path/MovementPath.java new file mode 100644 index 00000000..35d210e2 --- /dev/null +++ b/api/src/main/java/com/bartlomiejpluta/base/util/path/MovementPath.java @@ -0,0 +1,47 @@ +package com.bartlomiejpluta.base.util.path; + +import com.bartlomiejpluta.base.api.move.Direction; +import com.bartlomiejpluta.base.api.move.Movable; + +import java.util.ArrayList; +import java.util.List; + +public class MovementPath implements Path { + private final List> path = new ArrayList<>(); + + @Override + public List> getPath() { + return path; + } + + public MovementPath add(Direction direction, int x, int y) { + path.add(new PositionableMoveSegment<>(direction, x, y)); + return this; + } + + public MovementPath addFirst(Direction direction, int x, int y) { + path.add(0, new PositionableMoveSegment<>(direction, x, y)); + return this; + } + + public boolean contains(int x, int y) { + for (var segment : path) { + if (segment.x == x && segment.y == y) { + return true; + } + } + + return false; + } + + private static class PositionableMoveSegment extends MoveSegment { + final int x; + final int y; + + PositionableMoveSegment(Direction direction, int x, int y) { + super(direction); + this.x = x; + this.y = y; + } + } +} diff --git a/api/src/main/java/com/bartlomiejpluta/base/util/path/NPCPath.java b/api/src/main/java/com/bartlomiejpluta/base/util/path/NPCPath.java index 6722ad6c..2a7560f0 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/util/path/NPCPath.java +++ b/api/src/main/java/com/bartlomiejpluta/base/util/path/NPCPath.java @@ -2,47 +2,48 @@ package com.bartlomiejpluta.base.util.path; import com.bartlomiejpluta.base.api.ai.NPC; import com.bartlomiejpluta.base.api.move.Direction; +import lombok.Getter; -public class NPCPath extends Path { +import java.util.ArrayList; +import java.util.List; - public NPCPath turn(Direction direction) { +public class NPCPath implements Path { + + @Getter + private final List> path = new ArrayList<>(); + + public NPCPath add(PathSegment segment) { + path.add(segment); + return this; + } + + public NPCPath addFirst(PathSegment segment) { + path.add(0, segment); + return this; + } + + public NPCPath move(Direction direction) { + path.add(new MoveSegment<>(direction)); + return this; + } + + public NPCPath move(Direction direction, boolean ignore) { + path.add(new MoveSegment<>(direction, ignore)); + return this; + } + + public NPCPath turn(Direction direction) { path.add(new TurnSegment<>(direction)); return this; } - @Override - public NPCPath add(PathSegment segment) { - super.add(segment); + public NPCPath wait(float seconds) { + path.add(new WaitSegment<>(seconds)); return this; } - @Override - public NPCPath addFirst(PathSegment segment) { - super.addFirst(segment); - return this; - } - - @Override - public NPCPath move(Direction direction) { - super.move(direction); - return this; - } - - @Override - public NPCPath move(Direction direction, boolean ignore) { - super.move(direction, ignore); - return this; - } - - @Override - public NPCPath wait(float seconds) { - super.wait(seconds); - return this; - } - - @Override - public NPCPath run(Runnable runnable) { - super.run(runnable); + public NPCPath run(Runnable runnable) { + path.add(new RunSegment<>(runnable)); return this; } } diff --git a/api/src/main/java/com/bartlomiejpluta/base/util/path/Path.java b/api/src/main/java/com/bartlomiejpluta/base/util/path/Path.java index a24dbe5e..15a31740 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/util/path/Path.java +++ b/api/src/main/java/com/bartlomiejpluta/base/util/path/Path.java @@ -1,45 +1,9 @@ package com.bartlomiejpluta.base.util.path; -import com.bartlomiejpluta.base.api.move.Direction; import com.bartlomiejpluta.base.api.move.Movable; -import java.util.ArrayList; import java.util.List; -public class Path { - protected final List> path = new ArrayList<>(); - - public List> getPath() { - return path; - } - - public Path add(PathSegment segment) { - path.add(segment); - return this; - } - - public Path addFirst(PathSegment segment) { - path.add(0, segment); - return this; - } - - public Path move(Direction direction) { - path.add(new MoveSegment<>(direction)); - return this; - } - - public Path move(Direction direction, boolean ignore) { - path.add(new MoveSegment<>(direction, ignore)); - return this; - } - - public Path wait(float seconds) { - path.add(new WaitSegment<>(seconds)); - return this; - } - - public Path run(Runnable runnable) { - path.add(new RunSegment<>(runnable)); - return this; - } +public interface Path { + List> getPath(); } diff --git a/api/src/main/java/com/bartlomiejpluta/base/util/path/PathExecutor.java b/api/src/main/java/com/bartlomiejpluta/base/util/path/PathExecutor.java index df7d83a1..5d3e9ef1 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/util/path/PathExecutor.java +++ b/api/src/main/java/com/bartlomiejpluta/base/util/path/PathExecutor.java @@ -10,7 +10,7 @@ import static java.util.Collections.emptyList; public class PathExecutor { private final T movable; - private List> path = emptyList(); + private List> path = emptyList(); private Integer repeat; private int current = 0; diff --git a/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/AstarPathFinder.java b/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/AstarPathFinder.java index ba8f201c..2b4fbd24 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/AstarPathFinder.java +++ b/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/AstarPathFinder.java @@ -3,8 +3,7 @@ package com.bartlomiejpluta.base.util.pathfinder; import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.api.move.Direction; import com.bartlomiejpluta.base.api.move.Movable; -import com.bartlomiejpluta.base.util.path.MoveSegment; -import com.bartlomiejpluta.base.util.path.Path; +import com.bartlomiejpluta.base.util.path.MovementPath; import org.joml.Vector2i; import org.joml.Vector2ic; @@ -43,23 +42,27 @@ public class AstarPathFinder implements PathFinder { } @Override - public Path findPath(ObjectLayer layer, T start, Vector2ic end) { + public MovementPath findPath(ObjectLayer layer, T start, Vector2ic end) { return astar(layer, start.getCoordinates(), end, this::recreatePath); } - private Path recreatePath(Node node) { + private MovementPath recreatePath(Node node) { if (node == null) { - return new Path<>(); + return new MovementPath<>(); } - var path = new Path(); + var path = new MovementPath(); var current = node; while (current.parent != null) { - path.addFirst(new MoveSegment<>(Direction.ofVector( - current.position.x() - current.parent.position.x(), - current.position.y() - current.parent.position.y() - ))); + var currentX = current.position.x(); + var currentY = current.position.y(); + + path.addFirst(Direction.ofVector( + currentX - current.parent.position.x(), + currentY - current.parent.position.y() + ), currentX, currentY); + current = current.parent; } diff --git a/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/PathFinder.java b/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/PathFinder.java index 99c8f623..0e8e8e5a 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/PathFinder.java +++ b/api/src/main/java/com/bartlomiejpluta/base/util/pathfinder/PathFinder.java @@ -2,13 +2,13 @@ package com.bartlomiejpluta.base.util.pathfinder; import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.api.move.Movable; -import com.bartlomiejpluta.base.util.path.Path; +import com.bartlomiejpluta.base.util.path.MovementPath; import org.joml.Vector2ic; import java.util.LinkedList; public interface PathFinder { - Path findPath(ObjectLayer layer, T start, Vector2ic end); + MovementPath findPath(ObjectLayer layer, T start, Vector2ic end); LinkedList findSequence(ObjectLayer layer, Vector2ic start, Vector2ic end); }