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).
This commit is contained in:
@@ -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<Animation> UP = new Path<Animation>().move(Direction.UP);
|
||||
private static final Path<Animation> DOWN = new Path<Animation>().move(Direction.DOWN);
|
||||
private static final Path<Animation> LEFT = new Path<Animation>().move(Direction.LEFT);
|
||||
private static final Path<Animation> RIGHT = new Path<Animation>().move(Direction.RIGHT);
|
||||
private static final Path<Animation> UP = new BasePath<Animation>().move(Direction.UP);
|
||||
private static final Path<Animation> DOWN = new BasePath<Animation>().move(Direction.DOWN);
|
||||
private static final Path<Animation> LEFT = new BasePath<Animation>().move(Direction.LEFT);
|
||||
private static final Path<Animation> RIGHT = new BasePath<Animation>().move(Direction.RIGHT);
|
||||
|
||||
private final String animationUid;
|
||||
|
||||
|
||||
@@ -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<T extends Movable> implements Path<T> {
|
||||
|
||||
@Getter
|
||||
private final List<PathSegment<T>> path = new ArrayList<>();
|
||||
|
||||
public Path<T> add(PathSegment<T> segment) {
|
||||
path.add(segment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> addFirst(PathSegment<T> segment) {
|
||||
path.add(0, segment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> move(Direction direction) {
|
||||
path.add(new MoveSegment<>(direction));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> move(Direction direction, boolean ignore) {
|
||||
path.add(new MoveSegment<>(direction, ignore));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> wait(float seconds) {
|
||||
path.add(new WaitSegment<>(seconds));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> run(Runnable runnable) {
|
||||
path.add(new RunSegment<>(runnable));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -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<T extends Movable> implements Path<T> {
|
||||
private final List<PositionableMoveSegment<T>> path = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public List<? extends PathSegment<T>> getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public MovementPath<T> add(Direction direction, int x, int y) {
|
||||
path.add(new PositionableMoveSegment<>(direction, x, y));
|
||||
return this;
|
||||
}
|
||||
|
||||
public MovementPath<T> 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<T extends Movable> extends MoveSegment<T> {
|
||||
final int x;
|
||||
final int y;
|
||||
|
||||
PositionableMoveSegment(Direction direction, int x, int y) {
|
||||
super(direction);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<NPC> {
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public NPCPath turn(Direction direction) {
|
||||
public class NPCPath<T extends NPC> implements Path<T> {
|
||||
|
||||
@Getter
|
||||
private final List<PathSegment<T>> path = new ArrayList<>();
|
||||
|
||||
public NPCPath<T> add(PathSegment<T> segment) {
|
||||
path.add(segment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NPCPath<T> addFirst(PathSegment<T> segment) {
|
||||
path.add(0, segment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NPCPath<T> move(Direction direction) {
|
||||
path.add(new MoveSegment<>(direction));
|
||||
return this;
|
||||
}
|
||||
|
||||
public NPCPath<T> move(Direction direction, boolean ignore) {
|
||||
path.add(new MoveSegment<>(direction, ignore));
|
||||
return this;
|
||||
}
|
||||
|
||||
public NPCPath<T> turn(Direction direction) {
|
||||
path.add(new TurnSegment<>(direction));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPCPath add(PathSegment<NPC> segment) {
|
||||
super.add(segment);
|
||||
public NPCPath<T> wait(float seconds) {
|
||||
path.add(new WaitSegment<>(seconds));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPCPath addFirst(PathSegment<NPC> 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<T> run(Runnable runnable) {
|
||||
path.add(new RunSegment<>(runnable));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T extends Movable> {
|
||||
protected final List<PathSegment<T>> path = new ArrayList<>();
|
||||
|
||||
public List<PathSegment<T>> getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public Path<T> add(PathSegment<T> segment) {
|
||||
path.add(segment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> addFirst(PathSegment<T> segment) {
|
||||
path.add(0, segment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> move(Direction direction) {
|
||||
path.add(new MoveSegment<>(direction));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> move(Direction direction, boolean ignore) {
|
||||
path.add(new MoveSegment<>(direction, ignore));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> wait(float seconds) {
|
||||
path.add(new WaitSegment<>(seconds));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path<T> run(Runnable runnable) {
|
||||
path.add(new RunSegment<>(runnable));
|
||||
return this;
|
||||
}
|
||||
public interface Path<T extends Movable> {
|
||||
List<? extends PathSegment<T>> getPath();
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import static java.util.Collections.emptyList;
|
||||
public class PathExecutor<T extends Movable> {
|
||||
private final T movable;
|
||||
|
||||
private List<PathSegment<T>> path = emptyList();
|
||||
private List<? extends PathSegment<T>> path = emptyList();
|
||||
private Integer repeat;
|
||||
|
||||
private int current = 0;
|
||||
|
||||
@@ -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 <T extends Movable> Path<T> findPath(ObjectLayer layer, T start, Vector2ic end) {
|
||||
public <T extends Movable> MovementPath<T> findPath(ObjectLayer layer, T start, Vector2ic end) {
|
||||
return astar(layer, start.getCoordinates(), end, this::recreatePath);
|
||||
}
|
||||
|
||||
private <T extends Movable> Path<T> recreatePath(Node node) {
|
||||
private <T extends Movable> MovementPath<T> recreatePath(Node node) {
|
||||
if (node == null) {
|
||||
return new Path<>();
|
||||
return new MovementPath<>();
|
||||
}
|
||||
|
||||
var path = new Path<T>();
|
||||
var path = new MovementPath<T>();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
<T extends Movable> Path<T> findPath(ObjectLayer layer, T start, Vector2ic end);
|
||||
<T extends Movable> MovementPath<T> findPath(ObjectLayer layer, T start, Vector2ic end);
|
||||
|
||||
LinkedList<Vector2ic> findSequence(ObjectLayer layer, Vector2ic start, Vector2ic end);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user