Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/#51 make geometryitems clickable #95

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/main/java/com/treasure/hunt/game/GameEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.treasure.hunt.utils.JTSUtils;
import com.treasure.hunt.utils.Requires;
import lombok.Getter;
import lombok.Setter;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Point;

Expand All @@ -25,12 +26,11 @@ public class GameEngine {
@Getter
protected final Hider hider;
protected final Coordinate initialSearcherCoordinate;
DorianRec marked this conversation as resolved.
Show resolved Hide resolved
@Getter
private final Statistic statistics = new Statistic();
/**
* Tells, whether the game is done or not.
*/
@Getter
@Setter
protected boolean finished = false;
/**
* Tells, whether a first move is happened in the game yet, or not.
Expand All @@ -40,6 +40,8 @@ public class GameEngine {
protected SearchPath lastSearchPath;
protected Point searcherPos;
protected Point treasurePos;
@Getter
private final Statistic statistics = new Statistic();

/**
* The constructor.
Expand Down Expand Up @@ -76,7 +78,7 @@ public Turn init() {

treasurePos = hider.getTreasureLocation();
if (treasurePos == null) {
throw new IllegalArgumentException("hider: " + hider + " gave a treasure position which is null.");
throw new IllegalArgumentException(hider + " gave a treasurePosition which is null.");
}

// Check, whether treasure spawns in range of searcher
Expand Down
100 changes: 97 additions & 3 deletions src/main/java/com/treasure/hunt/game/GameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
import com.esotericsoftware.kryo.io.Output;
import com.google.common.annotations.VisibleForTesting;
import com.treasure.hunt.analysis.StatisticObject;
import com.treasure.hunt.jts.geom.Shapeable;
import com.treasure.hunt.strategy.geom.GeometryItem;
import com.treasure.hunt.strategy.geom.GeometryType;
import com.treasure.hunt.strategy.geom.StatusMessageItem;
import com.treasure.hunt.strategy.geom.StatusMessageType;
import com.treasure.hunt.strategy.hider.Hider;
import com.treasure.hunt.strategy.searcher.Searcher;
import com.treasure.hunt.utils.AsyncUtils;
import com.treasure.hunt.utils.JTSUtils;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
Expand All @@ -27,6 +29,7 @@
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import sun.reflect.ReflectionFactory;

Expand All @@ -51,6 +54,10 @@
@Slf4j
public class GameManager implements KryoSerializable, KryoCopyable<GameManager> {

public static final double MOUSE_RECOGNIZE_DISTANCE = 0.2;
private List<GeometryItem<?>> geometryItemsList = new ArrayList<>();
private int geometryItemsListIndex = 0;
private Coordinate lastMouseClick;
/**
* Contains the "gameHistory".
*/
Expand Down Expand Up @@ -83,7 +90,6 @@ public class GameManager implements KryoSerializable, KryoCopyable<GameManager>
@Getter
private ObjectBinding<List<StatusMessageItem>> statusMessageItemsBinding;


/**
* @param searcherClass (Sub-)class of {@link Searcher}
* @param hiderClass (Sub-)class of {@link Hider}
Expand Down Expand Up @@ -190,8 +196,25 @@ public void move(int steps) {
* Works only for stepView &gt; 0
*/
public void previous() {
if (viewIndex.get() > 0) {
viewIndex.set(viewIndex.get() - 1);
int viewIndexSnapshot = viewIndex.get();
if (viewIndexSnapshot > 0) {
for (int i = viewIndexSnapshot; i < turns.size(); i++) {
log.info("" + i + " of " + turns.size());
if (i == 0) {
if (!turns.get(i).getGeometryItems(JTSUtils.createPoint(0, 0)).isEmpty()) {
turns.get(i).getGeometryItems(JTSUtils.createPoint(0, 0)).forEach(geometryItem -> {
geometryItem.setSelected(false);
});
}
} else {
if (!turns.get(i).getGeometryItems(turns.get(i - 1).getSearchPath().getLastPoint()).isEmpty()) {
turns.get(i).getGeometryItems(turns.get(i - 1).getSearchPath().getLastPoint()).forEach(geometryItem -> {
geometryItem.setSelected(false);
});
}
}
}
viewIndex.set(viewIndexSnapshot - 1);
}
DorianRec marked this conversation as resolved.
Show resolved Hide resolved
}

Expand Down Expand Up @@ -384,4 +407,75 @@ public GameManager copy(Kryo kryo) {
gameManager.setBindings();
return gameManager;
}

/**
* @param coordinate the point on the canvas, we want to get the closest {@link GeometryType} to.
* @param distance the maximum distance to a potential {@link GeometryItem}.
* @return a sorted list, containing the nearest {@link GeometryItem}'s to {@code coordinate}, with a maximum distance of {@code distance}.
*/
private List<GeometryItem<?>> pickGeometryItem(Coordinate coordinate, double distance) {
List<GeometryItem<?>> geometryItems = getGeometryItems(true);
if (geometryItems.size() < 1) {
return new ArrayList<>();
}

Point mouse = JTSUtils.GEOMETRY_FACTORY.createPoint(coordinate);

log.info("mouse: " + mouse.getCoordinate());

geometryItems = geometryItems.stream()
.filter(geometryItem -> geometryItem.getObject() instanceof Geometry || geometryItem.getObject() instanceof Shapeable) // TODO also allow non-geometries
.filter(geometryItem ->
{
//log.info(/*"mouse: " + mouse + ", geometryItem: " + geometryItem.getObject() + */
// ", distance: " + mouse.distance((Geometry) geometryItem.getObject()) + " / " + distance);
DorianRec marked this conversation as resolved.
Show resolved Hide resolved
return mouse.distance((Geometry) geometryItem.getObject()) <= distance;
}
)
.filter(geometryItem -> geometryItem.getGeometryStyle().isVisible())
.sorted((geometryItem, secondGeometryItem) ->
(int) (mouse.distance((Geometry) geometryItem.getObject()) -
mouse.distance((Geometry) secondGeometryItem.getObject()))
)
.collect(Collectors.toList());

return geometryItems;
}

public void refreshHighlighter(Coordinate coordinate, double scale) {

double distance = MOUSE_RECOGNIZE_DISTANCE / scale;

// unselect all
for (GeometryItem geometryItem : geometryItemsList) {
geometryItem.setSelected(false);
}

if (lastMouseClick == null) {
lastMouseClick = coordinate;
}

// new mouse coordinate
if (lastMouseClick.getX() != coordinate.getX() ||
lastMouseClick.getY() != coordinate.getY()) {

geometryItemsListIndex = 0;
geometryItemsList = pickGeometryItem(coordinate, distance);

lastMouseClick = coordinate;

if (geometryItemsList.size() < 1) {
return;
}
} else { // same mouse coordinate
if (geometryItemsList.size() < 1) {
return;
}
geometryItemsListIndex = (geometryItemsListIndex + 1) % geometryItemsList.size();
}
geometryItemsList.get(geometryItemsListIndex).setSelected(true);

log.info("received: " + (geometryItemsListIndex + 1) + "/" + geometryItemsList.size());
log.info("selected: " + geometryItemsList.get(geometryItemsListIndex).getObject());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,7 @@ public Shape toShape(Object object) {
if (object instanceof Shapeable) {
return ((Shapeable) object).toShape(this);
}
try {
return super.toShape((Geometry) object);
} catch (IllegalArgumentException e) {
log.debug("Could not render object to shape", e);
}
return null;
return super.toShape((Geometry) object);
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/treasure/hunt/jts/geom/Circle.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
* @see org.locationtech.jts.geom.Geometry
*/
public class Circle extends Polygon {

protected Coordinate coordinate;
protected double radius;

/**
* The constructor
*
Expand All @@ -29,6 +33,8 @@ public Circle(Coordinate coordinate, double radius, int numOfPoints, GeometryFac
geometricShapeFactory.setSize(radius * 2);
Polygon circle = geometricShapeFactory.createCircle();
this.shell = (LinearRing) circle.getExteriorRing();
this.coordinate = coordinate;
this.radius = radius;
}

/**
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/com/treasure/hunt/jts/geom/CircleHighlighter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.treasure.hunt.jts.geom;

import com.treasure.hunt.jts.awt.AdvancedShapeWriter;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;

import java.awt.*;
import java.awt.geom.Ellipse2D;

/**
* Non-scaling {@link Circle}, surrounding points to highlight them.
*
* @author dorianreineccius
*/
public class CircleHighlighter extends Circle implements Shapeable {
public CircleHighlighter(Coordinate coordinate, double radius, int numOfPoints, GeometryFactory geometryFactory) {
super(coordinate, radius, numOfPoints, geometryFactory);
}

@Override
public Shape toShape(AdvancedShapeWriter shapeWriter) {
Point dest = new Point();

shapeWriter.transform(coordinate, dest);

Shape circle = new Ellipse2D.Double(dest.x - radius, dest.y - radius, radius * 2, radius * 2);

return circle;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.treasure.hunt.jts.geom;

import com.treasure.hunt.jts.awt.AdvancedShapeWriter;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;

import java.awt.*;

/**
* @author dorianreineccius
*/
public class RectangleFixedHighlighter extends RectangleVariableHighlighter implements Shapeable {
/**
* Coordinate of the upper left corner.
*/
public final Coordinate coordinate;
/**
* Width of the rectangle.
*/
public final double width;
/**
* Height of the rectangle.
*/
public final double height;

public RectangleFixedHighlighter(Coordinate coordinate, double width, double height, GeometryFactory geometryFactory) {
super(coordinate, width, height, geometryFactory);
Coordinate[] coords = new Coordinate[]{
coordinate,
new Coordinate(coordinate.x + width, coordinate.y),
new Coordinate(coordinate.x + width, coordinate.y - height),
new Coordinate(coordinate.x, coordinate.y - height),
coordinate
};
this.shell = geometryFactory.createLinearRing(coords);
this.coordinate = coordinate;
this.width = width;
this.height = height;
}

@Override
public Shape toShape(AdvancedShapeWriter shapeWriter) {
Point dest = new Point();

shapeWriter.transform(coordinate, dest);

Shape rectangle = new Rectangle.Double((dest.x - width / 2), (dest.y - height / 2), width, height);

return rectangle;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.treasure.hunt.jts.geom;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Polygon;

/**
* @author dorianreineccius
*/
public class RectangleVariableHighlighter extends Polygon {
/**
* Coordinate of the upper left corner.
*/
public final Coordinate coordinate;
/**
* Width of the rectangle.
*/
public final double width;
/**
* Height of the rectangle.
*/
public final double height;

public RectangleVariableHighlighter(Coordinate coordinate, double width, double height, GeometryFactory geometryFactory) {
super(null, null, geometryFactory);
Coordinate[] coords = new Coordinate[]{
coordinate,
new Coordinate(coordinate.x + width, coordinate.y),
new Coordinate(coordinate.x + width, coordinate.y - height),
new Coordinate(coordinate.x, coordinate.y - height),
coordinate
};
this.shell = geometryFactory.createLinearRing(coords);
this.coordinate = coordinate;
this.width = width;
this.height = height;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -24,6 +25,9 @@ public class GeometryItem<T> {
@Getter
private List<GeometryStyle> geometryStyles = new ArrayList<>();
private int preferredStyle = 0;
@Getter
@Setter
private boolean isSelected = false;
DorianRec marked this conversation as resolved.
Show resolved Hide resolved

/**
* The constructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
*/
public enum GeometryType {
// hints
FALSE_HINT(false, "False Hint"),
HINT_ANGLE(true, "angle hint", true),
HINT_CENTER(false, "hint-center"),
HINT_RADIUS(false, "hint-center"),
TRUE_HINT(false, "True Hint"),

// HalfPlaneHint
HALF_PLANE(true, "the treasure is not here", true),
Expand All @@ -26,7 +24,6 @@ public enum GeometryType {
TREASURE_FLAG(true, "treasure flag", true),
NO_TREASURE(false, "no treasure"),
POSSIBLE_TREASURE(false, "possible treasure"),
HINT_ANGLE(true, "angle hint", true),

// searcher movements
WAY_POINT(true, "no treasure"),
Expand All @@ -40,6 +37,8 @@ public enum GeometryType {
CURRENT_RECTANGLE(true, "current rectangle", true),
CURRENT_POLYGON(true, "current polygon", true),

HIGHLIGHTER(true, "highlighter", true),

STANDARD(true, ""),
CURRENT_WAY_POINT(true, "Current way point", true),
GRID(true, "Grid", false);
Expand Down
Loading