@@ 33,6 33,7 @@ import net.dermetfan.utils.libgdx.scene2
* @author dermetfan */
public class JigsawPuzzle {
+ /** the {@link Piece pieces} of the puzzle */
private final Array<Piece> pieces;
public JigsawPuzzle() {
@@ 67,6 68,12 @@ public class JigsawPuzzle {
pieces.add(piece);
}
+ /** @param piece the piece to remove from {@link #pieces}
+ * @return if the piece was found and removed */
+ public boolean remove(Piece piece) {
+ return pieces.removeValue(piece, true);
+ }
+
/** @param piece the piece to which to find the closest other piece
* @return the piece most correctly placed in relation to the given piece
* @deprecated no known use case */
@@ 101,6 108,83 @@ public class JigsawPuzzle {
return pieces;
}
+ /** a piece on a {@link JigsawPuzzle}
+ * @author dermetfan */
+ public static class Piece extends Image {
+
+ /** the position of the piece on the puzzle (the {@link PolygonRegionDrawable#getPolygonX() minX} and {@link PolygonRegionDrawable#getPolygonY() minY} of its vertices) */
+ private float slotX, slotY;
+
+ /** temporary Polygon for internal use */
+ private final Polygon tmpPolygon = new Polygon();
+
+ public Piece(Drawable drawable) {
+ super(drawable);
+ }
+
+ @Override
+ public void setDrawable(Drawable drawable) {
+ super.setDrawable(drawable);
+ if(drawable instanceof PolygonRegionDrawable) {
+ PolygonRegionDrawable pd = (PolygonRegionDrawable) drawable;
+ slotX = pd.getPolygonX();
+ slotY = pd.getPolygonY();
+ } else
+ slotX = slotY = 0;
+ }
+
+ @Override
+ public Actor hit(float x, float y, boolean touchable) {
+ Actor hit = super.hit(x, y, touchable);
+ PolygonRegionDrawable drawable = getDrawable() instanceof PolygonRegionDrawable ? (PolygonRegionDrawable) getDrawable() : null;
+ if(hit == this && drawable != null) {
+ tmpPolygon.setVertices(drawable.getRegion().getVertices());
+ tmpPolygon.setPosition(-slotX, -slotY);
+ if(!tmpPolygon.contains(x / getWidth() * drawable.getPolygonWidth(), y / getHeight() * drawable.getPolygonHeight()))
+ return null;
+ }
+ return hit;
+ }
+
+ /** @param reference the piece in relation to which to this piece should snap in its spot */
+ public void place(Piece reference) {
+ Vector2 refPuzzlePoint = Pools.obtain(Vector2.class).set(reference.getX(), reference.getY()).sub(reference.slotX, reference.slotY);
+ setPosition(refPuzzlePoint.x + slotX, refPuzzlePoint.y + slotY);
+ Pools.free(refPuzzlePoint);
+ }
+
+ /** @param reference the piece in relation to which this piece's position should be checked
+ * @param tolerance the distance by which each piece is allowed to be off
+ * @return if this piece is placed correctly in relation to the given reference piece with the given tolerance */
+ public boolean isPlacedCorrectly(Piece reference, float tolerance) {
+ // get bottom left corner of each puzzle
+ Vector2 puzzlePos = Pools.obtain(Vector2.class).set(-slotX, -slotY), refPuzzlePoint = Pools.obtain(Vector2.class).set(-reference.slotX, -reference.slotY);
+ localToStageCoordinates(puzzlePos);
+ reference.localToStageCoordinates(refPuzzlePoint);
+
+ // see if they're the same
+ boolean rel = puzzlePos.epsilonEquals(refPuzzlePoint, tolerance);
+
+ Pools.free(puzzlePos);
+ Pools.free(refPuzzlePoint);
+
+ return rel;
+ }
+
+ // getters and setters
+
+ /** @return the {@link #slotX} */
+ public float getSlotX() {
+ return slotX;
+ }
+
+ /** @return the {@link #slotY} */
+ public float getSlotY() {
+ return slotY;
+ }
+
+ }
+
/** @author dermetfan */
public static class Source extends DragAndDrop.Source {
@@ 236,18 320,21 @@ public class JigsawPuzzle {
if(ref == piece)
continue;
if(piece.isPlacedCorrectly(ref, tolerance)) {
- piece.place(ref); // snap it into its perfect position in relation to some already placed piece
+ piece.place(ref);
placed(piece);
}
}
}
}
+ /** called by {@link #drop(DragAndDrop.Source, Payload, float, float, int) drop} when a piece is placed
+ * @param piece the placed piece */
protected void placed(Piece piece) {
if(puzzle.isSolved(tolerance))
solved();
}
+ /** called by {@link #placed(Piece) placed} when all pieces are placed correctly */
protected void solved() {}
// getters and setters
@@ 274,80 361,4 @@ public class JigsawPuzzle {
}
- /** a piece on a {@link JigsawPuzzle}
- * @author dermetfan */
- public static class Piece extends Image {
-
- /** the position of the piece on the puzzle (the {@link PolygonRegionDrawable#getPolygonX() minX} and {@link PolygonRegionDrawable#getPolygonY() minY} of its vertices) */
- private float slotX, slotY;
-
- public Piece(PolygonRegionDrawable drawable) {
- super(drawable);
- }
-
- @Override
- public void setDrawable(Drawable drawable) {
- super.setDrawable(drawable);
- if(drawable instanceof PolygonRegionDrawable) {
- PolygonRegionDrawable pd = (PolygonRegionDrawable) drawable;
- slotX = pd.getPolygonX();
- slotY = pd.getPolygonY();
- } else
- slotX = slotY = 0;
- }
-
- private final Polygon tmpPolygon = new Polygon();
-
- @Override
- public Actor hit(float x, float y, boolean touchable) {
- Actor hit = super.hit(x, y, touchable);
- PolygonRegionDrawable drawable = getDrawable() instanceof PolygonRegionDrawable ? (PolygonRegionDrawable) getDrawable() : null;
- if(hit == this && drawable != null) {
- tmpPolygon.setVertices(drawable.getRegion().getVertices());
- tmpPolygon.setPosition(-slotX, -slotY);
- if(!tmpPolygon.contains(x / getWidth() * drawable.getPolygonWidth(), y / getHeight() * drawable.getPolygonHeight()))
- return null;
- }
- return hit;
- }
-
- /** @param reference the piece in relation to which to this piece should snap in its spot */
- public void place(Piece reference) {
- Vector2 refPuzzlePoint = Pools.obtain(Vector2.class).set(reference.getX(), reference.getY()).sub(reference.slotX, reference.slotY);
- setPosition(refPuzzlePoint.x + slotX, refPuzzlePoint.y + slotY);
- Pools.free(refPuzzlePoint);
- }
-
- /** @param reference the piece in relation to which this piece's position should be checked
- * @param tolerance the distance by which each piece is allowed to be off
- * @return if this piece is placed correctly in relation to the given reference piece with the given tolerance */
- public boolean isPlacedCorrectly(Piece reference, float tolerance) {
- // get puzzle points (bottom left corner of the puzzle)
- Vector2 puzzlePoint = Pools.obtain(Vector2.class).set(-slotX, -slotY), refPuzzlePoint = Pools.obtain(Vector2.class).set(-reference.slotX, -reference.slotY);
- localToStageCoordinates(puzzlePoint);
- reference.localToStageCoordinates(refPuzzlePoint);
-
- // see if they're the same
- boolean rel = puzzlePoint.epsilonEquals(refPuzzlePoint, tolerance);
-
- Pools.free(puzzlePoint);
- Pools.free(refPuzzlePoint);
-
- return rel;
- }
-
- // getters and setters
-
- /** @return the {@link #slotX} */
- public float getSlotX() {
- return slotX;
- }
-
- /** @return the {@link #slotY} */
- public float getSlotY() {
- return slotY;
- }
-
- }
-
}