diff --git a/android/assets/ui/snap_off.png b/android/assets/ui/snap_off.png
new file mode 100644
index 0000000..993ab25
Binary files /dev/null and b/android/assets/ui/snap_off.png differ
diff --git a/android/assets/ui/snap_on.png b/android/assets/ui/snap_on.png
new file mode 100644
index 0000000..2dafd33
Binary files /dev/null and b/android/assets/ui/snap_on.png differ
diff --git a/core/src/io/github/lonamiwebs/klooni/Klooni.java b/core/src/io/github/lonamiwebs/klooni/Klooni.java
index 9a3df41..8c39939 100644
--- a/core/src/io/github/lonamiwebs/klooni/Klooni.java
+++ b/core/src/io/github/lonamiwebs/klooni/Klooni.java
@@ -50,6 +50,8 @@ public class Klooni extends Game {
skin.add("share_texture", new Texture(Gdx.files.internal("ui/share.png")));
skin.add("sound_on_texture", new Texture(Gdx.files.internal("ui/sound_on.png")));
skin.add("sound_off_texture", new Texture(Gdx.files.internal("ui/sound_off.png")));
+ skin.add("snap_on_texture", new Texture(Gdx.files.internal("ui/snap_on.png")));
+ skin.add("snap_off_texture", new Texture(Gdx.files.internal("ui/snap_off.png")));
skin.add("issues_texture", new Texture(Gdx.files.internal("ui/issues.png")));
skin.add("credits_texture", new Texture(Gdx.files.internal("ui/credits.png")));
skin.add("web_texture", new Texture(Gdx.files.internal("ui/web.png")));
@@ -121,6 +123,14 @@ public class Klooni extends Game {
prefs.putBoolean("muteSound", soundsEnabled()).flush();
}
+ public static boolean shouldSnapToGrid() {
+ return prefs.getBoolean("snapToGrid", false);
+ }
+
+ public static void toggleSnapToGrid() {
+ prefs.putBoolean("snapToGrid", !shouldSnapToGrid()).flush();
+ }
+
public static boolean isThemeBought(Theme theme) {
if (theme.getPrice() == 0)
return true;
diff --git a/core/src/io/github/lonamiwebs/klooni/game/Board.java b/core/src/io/github/lonamiwebs/klooni/game/Board.java
index d091237..01b45ad 100644
--- a/core/src/io/github/lonamiwebs/klooni/game/Board.java
+++ b/core/src/io/github/lonamiwebs/klooni/game/Board.java
@@ -121,6 +121,21 @@ public class Board implements BinSerializable {
return putPiece(piece, x, y);
}
+ Vector2 snapToGrid(final Piece piece, final Vector2 position) {
+ // Snaps the given position (e.g. mouse) to the grid,
+ // assuming piece wants to be put at the specified position.
+ // If the piece was not on the grid, the original position is returned
+ //
+ // Logic to determine the x and y is a copy-paste from putScreenPiece
+ final Vector2 local = position.cpy().sub(pos);
+ int x = MathUtils.round(local.x / piece.cellSize);
+ int y = MathUtils.round(local.y / piece.cellSize);
+ if (canPutPiece(piece, x, y))
+ return new Vector2(pos.x + x * piece.cellSize, pos.y + y * piece.cellSize);
+ else
+ return position;
+ }
+
// This will clear both complete rows and columns, all at once.
// The reason why we can't check first rows and then columns
// (or vice versa) is because the following case (* filled, _ empty):
diff --git a/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java b/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java
index 7a57844..f70eb04 100644
--- a/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java
+++ b/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java
@@ -209,7 +209,8 @@ public class PieceHolder implements BinSerializable {
}
// Updates the state of the piece holder (and the held piece)
- public void update() {
+ // TODO Passing the board seems expensive… Should it rather be an attribute?
+ public void update(Board board) {
Piece piece;
if (heldPiece > -1) {
piece = pieces[heldPiece];
@@ -227,6 +228,8 @@ public class PieceHolder implements BinSerializable {
// avoiding to cover it with the finger (issue on Android devices)
mouse.sub(piece.getRectangle().width * 0.5f, -pickedCellSize);
}
+ if (Klooni.shouldSnapToGrid())
+ mouse.set(board.snapToGrid(piece, mouse));
piece.pos.lerp(mouse, DRAG_SPEED);
piece.cellSize = Interpolation.linear.apply(piece.cellSize, pickedCellSize, DRAG_SPEED);
diff --git a/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java b/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java
index 99ad816..cccbee0 100644
--- a/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java
+++ b/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java
@@ -80,6 +80,20 @@ class CustomizeScreen implements Screen {
});
optionsGroup.addActor(soundButton);
+ // Snap to grid on/off
+ final SoftButton snapButton = new SoftButton(
+ 2, Klooni.shouldSnapToGrid() ? "snap_on_texture" : "snap_off_texture");
+
+ snapButton.addListener(new ChangeListener() {
+ @Override
+ public void changed(ChangeEvent event, Actor actor) {
+ Klooni.toggleSnapToGrid();
+ snapButton.image = CustomizeScreen.this.game.skin.getDrawable(
+ Klooni.shouldSnapToGrid() ? "snap_on_texture" : "snap_off_texture");
+ }
+ });
+ optionsGroup.addActor(snapButton);
+
// Issues
final SoftButton issuesButton = new SoftButton(3, "issues_texture");
issuesButton.addListener(new ChangeListener() {
diff --git a/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java b/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java
index b7aa2b2..05cf406 100644
--- a/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java
+++ b/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java
@@ -166,7 +166,7 @@ class GameScreen implements Screen, InputProcessor, BinSerializable {
scorer.draw(batch);
board.draw(batch);
- holder.update();
+ holder.update(board);
holder.draw(batch);
bonusParticleHandler.run(batch);
diff --git a/original-resources/buttons.svg b/original-resources/buttons.svg
index 3ac7792..b902870 100644
--- a/original-resources/buttons.svg
+++ b/original-resources/buttons.svg
@@ -102,9 +102,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="4.0000001"
- inkscape:cx="16.355684"
- inkscape:cy="190.15864"
+ inkscape:zoom="1.4142136"
+ inkscape:cx="95.169026"
+ inkscape:cy="193.1638"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@@ -141,7 +141,7 @@
style="opacity:1;fill:#e3e3e3;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0"
id="rect4301"
width="120"
- height="100"
+ height="90"
x="0"
y="752.36218"
ry="0" />
@@ -358,14 +358,14 @@
buttons
+ x="128.69154"
+ y="836.78644">buttons
+
+
+
+
+
+
+
diff --git a/original-resources/window_size.svg b/original-resources/window_size.svg
index 29d9ea2..25ac142 100644
--- a/original-resources/window_size.svg
+++ b/original-resources/window_size.svg
@@ -17,7 +17,36 @@
inkscape:version="0.91 r13725"
sodipodi:docname="window_size.svg">
+ id="defs4">
+
+
+
+
+
+
+
image/svg+xml
-
+
@@ -283,7 +312,7 @@
style="opacity:1;fill:#0000ff;fill-opacity:0.25;stroke:none;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4312"
width="715.76221"
- height="750.81952"
+ height="622.24811"
x="799.99988"
y="243.2572" />
@@ -307,11 +336,6 @@
height="151.81004"
x="1474.7661"
y="289.58844" />
-
default colors
- hodor hodor
bought
-
pieces: 300px (25%)
+
+ 42h | confirm purchase?
+
+
+
+
+