summaryrefslogtreecommitdiffstats
path: root/core/src/ch/asynk/tankontank/engine
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2014-09-17 09:22:21 +0200
committerJérémy Zurcher <jeremy@asynk.ch>2014-09-17 09:22:21 +0200
commit007ee42ea9ce00aa47a18f8e514fdcd018b486a7 (patch)
treee147983cf66b1074b9bb65252112ace89d96d1ec /core/src/ch/asynk/tankontank/engine
parent3b6edd5375770fe6e9080759601896a0bb43d404 (diff)
downloadRustAndDust-007ee42ea9ce00aa47a18f8e514fdcd018b486a7.zip
RustAndDust-007ee42ea9ce00aa47a18f8e514fdcd018b486a7.tar.gz
split into '.engine.*' and '.game.*'
Diffstat (limited to 'core/src/ch/asynk/tankontank/engine')
-rw-r--r--core/src/ch/asynk/tankontank/engine/Map.java43
-rw-r--r--core/src/ch/asynk/tankontank/engine/MapImage.java167
-rw-r--r--core/src/ch/asynk/tankontank/engine/Pawn.java24
-rw-r--r--core/src/ch/asynk/tankontank/engine/PawnImage.java71
-rw-r--r--core/src/ch/asynk/tankontank/engine/Tile.java41
5 files changed, 346 insertions, 0 deletions
diff --git a/core/src/ch/asynk/tankontank/engine/Map.java b/core/src/ch/asynk/tankontank/engine/Map.java
new file mode 100644
index 0000000..75aedd9
--- /dev/null
+++ b/core/src/ch/asynk/tankontank/engine/Map.java
@@ -0,0 +1,43 @@
+package ch.asynk.tankontank.engine;
+
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.math.Vector3;
+import com.badlogic.gdx.math.GridPoint2;
+
+public interface Map
+{
+ // libgdx
+
+ public float getWidth();
+ public float getHeight();
+
+ // game
+
+ public GridPoint2 getHexAt(GridPoint2 hex, float x, float y);
+
+ public Pawn getTopPawnAt(GridPoint2 hex);
+
+ public Vector2 getHexCenterAt(GridPoint2 hex);
+
+ public Vector2 getPawnPosAt(Pawn pawn, GridPoint2 hex);
+
+ public void movePawnTo(Pawn pawn, Vector3 coords);
+
+ public void setPawnAt(Pawn pawn, int col, int row, Tile.Orientation o);
+
+ public void movePawnTo(Pawn pawn, int col, int row, Tile.Orientation o);
+
+ public class Config
+ {
+ public int cols;
+ public int rows;
+ public int x0; // bottom left x offset
+ public int y0; // bottom left y offset
+ public int w; // hex width
+ public int dw; // half hex : w/2
+ public int h; // hex side
+ public float dh; // hex top : h/2
+ public float H; // square height : h + dh
+ public float slope; // north-west side slope : (dh / (float) dw)
+ }
+}
diff --git a/core/src/ch/asynk/tankontank/engine/MapImage.java b/core/src/ch/asynk/tankontank/engine/MapImage.java
new file mode 100644
index 0000000..07ab9cf
--- /dev/null
+++ b/core/src/ch/asynk/tankontank/engine/MapImage.java
@@ -0,0 +1,167 @@
+package ch.asynk.tankontank.engine;
+
+import com.badlogic.gdx.Gdx;
+
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.math.Vector3;
+import com.badlogic.gdx.math.GridPoint2;
+
+public class MapImage extends Image implements Map
+{
+ private Map.Config cfg;
+ private int cols;
+ private int rows;
+ private Tile[][] board;
+
+ @SuppressWarnings("unchecked")
+ public MapImage(Map.Config cfg, Tile[][] board, Texture texture)
+ {
+ super(texture);
+ this.cfg = cfg;
+ this.board = board;
+ this.cols = cfg.cols - 1;
+ this.rows = cfg.rows - 1;
+ }
+
+ public Pawn getTopPawnAt(GridPoint2 cell)
+ {
+ return getTopPawnAt(cell.x, cell.y);
+ }
+
+ private Pawn getTopPawnAt(int col, int row)
+ {
+ // if ((col < 0) || (row < 0)) throw new ();
+ return board[row][col].getTop();
+ }
+
+ private int pushPawnAt(Pawn pawn, int col, int row)
+ {
+ // if ((col < 0) || (row < 0)) throw new ();
+ return board[row][col].push(pawn);
+ }
+
+ private void removePawnFrom(Pawn pawn, int col, int row)
+ {
+ // if ((col < 0) || (row < 0)) throw new ();
+ board[row][col].remove(pawn);
+ }
+
+ public Vector2 getHexCenterAt(GridPoint2 cell)
+ {
+ float x = cfg.x0 + ((cell.x * cfg.w) + (cfg.w / 2));
+ float y = cfg.y0 + ((cell.y * cfg.H) + (cfg.h / 2));
+ if ((cell.y % 2) == 1) x += cfg.dw;
+ return new Vector2(x, y);
+ }
+
+ public Vector2 getPawnPosAt(Pawn pawn, GridPoint2 cell)
+ {
+ return getPawnPosAt(pawn, cell.x, cell.y);
+ }
+
+ private Vector2 getPawnPosAt(Pawn pawn, int col, int row)
+ {
+ float x = cfg.x0 + ((col * cfg.w) + ((cfg.w - pawn.getHeight()) / 2));
+ float y = cfg.y0 + ((row * cfg.H) + ((cfg.h - pawn.getWidth()) / 2));
+ if ((row % 2) == 1) x += cfg.dw;
+ return new Vector2(x, y);
+ }
+
+ public void movePawnTo(Pawn pawn, Vector3 coords)
+ {
+ GridPoint2 p = getHexAt(null, coords.x, coords.y);
+ movePawnTo(pawn, p.x, p.y, Tile.Orientation.KEEP);
+ }
+
+ public void setPawnAt(final Pawn pawn, final int col, final int row, Tile.Orientation o)
+ {
+ int z = pushPawnAt(pawn, col, row);
+ Vector2 pos = getPawnPosAt(pawn, col, row);
+ pawn.pushMove(pos.x, pos.y, z, o);
+ }
+
+ public void movePawnTo(final Pawn pawn, final int col, final int row, Tile.Orientation o)
+ {
+ GridPoint2 prev = getHexAt(pawn.getLastPosition());
+ // if (prev == null) throw new ();
+ removePawnFrom(pawn, prev.x, prev.y);
+
+ if ((col < 0) || (row < 0)) {
+ pawn.resetMoves(new Runnable() {
+ @Override
+ public void run() {
+ GridPoint2 hex = getHexAt(pawn.getLastPosition());
+ pawn.setZIndex(pushPawnAt(pawn, hex.x, hex.y));
+ }
+ });
+ return;
+ } else {
+ int z = pushPawnAt(pawn, col, row);
+ Vector2 pos = getPawnPosAt(pawn, col, row);
+ pawn.pushMove(pos.x, pos.y, z, o);
+ }
+ }
+
+ private GridPoint2 getHexAt(Vector3 v)
+ {
+ if (v == null) return null;
+ return getHexAt(null, v.x, v.y);
+ }
+
+ public GridPoint2 getHexAt(GridPoint2 hex, float cx, float cy)
+ {
+ if (hex == null) hex = new GridPoint2();
+
+ // compute row
+ int row;
+ boolean oddRow = true;
+ float y = (cy - cfg.y0);
+ if (y < 0.f) {
+ row = -1;
+ } else {
+ row = (int) (y / cfg.H);
+ oddRow = ((row % 2) == 1);
+ }
+
+ // compute col
+ int col;
+ float x = (cx - cfg.x0);
+ if (oddRow) x -= cfg.dw;
+ if (x < 0.f) {
+ col = -1;
+ } else {
+ col = (int) (x / cfg.w);
+ }
+
+ // check upper boundaries
+ float dy = (y - (row * cfg.H));
+ if (dy > cfg.h) {
+ dy -= cfg.h;
+ float dx = (x - (col * cfg.w));
+ if (dx < cfg.dw) {
+ if ((dx * cfg.slope) < dy) {
+ row += 1;
+ if (!oddRow) col -= 1;
+ oddRow = !oddRow;
+ }
+ } else {
+ if (((cfg.w - dx) * cfg.slope) < dy) {
+ row += 1;
+ if (oddRow) col += 1;
+ oddRow = !oddRow;
+ }
+ }
+ }
+
+ // validate hex
+ if ((col < 0) || (row < 0) || (row > rows) || (col > cols) || (oddRow && ((col +1)> cols)))
+ hex.set(-1, -1);
+ else
+ hex.set(col, row);
+
+ return hex;
+ }
+}
diff --git a/core/src/ch/asynk/tankontank/engine/Pawn.java b/core/src/ch/asynk/tankontank/engine/Pawn.java
new file mode 100644
index 0000000..969e1e9
--- /dev/null
+++ b/core/src/ch/asynk/tankontank/engine/Pawn.java
@@ -0,0 +1,24 @@
+package ch.asynk.tankontank.engine;
+
+import com.badlogic.gdx.math.Vector3;
+
+public interface Pawn
+{
+ // libgdx
+
+ public float getWidth();
+ public float getHeight();
+ public void setZIndex(int z);
+
+ // game
+
+ public Vector3 getLastPosition();
+
+ public void moveBy(float x, float y);
+
+ public void pushMove(float x, float y, int z, Tile.Orientation o);
+
+ public void resetMoves(Runnable cb);
+
+ public void moveDone();
+}
diff --git a/core/src/ch/asynk/tankontank/engine/PawnImage.java b/core/src/ch/asynk/tankontank/engine/PawnImage.java
new file mode 100644
index 0000000..77ef752
--- /dev/null
+++ b/core/src/ch/asynk/tankontank/engine/PawnImage.java
@@ -0,0 +1,71 @@
+package ch.asynk.tankontank.engine;
+
+import java.util.ArrayDeque;
+
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction;
+
+import com.badlogic.gdx.math.Vector3;
+
+public class PawnImage extends Image implements Pawn
+{
+ private static final float MOVE_TIME = 0.3f;
+ private static final float ROTATE_TIME = 0.2f;
+
+ private ArrayDeque<Vector3> path = new ArrayDeque<Vector3>();
+
+ public PawnImage(TextureRegion region)
+ {
+ super(region);
+ setOrigin((getWidth() / 2.f), (getHeight() / 2.f));
+ }
+
+ public Vector3 getLastPosition()
+ {
+ if ((path == null) || (path.size() == 0)) return null;
+ return path.getFirst();
+ }
+
+ public void pushMove(float x, float y, int z, Tile.Orientation r)
+ {
+ setPosition(x, y);
+ if (r != Tile.Orientation.KEEP) setRotation(r.v);
+ setZIndex(z);
+ path.push(new Vector3(x, y, r.v));
+ }
+
+ public void resetMoves(Runnable cb)
+ {
+ final Pawn self = this;
+ final Vector3 finalPos = path.getLast();
+
+ SequenceAction seq = new SequenceAction();
+ while(path.size() != 0) {
+ Vector3 v = path.pop();
+ seq.addAction(Actions.moveTo(v.x, v.y, MOVE_TIME));
+ if (v.z != Tile.Orientation.KEEP.v)
+ seq.addAction(Actions.rotateTo(v.z, ROTATE_TIME));
+ }
+
+ seq.addAction( Actions.run(new Runnable() {
+ @Override
+ public void run() {
+ path.push(finalPos);
+ }
+ }));
+
+ // map set z index and push me in hex stack
+ seq.addAction(Actions.run(cb));
+
+ addAction(seq);
+ }
+
+ public void moveDone()
+ {
+ Vector3 v = path.pop();
+ path.clear();
+ path.push(v);
+ }
+}
diff --git a/core/src/ch/asynk/tankontank/engine/Tile.java b/core/src/ch/asynk/tankontank/engine/Tile.java
new file mode 100644
index 0000000..eaaaf24
--- /dev/null
+++ b/core/src/ch/asynk/tankontank/engine/Tile.java
@@ -0,0 +1,41 @@
+package ch.asynk.tankontank.engine;
+
+import java.util.List;
+
+public interface Tile
+{
+ public int push(Pawn pawn);
+
+ public void remove(Pawn pawn);
+
+ public Pawn getTop();
+
+ public int costFrom(Side side);
+
+ public enum Orientation
+ {
+ KEEP(0),
+ WEST(-90),
+ NORTH_WEST(-30),
+ NORTH_EAST (30),
+ EAST(90),
+ SOUTH_EAST(150),
+ SOUTH_WEST(-150);
+
+ public final int v;
+ Orientation(int v) { this.v = v; }
+ }
+
+ public enum Side
+ {
+ WEST(1),
+ NORTH_WEST(2),
+ NORTH_EAST (4),
+ EAST(8),
+ SOUTH_EAST(16),
+ SOUTH_WEST(32);
+
+ public final int v;
+ Side(int v) { this.v = v; }
+ }
+}