summaryrefslogtreecommitdiffstats
path: root/core/src/ch/asynk/gdx/boardgame/board
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2018-10-03 16:29:04 +0200
committerJérémy Zurcher <jeremy@asynk.ch>2018-10-03 16:29:04 +0200
commit2f1bec6890815033211fde71e645c5a57e502a20 (patch)
treea83756b4df61e729fdbdf495c19423dc7799e269 /core/src/ch/asynk/gdx/boardgame/board
parent977ce8e5a8f967f2ad9acc634111231e3af9ef7a (diff)
downloadgdx-boardgame-2f1bec6890815033211fde71e645c5a57e502a20.zip
gdx-boardgame-2f1bec6890815033211fde71e645c5a57e502a20.tar.gz
tabletop -> boardgame
Diffstat (limited to 'core/src/ch/asynk/gdx/boardgame/board')
-rw-r--r--core/src/ch/asynk/gdx/boardgame/board/BoardFactory.java42
-rw-r--r--core/src/ch/asynk/gdx/boardgame/board/HexBoard.java136
-rw-r--r--core/src/ch/asynk/gdx/boardgame/board/SquareBoard.java39
-rw-r--r--core/src/ch/asynk/gdx/boardgame/board/TriangleBoard.java108
4 files changed, 325 insertions, 0 deletions
diff --git a/core/src/ch/asynk/gdx/boardgame/board/BoardFactory.java b/core/src/ch/asynk/gdx/boardgame/board/BoardFactory.java
new file mode 100644
index 0000000..8dc73b6
--- /dev/null
+++ b/core/src/ch/asynk/gdx/boardgame/board/BoardFactory.java
@@ -0,0 +1,42 @@
+package ch.asynk.gdx.boardgame.board;
+
+import ch.asynk.gdx.boardgame.Board;
+
+public class BoardFactory
+{
+ public enum BoardType
+ {
+ HEX, SQUARE, TRIANGLE
+ }
+
+ public enum BoardOrientation
+ {
+ VERTICAL,
+ HORIZONTAL,
+ }
+
+ public static Board getBoard(BoardType boardType, float side)
+ {
+ return getBoard(boardType, side, 0f, 0f, BoardOrientation.VERTICAL);
+ }
+
+ public static Board getBoard(BoardType boardType, float side, float x0, float y0)
+ {
+ return getBoard(boardType, side, x0, y0, BoardOrientation.VERTICAL);
+ }
+
+ public static Board getBoard(BoardType boardType, float side, float x0, float y0, BoardOrientation boardOrientation)
+ {
+ switch(boardType)
+ {
+ case HEX:
+ return new HexBoard(side, x0, y0, boardOrientation);
+ case SQUARE:
+ return new SquareBoard(side, x0, y0);
+ case TRIANGLE:
+ return new TriangleBoard(side, x0, y0, boardOrientation);
+ default:
+ throw new RuntimeException( String.format("%s board type is not implemented yet.", boardType) );
+ }
+ }
+}
diff --git a/core/src/ch/asynk/gdx/boardgame/board/HexBoard.java b/core/src/ch/asynk/gdx/boardgame/board/HexBoard.java
new file mode 100644
index 0000000..d5b2a26
--- /dev/null
+++ b/core/src/ch/asynk/gdx/boardgame/board/HexBoard.java
@@ -0,0 +1,136 @@
+package ch.asynk.gdx.boardgame.board;
+
+import com.badlogic.gdx.math.Vector2;
+
+import ch.asynk.gdx.boardgame.Board;
+
+public class HexBoard implements Board
+{
+ private final float side; // length of the side of the hex
+ private final float x0; // bottom left x offset
+ private final float y0; // bottom left y offset
+ private final BoardFactory.BoardOrientation orientation;
+
+ private final float w; // side to side orthogonal distance
+ private final float dw; // half hex : w/2
+ private final float dh; // hex top : s/2
+ private final float h; // square height : s + dh
+ private final float slope; // dh / dw
+
+ // BoardOrientation.VERTICAL : 2 vertical sides : 2 vertices pointing up and down
+ // coordinates
+ // \
+ // \___
+ // cols are horizontal
+ // rows are at -120°
+ // bottom left is the bottom vertice of the most bottom-left vertical hex side of the map
+ //
+ // BoardOrientation.HORIZONTAL : 2 horizontal sides : 2 vertices pointing left and right
+ // coordinates
+ // |
+ // |
+ // \
+ // \
+ // cols are at +120°
+ // rows are vertical°
+ // bottom left is the left vertice of the most bottom-left horizontal hex side of the map
+
+ public HexBoard(float side, float x0, float y0, BoardFactory.BoardOrientation boardOrientation)
+ {
+ this.side = side;
+ this.x0 = x0;
+ this.y0 = y0;
+ this.orientation = boardOrientation;
+
+ this.w = side * 1.73205f;
+ this.dw = w / 2.0f;
+ this.dh = side / 2.0f;
+ this.h = side + dh;
+ this.slope = dh / dw;
+ }
+
+ @Override public void centerOf(int x, int y, Vector2 v)
+ {
+ float cx = this.x0;
+ float cy = this.y0;
+
+ if (this.orientation == BoardFactory.BoardOrientation.VERTICAL) {
+ cx += (this.dw + (x * this.w) - (y * this.dw));
+ cy += (this.dh + (y * this.h));
+ } else {
+ cx += (this.dh + (x * this.h));
+ cy += (this.dw + (y * this.w) - (x * this.dw));
+ }
+
+ v.set(cx, cy);
+ }
+
+ @Override public void toBoard(float x, float y, Vector2 v)
+ {
+ int col = -1;
+ int row = -1;
+
+ if (this.orientation == BoardFactory.BoardOrientation.VERTICAL) {
+ // compute row
+ float dy = y - this.y0;
+ row = (int) (dy / this.h);
+ if (dy < 0f) row -= 1;
+
+ // compute col
+ float dx = x - this.x0 + (row * this.dw);
+ col = (int) (dx / this.w);
+ if (dx < 0f) col -= 1;
+
+ // upper rectangle or hex body
+ if (dy > ((row * this.h) + this.side)) {
+ dy -= ((row * this.h) + this.side);
+ dx -= (col * this.w);
+ // upper left or right rectangle
+ if (dx < this.dw) {
+ if (dy > (dx * this.slope)) {
+ // upper left hex
+ row += 1;
+ }
+ } else {
+ // if (dy > ((2 * this.dh) - (dx * this.slope))) {
+ if (dy > ((this.w - dx) * this.slope)) {
+ // upper right hex
+ row += 1;
+ col += 1;
+ }
+ }
+ }
+ } else {
+ // compute col
+ float dx = x - this.x0;
+ col = (int) (dx / this.h);
+ if (dx < 0f) col -= 1;
+
+ // compute row
+ float dy = y - this.y0 + (col * this.dw);
+ row = (int) (dy / this.w);
+ if (dy < 0f) row -= 1;
+
+ // right rectangle or hex body
+ if (dx > ((col * this.h) + this.side)) {
+ dx -= ((col * this.h) + this.side);
+ dy -= (row * this.w);
+ // upper or lower rectangle
+ if (dy > ((this.dw - dx) / this.slope)) {
+ if (dy > ((2 * this.dw) - (dx / this.slope))) {
+ // upper right hex
+ col += 1;
+ row += 1;
+ }
+ } else {
+ if (dy < (dx / this.slope)) {
+ // lower right hex
+ col += 1;
+ }
+ }
+ }
+ }
+
+ v.set(col, row);
+ }
+}
diff --git a/core/src/ch/asynk/gdx/boardgame/board/SquareBoard.java b/core/src/ch/asynk/gdx/boardgame/board/SquareBoard.java
new file mode 100644
index 0000000..de2ab4c
--- /dev/null
+++ b/core/src/ch/asynk/gdx/boardgame/board/SquareBoard.java
@@ -0,0 +1,39 @@
+package ch.asynk.gdx.boardgame.board;
+
+import com.badlogic.gdx.math.Vector2;
+
+import ch.asynk.gdx.boardgame.Board;
+
+public class SquareBoard implements Board
+{
+ private final float side; // length of the side of a square
+ private final float x0; // bottom left x offset
+ private final float y0; // bottom left y offset
+
+ public SquareBoard(float side, float x0, float y0)
+ {
+ this.side = side;
+ this.x0 = x0;
+ this.y0 = y0;
+ }
+
+ @Override public void centerOf(int x, int y, Vector2 v)
+ {
+ float cx = this.x0 + (this.side / 2) + (this.side * x);
+ float cy = this.y0 + (this.side / 2) + (this.side * y);
+
+ v.set(cx, cy);
+ }
+
+ @Override public void toBoard(float x, float y, Vector2 v)
+ {
+ float dx = x - this.x0;
+ float dy = y - this.y0;
+ int col = (int) (dx / this.side);
+ int row = (int) (dy / this.side);
+ if (dx < 0) col -=1;
+ if (dy < 0) row -=1;
+
+ v.set(col, row);
+ }
+}
diff --git a/core/src/ch/asynk/gdx/boardgame/board/TriangleBoard.java b/core/src/ch/asynk/gdx/boardgame/board/TriangleBoard.java
new file mode 100644
index 0000000..e3c9434
--- /dev/null
+++ b/core/src/ch/asynk/gdx/boardgame/board/TriangleBoard.java
@@ -0,0 +1,108 @@
+package ch.asynk.gdx.boardgame.board;
+
+import com.badlogic.gdx.math.Vector2;
+
+import ch.asynk.gdx.boardgame.Board;
+
+public class TriangleBoard implements Board
+{
+ private final float side; // length of the side of the equilateral triangle
+ private final float x0; // bottom left x offset
+ private final float y0; // bottom left y offset
+ private final BoardFactory.BoardOrientation orientation;
+
+ private final float d; // side / 2
+ private final float h; // height of the triangle
+ private final float m; // h / d
+ private final float h13; // 1/3 height of the triangle
+ private final float h23; // 2/3 height of the triangle
+ private final float h43; // 4/3 height of the triangle
+
+ public TriangleBoard(float side, float x0, float y0, BoardFactory.BoardOrientation boardOrientation)
+ {
+ this.side = side;
+ this.x0 = x0;
+ this.y0 = y0;
+ this.orientation = boardOrientation;
+
+ this.d = side / 2f;
+ this.h = side * 0.866f;
+ this.m = this.h / this.d;
+ this.h13 = this.h * 0.33333f;
+ this.h23 = this.h * 0.66666f;
+ this.h43 = this.h * 1.33333f;
+ }
+
+ @Override public void centerOf(int x, int y, Vector2 v)
+ {
+ float cx = this.x0;
+ float cy = this.y0;
+
+ if (this.orientation == BoardFactory.BoardOrientation.VERTICAL) {
+ cy += (y * this.d);
+ cx += ((x * this.h) + (((x + y) % 2 == 0) ? this.h23 : this.h13));
+ } else {
+ cx += (this.d + (x * this.d));
+ cy += ((y * this.h) + (((x + y) % 2 == 0) ? this.h13 : this.h23));
+ }
+
+ v.set(cx, cy);
+ }
+
+ @Override public void toBoard(float x, float y, Vector2 v)
+ {
+ boolean vert = (this.orientation == BoardFactory.BoardOrientation.VERTICAL);
+
+ float dx = x - this.x0;
+ float dy = y - this.y0;
+ float cx = (vert ? this.h : this.d);
+ float cy = (vert ? this.d : this.h);
+
+ int col = (int) (dx / cx);
+ int row = (int) (dy / cy);
+ if (dx < 0) col -=1;
+ if (dy < 0) row -=1;
+ dx -= (col * cx);
+ dy -= (row * cy);
+
+ if (vert) {
+ if (col % 2 == 0) {
+ if (row % 2 == 0) {
+ if (dy > (dx / this.m))
+ row += 1;
+ } else {
+ if (dy + (dx / this.m) > d )
+ row += 1;
+ }
+ } else {
+ if (row % 2 == 0) {
+ if (dy + (dx / this.m) > d )
+ row += 1;
+ } else {
+ if (dy > (dx / this.m))
+ row += 1;
+ }
+ }
+ } else {
+ if (row % 2 == 0) {
+ if (col % 2 == 0) {
+ if (dy > (dx * this.m))
+ col -= 1;
+ } else {
+ if (dy + (dx * this.m) < h )
+ col -= 1;
+ }
+ } else {
+ if (col % 2 == 0) {
+ if (dy + (dx * this.m) < h )
+ col -= 1;
+ } else {
+ if (dy > (dx * this.m))
+ col -= 1;
+ }
+ }
+ }
+
+ v.set(col, row);
+ }
+}