From 2f1bec6890815033211fde71e645c5a57e502a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Wed, 3 Oct 2018 16:29:04 +0200 Subject: tabletop -> boardgame --- build.gradle | 2 +- core/src/ch/asynk/gdx/boardgame/Assets.java | 30 +++ core/src/ch/asynk/gdx/boardgame/Board.java | 9 + core/src/ch/asynk/gdx/boardgame/Camera.java | 223 +++++++++++++++++++ core/src/ch/asynk/gdx/boardgame/Drawable.java | 19 ++ core/src/ch/asynk/gdx/boardgame/Touchable.java | 6 + .../ch/asynk/gdx/boardgame/board/BoardFactory.java | 42 ++++ .../src/ch/asynk/gdx/boardgame/board/HexBoard.java | 136 ++++++++++++ .../ch/asynk/gdx/boardgame/board/SquareBoard.java | 39 ++++ .../asynk/gdx/boardgame/board/TriangleBoard.java | 108 ++++++++++ core/src/ch/asynk/gdx/boardgame/ui/Alignment.java | 168 +++++++++++++++ core/src/ch/asynk/gdx/boardgame/ui/Assembly.java | 63 ++++++ core/src/ch/asynk/gdx/boardgame/ui/Button.java | 67 ++++++ core/src/ch/asynk/gdx/boardgame/ui/Element.java | 116 ++++++++++ core/src/ch/asynk/gdx/boardgame/ui/Label.java | 61 ++++++ core/src/ch/asynk/gdx/boardgame/ui/Menu.java | 126 +++++++++++ core/src/ch/asynk/gdx/boardgame/ui/Patch.java | 23 ++ core/src/ch/asynk/gdx/boardgame/ui/Root.java | 28 +++ .../ch/asynk/gdx/boardgame/util/Collection.java | 28 +++ .../ch/asynk/gdx/boardgame/util/IterableArray.java | 143 ++++++++++++ .../ch/asynk/gdx/boardgame/util/IterableQueue.java | 19 ++ .../ch/asynk/gdx/boardgame/util/IterableSet.java | 16 ++ .../ch/asynk/gdx/boardgame/util/IterableStack.java | 26 +++ core/src/ch/asynk/gdx/tabletop/Assets.java | 30 --- core/src/ch/asynk/gdx/tabletop/Board.java | 9 - core/src/ch/asynk/gdx/tabletop/Camera.java | 223 ------------------- core/src/ch/asynk/gdx/tabletop/Drawable.java | 19 -- core/src/ch/asynk/gdx/tabletop/Touchable.java | 6 - .../ch/asynk/gdx/tabletop/board/BoardFactory.java | 42 ---- core/src/ch/asynk/gdx/tabletop/board/HexBoard.java | 136 ------------ .../ch/asynk/gdx/tabletop/board/SquareBoard.java | 39 ---- .../ch/asynk/gdx/tabletop/board/TriangleBoard.java | 108 ---------- core/src/ch/asynk/gdx/tabletop/ui/Alignment.java | 168 --------------- core/src/ch/asynk/gdx/tabletop/ui/Assembly.java | 63 ------ core/src/ch/asynk/gdx/tabletop/ui/Button.java | 67 ------ core/src/ch/asynk/gdx/tabletop/ui/Element.java | 116 ---------- core/src/ch/asynk/gdx/tabletop/ui/Label.java | 61 ------ core/src/ch/asynk/gdx/tabletop/ui/Menu.java | 126 ----------- core/src/ch/asynk/gdx/tabletop/ui/Patch.java | 23 -- core/src/ch/asynk/gdx/tabletop/ui/Root.java | 28 --- .../src/ch/asynk/gdx/tabletop/util/Collection.java | 28 --- .../ch/asynk/gdx/tabletop/util/IterableArray.java | 143 ------------ .../ch/asynk/gdx/tabletop/util/IterableQueue.java | 19 -- .../ch/asynk/gdx/tabletop/util/IterableSet.java | 16 -- .../ch/asynk/gdx/tabletop/util/IterableStack.java | 26 --- test/build.gradle | 2 +- .../asynk/gdx/boardgame/test/AbstractScreen.java | 168 +++++++++++++++ test/src/ch/asynk/gdx/boardgame/test/Assets.java | 84 ++++++++ .../ch/asynk/gdx/boardgame/test/BoardScreen.java | 240 +++++++++++++++++++++ .../asynk/gdx/boardgame/test/DesktopLauncher.java | 14 ++ .../ch/asynk/gdx/boardgame/test/GdxBoardTest.java | 97 +++++++++ .../ch/asynk/gdx/boardgame/test/LoadingScreen.java | 168 +++++++++++++++ .../ch/asynk/gdx/boardgame/test/MenuScreen.java | 86 ++++++++ test/src/ch/asynk/gdx/boardgame/test/UiScreen.java | 103 +++++++++ .../ch/asynk/gdx/tabletop/test/AbstractScreen.java | 168 --------------- test/src/ch/asynk/gdx/tabletop/test/Assets.java | 84 -------- .../ch/asynk/gdx/tabletop/test/BoardScreen.java | 240 --------------------- .../asynk/gdx/tabletop/test/DesktopLauncher.java | 14 -- .../ch/asynk/gdx/tabletop/test/GdxBoardTest.java | 97 --------- .../ch/asynk/gdx/tabletop/test/LoadingScreen.java | 168 --------------- .../src/ch/asynk/gdx/tabletop/test/MenuScreen.java | 86 -------- test/src/ch/asynk/gdx/tabletop/test/UiScreen.java | 103 --------- 62 files changed, 2458 insertions(+), 2458 deletions(-) create mode 100644 core/src/ch/asynk/gdx/boardgame/Assets.java create mode 100644 core/src/ch/asynk/gdx/boardgame/Board.java create mode 100644 core/src/ch/asynk/gdx/boardgame/Camera.java create mode 100644 core/src/ch/asynk/gdx/boardgame/Drawable.java create mode 100644 core/src/ch/asynk/gdx/boardgame/Touchable.java create mode 100644 core/src/ch/asynk/gdx/boardgame/board/BoardFactory.java create mode 100644 core/src/ch/asynk/gdx/boardgame/board/HexBoard.java create mode 100644 core/src/ch/asynk/gdx/boardgame/board/SquareBoard.java create mode 100644 core/src/ch/asynk/gdx/boardgame/board/TriangleBoard.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Alignment.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Assembly.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Button.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Element.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Label.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Menu.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Patch.java create mode 100644 core/src/ch/asynk/gdx/boardgame/ui/Root.java create mode 100644 core/src/ch/asynk/gdx/boardgame/util/Collection.java create mode 100644 core/src/ch/asynk/gdx/boardgame/util/IterableArray.java create mode 100644 core/src/ch/asynk/gdx/boardgame/util/IterableQueue.java create mode 100644 core/src/ch/asynk/gdx/boardgame/util/IterableSet.java create mode 100644 core/src/ch/asynk/gdx/boardgame/util/IterableStack.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/Assets.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/Board.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/Camera.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/Drawable.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/Touchable.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/board/BoardFactory.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/board/HexBoard.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/board/SquareBoard.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/board/TriangleBoard.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Alignment.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Assembly.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Button.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Element.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Label.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Menu.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Patch.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/ui/Root.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/util/Collection.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/util/IterableArray.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/util/IterableQueue.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/util/IterableSet.java delete mode 100644 core/src/ch/asynk/gdx/tabletop/util/IterableStack.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/AbstractScreen.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/Assets.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/BoardScreen.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/DesktopLauncher.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/GdxBoardTest.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/LoadingScreen.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/MenuScreen.java create mode 100644 test/src/ch/asynk/gdx/boardgame/test/UiScreen.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/AbstractScreen.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/Assets.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/BoardScreen.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/DesktopLauncher.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/GdxBoardTest.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/LoadingScreen.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/MenuScreen.java delete mode 100644 test/src/ch/asynk/gdx/tabletop/test/UiScreen.java diff --git a/build.gradle b/build.gradle index cf09827..090f805 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ allprojects { version = '1.0' ext { - appName = "gdx-tabletop" + appName = "gdx-boardgame" gdxVersion = '1.9.8' } diff --git a/core/src/ch/asynk/gdx/boardgame/Assets.java b/core/src/ch/asynk/gdx/boardgame/Assets.java new file mode 100644 index 0000000..3402430 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/Assets.java @@ -0,0 +1,30 @@ +package ch.asynk.gdx.boardgame; + +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; + +public class Assets extends AssetManager +{ + public Texture getTexture(String assetName) + { + return get(assetName, Texture.class); + } + + public NinePatch getNinePatch(String assetName, int left, int right, int top, int bottom) + { + return new NinePatch(get(assetName, Texture.class), left, right, top, bottom); + } + + public TextureAtlas getAtlas(String assetName) + { + return get(assetName, TextureAtlas.class); + } + + public BitmapFont getFont(String assetName) + { + return get(assetName, BitmapFont.class); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/Board.java b/core/src/ch/asynk/gdx/boardgame/Board.java new file mode 100644 index 0000000..b1d82d0 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/Board.java @@ -0,0 +1,9 @@ +package ch.asynk.gdx.boardgame; + +import com.badlogic.gdx.math.Vector2; + +public interface Board +{ + public void centerOf(int x, int y, Vector2 v); + public void toBoard(float x, float y, Vector2 v); +} diff --git a/core/src/ch/asynk/gdx/boardgame/Camera.java b/core/src/ch/asynk/gdx/boardgame/Camera.java new file mode 100644 index 0000000..5140538 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/Camera.java @@ -0,0 +1,223 @@ +package ch.asynk.gdx.boardgame; + +import com.badlogic.gdx.graphics.glutils.HdpiUtils; +import com.badlogic.gdx.graphics.OrthographicCamera; + +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Matrix4; + +public class Camera extends OrthographicCamera +{ + private static final float ZEROF = 0.01f; + + private int padding; + private float boardWidth; + private float boardHeight; + private float boardAspectRatio; + private float zoomMax; + private float zoomMin; + private int screenWidth; + private int screenHeight; + private float widthFactor; + private float heightFactor; + private Rectangle viewport; + + private Rectangle hud; + private Matrix4 hudMatrix; + private Matrix4 hudInvProjMatrix; + private int hudLeft; + private int hudBottom; + private boolean hudInBoard; + + public Camera(int padding, float boardWidth, float boardHeight, float zoomMax, float zoomMin, boolean hudInBoard) + { + super(boardWidth, boardHeight); + this.boardWidth = boardWidth; + this.boardHeight = boardHeight; + this.padding = padding; + this.boardAspectRatio = (boardWidth / boardHeight); + this.zoomMax = zoomMax; + this.zoomMin = zoomMin; + this.viewport = new Rectangle(); + + this.hudInBoard = hudInBoard; + this.hud = new Rectangle(); + this.hudMatrix = new Matrix4(); + this.hudInvProjMatrix = new Matrix4(); + } + + public void setDimension(float boardWidth, float boardHeight) + { + setToOrtho(false, boardWidth, boardHeight); + this.boardWidth = boardWidth; + this.boardHeight = boardHeight; + this.boardAspectRatio = (boardWidth / boardHeight); + } + + public void updateViewport(int screenWidth, int screenHeight) + { + this.screenWidth = screenWidth; + this.screenHeight = screenHeight; + + float screenAvailableWidth = screenWidth - (2 * padding); + float screenAvailableHeight = screenHeight - (2 * padding); + float screenAspectRatio = (screenWidth / (float) screenHeight); + float diff = (boardAspectRatio - screenAspectRatio); + + if (diff <= -ZEROF) { + // screen wider than board : use max height, width grows up until max available on zooming + viewport.height = screenAvailableHeight; + viewport.width = java.lang.Math.min((screenAvailableHeight * boardAspectRatio / zoom), screenAvailableWidth); + viewport.x = padding + ((screenAvailableWidth - viewport.width) / 2f); + viewport.y = padding; + // camera aspect ratio must follow viewport aspect ration + viewportHeight = boardHeight; + viewportWidth = (viewportHeight * (viewport.width / viewport.height)); + // hud + hud.y = 0; + hud.x = (hud.y * viewportWidth / viewportHeight); + } else if (diff > ZEROF) { + // word is wider than screen : use max width, height grows up until max available on zooming + viewport.width = screenAvailableWidth; + viewport.height = java.lang.Math.min((screenAvailableWidth / boardAspectRatio / zoom), screenAvailableHeight); + viewport.y = padding + ((screenAvailableHeight - viewport.height) / 2f); + viewport.x = padding; + // camera aspect ratio must follow viewport aspect ration + viewportWidth = boardWidth; + viewportHeight = (viewportWidth * (viewport.height / viewport.width)); + // hud + hud.x = 0; + hud.y = (hud.x * viewportHeight / viewportWidth); + } + + if (hudInBoard) { + hud.width = (viewport.width - (2 * hud.x)); + hud.height = (viewport.height - (2 * hud.y)); + } else { + hud.x = 0; + hud.y = 0; + hud.width = screenWidth; + hud.height = screenHeight; + } + + // ratio viewport -> camera + widthFactor = (viewportWidth / viewport.width); + heightFactor = (viewportHeight / viewport.height); + + clampPosition(); + update(true); + + hudMatrix.setToOrtho2D(hud.x, hud.y, hud.width, hud.height); + hudInvProjMatrix.set(hudMatrix); + Matrix4.inv(hudInvProjMatrix.val); + } + + public void applyScreenViewport() + { + HdpiUtils.glViewport(0, 0, screenWidth, screenHeight); + } + + public void applyBoardViewport() + { + HdpiUtils.glViewport((int)viewport.x, (int)viewport.y, (int)viewport.width, (int)viewport.height); + } + + public void applyHudViewport() + { + if (hudInBoard) + applyBoardViewport(); + else + applyScreenViewport(); + } + + public void centerOnWorld() + { + position.set((boardWidth / 2f), (boardHeight / 2f), 0f); + } + + public void zoom(float dz) + { + zoom += dz; + clampZoom(); + } + + public void clampZoom() + { + zoom = MathUtils.clamp(zoom, zoomMin, zoomMax); + } + + public void translate(float dx, float dy) + { + float deltaX = (dx * zoom * widthFactor); + float deltaY = (dy * zoom * heightFactor); + translate(deltaX, -deltaY, 0); + clampPosition(); + update(true); + } + + public void clampPosition() + { + float cameraWidth = (viewportWidth * zoom); + float cameraHeight = (viewportHeight * zoom); + + // on each axis, clamp on [ cameraDim/2 ; boardDim - cameraDim/2 ] + + if ((boardWidth - cameraWidth) > ZEROF) { + cameraWidth /= 2f; + position.x = MathUtils.clamp(position.x, cameraWidth, (boardWidth - cameraWidth)); + } else { + position.x = (boardWidth / 2f); + } + + if ((boardHeight - cameraHeight) > ZEROF) { + cameraHeight /= 2f; + position.y = MathUtils.clamp(position.y, cameraHeight, (boardHeight - cameraHeight)); + } else { + position.y = (boardHeight / 2f); + } + } + + public void unproject(int x, int y, Vector3 v) + { + unproject(v.set(x, y, 0), viewport.x, viewport.y, viewport.width, viewport.height); + } + + public void unprojectHud(float x, float y, Vector3 v) + { + Rectangle r = (hudInBoard ? viewport : hud); + x = x - r.x; + y = screenHeight - y - 1; + y = y - r.y; + v.x = (2 * x) / r.width - 1; + v.y = (2 * y) / r.height - 1; + v.z = 2 * v.z - 1; + v.prj(hudInvProjMatrix); + } + + public int getScreenWidth() + { + return screenWidth; + } + + public int getScreenHeight() + { + return screenHeight; + } + + public Matrix4 getHudMatrix() + { + return hudMatrix; + } + + public Rectangle getViewport() + { + return viewport; + } + + public Rectangle getHud() + { + return hud; + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/Drawable.java b/core/src/ch/asynk/gdx/boardgame/Drawable.java new file mode 100644 index 0000000..618d6a2 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/Drawable.java @@ -0,0 +1,19 @@ +package ch.asynk.gdx.boardgame; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +public interface Drawable +{ + public float getX(); + public float getY(); + public float getWidth(); + public float getHeight(); + public float getInnerX(); + public float getInnerY(); + public float getInnerWidth(); + public float getInnerHeight(); + public void draw(Batch batch); + default public void drawDebug(ShapeRenderer debugShapes) { } + public void setPosition(float x, float y, float w, float h); +} diff --git a/core/src/ch/asynk/gdx/boardgame/Touchable.java b/core/src/ch/asynk/gdx/boardgame/Touchable.java new file mode 100644 index 0000000..0fd99d0 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/Touchable.java @@ -0,0 +1,6 @@ +package ch.asynk.gdx.boardgame; + +public interface Touchable +{ + public boolean touch(float x, float y); +} 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); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Alignment.java b/core/src/ch/asynk/gdx/boardgame/ui/Alignment.java new file mode 100644 index 0000000..67da089 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Alignment.java @@ -0,0 +1,168 @@ +package ch.asynk.gdx.boardgame.ui; + +public enum Alignment +{ + ABSOLUTE, // Root + RELATIVE, // Default + TOP_LEFT, + TOP_RIGHT, + TOP_CENTER, + MIDDLE_LEFT, + MIDDLE_RIGHT, + MIDDLE_CENTER, + BOTTOM_LEFT, + BOTTOM_RIGHT, + BOTTOM_CENTER; + + public Alignment verticalMirror() + { + switch(this) { + case TOP_LEFT: + return TOP_RIGHT; + case MIDDLE_LEFT: + return MIDDLE_RIGHT; + case BOTTOM_LEFT: + return BOTTOM_RIGHT; + case TOP_RIGHT: + return TOP_LEFT; + case MIDDLE_RIGHT: + return MIDDLE_LEFT; + case BOTTOM_RIGHT: + return BOTTOM_LEFT; + } + return this; + } + + public Alignment horizontalMirror() + { + switch(this) { + case TOP_LEFT: + return BOTTOM_LEFT; + case TOP_CENTER: + return BOTTOM_CENTER; + case TOP_RIGHT: + return BOTTOM_RIGHT; + case BOTTOM_LEFT: + return TOP_LEFT; + case BOTTOM_CENTER: + return TOP_CENTER; + case BOTTOM_RIGHT: + return TOP_RIGHT; + } + return this; + } + + public boolean isTop() + { + switch(this) { + case TOP_LEFT: + case TOP_CENTER: + case TOP_RIGHT: + return true; + } + return false; + } + + public boolean isMiddle() + { + boolean r = false; + switch(this) { + case MIDDLE_LEFT: + case MIDDLE_CENTER: + case MIDDLE_RIGHT: + return true; + } + return false; + } + + public boolean isBottom() + { + boolean r = false; + switch(this) { + case BOTTOM_LEFT: + case BOTTOM_CENTER: + case BOTTOM_RIGHT: + return true; + } + return false; + } + + public boolean isLeft() + { + boolean r = false; + switch(this) { + case TOP_LEFT: + case MIDDLE_LEFT: + case BOTTOM_LEFT: + return true; + } + return false; + } + + public boolean isRight() + { + boolean r = false; + switch(this) { + case TOP_RIGHT: + case MIDDLE_RIGHT: + case BOTTOM_RIGHT: + return true; + } + return false; + } + + public boolean isCenter() + { + switch(this) { + case TOP_CENTER: + case MIDDLE_CENTER: + case BOTTOM_CENTER: + return true; + } + return false; + } + + public float getX(Element element, float width) + { + float x = element.getInnerX(); + switch(this) { + case TOP_LEFT: + case MIDDLE_LEFT: + case BOTTOM_LEFT: + break; + case TOP_CENTER: + case MIDDLE_CENTER: + case BOTTOM_CENTER: + x += ((element.getInnerWidth() - width) / 2); + break; + case TOP_RIGHT: + case MIDDLE_RIGHT: + case BOTTOM_RIGHT: + x += (element.getInnerWidth() - width); + break; + } + return x; + } + + public float getY(Element element, float height) + { + float y = element.getInnerY(); + switch(this) { + case TOP_LEFT: + case TOP_CENTER: + case TOP_RIGHT: + y += (element.getInnerHeight() - height); + break; + case MIDDLE_LEFT: + case MIDDLE_CENTER: + case MIDDLE_RIGHT: + y += ((element.getInnerHeight() - height) / 2); + break; + case BOTTOM_LEFT: + case BOTTOM_CENTER: + case BOTTOM_RIGHT: + break; + } + return y; + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Assembly.java b/core/src/ch/asynk/gdx/boardgame/ui/Assembly.java new file mode 100644 index 0000000..c603383 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Assembly.java @@ -0,0 +1,63 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.gdx.boardgame.util.IterableSet; + +public abstract class Assembly extends Element +{ + private IterableSet children; + private Element touched; + + public Assembly(int c) + { + this.children = new IterableSet(c); + } + + public void add(Element e) + { + if (children.add(e)) { + e.setParent(this); + } + } + + public void remove(Element e) + { + if (children.remove(e)) { + e.setParent(null); + } + } + + public Element touched() + { + return touched; + } + + @Override public boolean touch(float x, float y) + { + for (Element e : children) + if (e.touch(x, y)) { + touched = e; + return true; + } + touched = null; + return false; + } + + @Override public void taint() + { + children.forEach( c -> c.taint() ); + } + + @Override public void draw(Batch batch) + { + if (tainted) computeGeometry(); + children.forEach( c -> c.draw(batch) ); + } + + @Override public void drawDebug(ShapeRenderer debugShapes) + { + children.forEach( c -> c.drawDebug(debugShapes) ); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Button.java b/core/src/ch/asynk/gdx/boardgame/ui/Button.java new file mode 100644 index 0000000..9bc1149 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Button.java @@ -0,0 +1,67 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +public class Button extends Patch +{ + private Label label; + private float spacing; // for label alignment; + + public Button(BitmapFont font, NinePatch patch) + { + this(font, patch, 0); + } + + public Button(BitmapFont font, NinePatch patch, float padding) + { + this(font, patch, padding, 0); + } + + public Button(BitmapFont font, NinePatch patch, float padding, float spacing) + { + super(patch); + this.padding = padding; + this.spacing = spacing; + label = new Label(font); + label.setParent(this); + label.setAlignment(Alignment.MIDDLE_CENTER); + } + + public void write(String text) + { + label.write(text); + this.tainted = true; // might impact Button's geometry + } + + public void setLabelAlignment(Alignment alignment) + { + label.setAlignment(alignment); + } + + @Override public void computeGeometry() + { + float dd = 2 * (padding + spacing); + label.computeGeometry(); // update dimensions + rect.width = label.getWidth() + dd; + rect.height = label.getHeight() + dd; + super.computeGeometry(); + label.computeGeometry(); // update position + } + + @Override public void draw(Batch batch) + { + if (!visible) return; + if (tainted) computeGeometry(); + super.draw(batch); + label.draw(batch); + } + + @Override public void drawDebug(ShapeRenderer debugShapes) + { + super.drawDebug(debugShapes); + label.drawDebug(debugShapes); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Element.java b/core/src/ch/asynk/gdx/boardgame/ui/Element.java new file mode 100644 index 0000000..25f38eb --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Element.java @@ -0,0 +1,116 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.Rectangle; + +import ch.asynk.gdx.boardgame.Drawable; +import ch.asynk.gdx.boardgame.Touchable; + +public abstract class Element implements Drawable, Touchable +{ + public boolean blocked; + public boolean visible; + protected float padding; + protected Element parent; + protected Alignment alignment; + protected Rectangle rect; // outer drawing coordinates + protected float x, y; // given position + protected boolean tainted; // geometry must be computed + + protected Element() + { + this.blocked = false; + this.visible = true; + this.padding = 0; + this.parent = null; + this.alignment = alignment.RELATIVE; + this.rect = new Rectangle(0, 0, 0, 0); + this.x = this.y = 0; + this.tainted = true; + } + + @Override public final float getX() { return rect.x; } + @Override public final float getY() { return rect.y; } + @Override public final float getWidth() { return rect.width; } + @Override public final float getHeight() { return rect.height; } + + @Override public final float getInnerX() { return rect.x + padding; } + @Override public final float getInnerY() { return rect.y + padding; } + @Override public final float getInnerWidth() { return rect.width - 2 * padding; } + @Override public final float getInnerHeight() { return rect.height - 2 * padding; } + + @Override public void drawDebug(ShapeRenderer debugShapes) + { + debugShapes.rect(getX(), getY(), getWidth(), getHeight()); + } + + @Override public boolean touch(float x, float y) + { + if (blocked || !visible) return false; + return rect.contains(x, y); + } + + public void taint() + { + this.tainted = true; + } + + @Override public void setPosition(float x, float y, float w, float h) + { + this.x = x; + this.y = y; + this.rect.width = w; + this.rect.height = h; + this.tainted = true; + // rect.(x,y) will be set in computeGeometry + } + + public void setParent(Element parent) + { + this.parent = parent; + this.tainted = true; + } + + public void setPadding(float padding) + { + this.padding = padding; + this.tainted = true; + } + + public void setAlignment(Alignment alignment) + { + this.alignment = alignment; + this.tainted = true; + } + + public final void translate(float dx, float dy) + { + setPosition(x + dx, y + dy); + } + + public final void setPosition(Rectangle r) + { + setPosition(r.x, r.x, r.width, r.height); + } + + public final void setPosition(float x, float y) + { + setPosition(x, y, rect.width, rect.height); + } + + protected void computeGeometry() + { + if (alignment == Alignment.ABSOLUTE || parent == null) { + rect.x = x; + rect.y = y; + } else if (alignment == Alignment.RELATIVE) { + rect.x = x + parent.getInnerX(); + rect.y = y + parent.getInnerX(); + } else { + rect.x = x + alignment.getX(parent, rect.width); + rect.y = y + alignment.getY(parent, rect.height); + } + this.tainted = false; + // System.err.println(String.format("%s : %s", this, rect)); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Label.java b/core/src/ch/asynk/gdx/boardgame/ui/Label.java new file mode 100644 index 0000000..32ae814 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Label.java @@ -0,0 +1,61 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; + +public class Label extends Element +{ + private BitmapFont font; + private GlyphLayout layout; + private float fx; + private float fy; + private String text; + + public Label(BitmapFont font) + { + this(font, 0); + } + + public Label(BitmapFont font, float padding) + { + this(font, padding, Alignment.RELATIVE); + } + + public Label(BitmapFont font, float padding, Alignment alignment) + { + super(); + this.font = font; + this.padding = padding; + this.alignment = alignment; + this.layout = new GlyphLayout(); + } + + public void write(String text) + { + write(text, getX(), getY()); + } + + public void write(String text, float x, float y) + { + this.text = text; + this.layout.setText(font, (text == null) ? "" : text); + this.tainted = true; + } + + @Override protected void computeGeometry() + { + this.rect.width = (layout.width + (2 * padding)); + this.rect.height = (layout.height + (2 * padding)); + super.computeGeometry(); + fx = getInnerX(); + fy = getInnerY() + layout.height; + } + + @Override public void draw(Batch batch) + { + if (!visible) return; + if (tainted) computeGeometry(); + font.draw(batch, layout, fx, fy); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Menu.java b/core/src/ch/asynk/gdx/boardgame/ui/Menu.java new file mode 100644 index 0000000..aa62483 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Menu.java @@ -0,0 +1,126 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; + +public class Menu extends Patch +{ + private Label title; + private Label[] entries; + private Integer touchedItem; + + private int entriesOffset; // horizontal offset + private int titleSpacing; // between title and entries + private int entriesSpacing; // between entries + + public Menu(BitmapFont font, NinePatch patch, String title, String[] entries) + { + super(patch); + this.touchedItem = null; + setTitle(font, title); + setEntries(font, entries); + } + + public void setTitle(BitmapFont font, String title) + { + this.title = new Label(font); + this.title.write(title); + this.tainted = true; + } + + public void setEntries(BitmapFont font, String[] entries) + { + this.entries = new Label[entries.length]; + for (int i = 0; i < entries.length; i++) { + Label l = new Label(font); + l.write(entries[i]); + this.entries[i] = l; + } + this.tainted = true; + } + + public void setLabelsOffset(int entriesOffset) + { + this.entriesOffset = entriesOffset; + this.tainted = true; + } + + public void setPaddings(int titlePadding, int labelPadding) + { + this.title.setPadding(titlePadding); + for (Label label : entries) { + label.setPadding(labelPadding); + } + this.tainted = true; + } + + public void setSpacings(int titleSpacing, int entriesSpacing) + { + this.titleSpacing = titleSpacing; + this.entriesSpacing = entriesSpacing; + this.tainted = true; + } + + @Override public void computeGeometry() + { + title.computeGeometry(); + float h = title.getHeight(); + float w = title.getWidth(); + for (Label label : entries) { + label.computeGeometry(); + h += label.getHeight(); + float t = label.getWidth() + entriesOffset; + if (t > w) + w = t; + } + h += (titleSpacing + (entriesSpacing * (entries.length - 1)) + (2 * padding)); + w += (2 * padding); + + rect.width = w; + rect.height = h; + super.computeGeometry(); + + float x = getInnerX(); + float y = getInnerY(); + + // setPosition() will trigger computeGeometry() from within draw() + for (int i = entries.length - 1; i >= 0; i--) { + entries[i].setPosition(x + entriesOffset, y); + y += entries[i].getHeight() + entriesSpacing; + } + y -= entriesSpacing; + y += titleSpacing; + title.setPosition(x, y); + } + + public Integer touched() + { + return touchedItem; + } + + @Override public boolean touch(float x, float y) + { + touchedItem = null; + if (super.touch(x, y)) { + for (int i = 0; i < entries.length; i++) { + if (entries[i].touch(x, y)) { + touchedItem = i; + return true; + } + } + } + return false; + } + + @Override public void draw(Batch batch) + { + if (!visible) return; + if (tainted) computeGeometry(); + super.draw(batch); + title.draw(batch); + for (Label label : entries) { + label.draw(batch); + } + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Patch.java b/core/src/ch/asynk/gdx/boardgame/ui/Patch.java new file mode 100644 index 0000000..df2cc06 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Patch.java @@ -0,0 +1,23 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.NinePatch; + +public class Patch extends Element +{ + private NinePatch patch; + + public Patch(NinePatch patch) + { + super(); + this.patch = patch; + setPosition(0, 0, patch.getTotalWidth(), patch.getTotalHeight()); + } + + @Override public void draw(Batch batch) + { + if (!visible) return; + if (tainted) computeGeometry(); + patch.draw(batch, getX(), getY(), getWidth(), getHeight()); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Root.java b/core/src/ch/asynk/gdx/boardgame/ui/Root.java new file mode 100644 index 0000000..2353c41 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Root.java @@ -0,0 +1,28 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.math.Rectangle; + +public class Root extends Assembly +{ + public Root(int c) + { + super(c); + this.alignment = Alignment.ABSOLUTE; + } + + public void resize(Rectangle r) + { + resize(r.x, r.y, r.width, r.height); + } + + public void resize(float width, float height) + { + resize(getX(), getY(), width, height); + } + + public void resize(float x, float y, float width, float height) + { + setPosition(x, y, width, height); + taint(); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/util/Collection.java b/core/src/ch/asynk/gdx/boardgame/util/Collection.java new file mode 100644 index 0000000..1d7d5e4 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/util/Collection.java @@ -0,0 +1,28 @@ +package ch.asynk.gdx.boardgame.util; + +import java.util.Iterator; + +public interface Collection extends Iterator, Iterable +{ + public int size(); + + public boolean isEmpty(); + + public void clear(); + + public void ensureCapacity(int c); + + public boolean contains(E e); + + public E get(int idx); + + public int indexOf(E e); + + public boolean add(E e); + + public boolean insert(E e, int idx); + + public E remove(int idx); + + public boolean remove(E e); +} diff --git a/core/src/ch/asynk/gdx/boardgame/util/IterableArray.java b/core/src/ch/asynk/gdx/boardgame/util/IterableArray.java new file mode 100644 index 0000000..ba57de1 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/util/IterableArray.java @@ -0,0 +1,143 @@ +package ch.asynk.gdx.boardgame.util; + +import java.util.Arrays; +import java.util.Iterator; + +public class IterableArray implements Collection +{ + private int idx; + private int s; + private int c; + transient E[] data; + + @SuppressWarnings("unchecked") + public IterableArray(int capacity) + { + this.s = 0; + this.c = capacity; + this.data = (E[]) new Object[c]; + } + + @Override public int size() + { + return s; + } + + @Override public boolean isEmpty() + { + return (s == 0); + } + + @Override public void clear() + { + for (int i = 0; i < s; i++) + data[i] = null; + s = 0; + } + + @Override public void ensureCapacity(int min) + { + if (c > min) return; + c += (c >> 1); + if (c < min) + c = min; + data = Arrays.copyOf(data, c); + } + + @Override public boolean contains(E e) + { + if (e == null) { + for (int i = 0; i < s; i++) { + if (data[i] == null) + return true; + } + } else { + for (int i = 0; i < s; i++) { + if (e.equals(data[i])) + return true; + } + } + return false; + } + + @Override public E get(int i) + { + return data[i]; + } + + @Override public int indexOf(E e) + { + for (int i = 0; i < data.length; i++) { + if (data[i] != null && data[i].equals(e)) + return i; + } + return -1; + } + + @Override public boolean add(E e) + { + ensureCapacity(s + 1); + data[s] = e; + s += 1; + return true; + } + + @Override public boolean insert(E e, int idx) + { + ensureCapacity(s + 1); + System.arraycopy(data, idx, data, idx+1, (s - idx)); + data[idx] = e; + s += 1; + return true; + } + + @Override public E remove(int i) + { + E e = data[i]; + int m = (s - i - 1); + if (m > 0) + System.arraycopy(data, i+1, data, i, m); + data[--s] = null; + + return e; + } + + @Override public boolean remove(E e) + { + for (int i = 0; i < s; i++) { + if (e.equals(data[i])) { + int m = (s - i - 1); + if (m > 0) + System.arraycopy(data, i+1, data, i, m); + data[--s] = null; + return true; + } + } + return false; + } + + @SuppressWarnings("unchecked") + @Override public Iterator iterator() + { + this.idx = 0; + return (Iterator) this; + } + + @Override public boolean hasNext() + { + return (idx < s); + } + + @Override public E next() + { + E e = get(idx); + idx += 1; + return e; + } + + @Override public void remove() + { + idx -= 1; + remove(idx); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/util/IterableQueue.java b/core/src/ch/asynk/gdx/boardgame/util/IterableQueue.java new file mode 100644 index 0000000..16ab442 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/util/IterableQueue.java @@ -0,0 +1,19 @@ +package ch.asynk.gdx.boardgame.util; + +public class IterableQueue extends IterableArray +{ + public IterableQueue(int n) + { + super(n); + } + + public void enqueue(E e) + { + add(e); + } + + public E dequeue() + { + return remove(0); + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/util/IterableSet.java b/core/src/ch/asynk/gdx/boardgame/util/IterableSet.java new file mode 100644 index 0000000..4132771 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/util/IterableSet.java @@ -0,0 +1,16 @@ +package ch.asynk.gdx.boardgame.util; + +public class IterableSet extends IterableArray +{ + public IterableSet(int n) + { + super(n); + } + + @Override public boolean add(E e) + { + if (contains(e)) return false; + super.add(e); + return true; + } +} diff --git a/core/src/ch/asynk/gdx/boardgame/util/IterableStack.java b/core/src/ch/asynk/gdx/boardgame/util/IterableStack.java new file mode 100644 index 0000000..7400718 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/util/IterableStack.java @@ -0,0 +1,26 @@ +package ch.asynk.gdx.boardgame.util; + +public class IterableStack extends IterableArray +{ + public IterableStack(int n) + { + super(n); + } + + public void push(E e) + { + add(e); + } + + public E pop() + { + if (size() <= 0) return null; + return remove(size() - 1); + } + + public E getTop() + { + if (size() <= 0) return null; + return get(size() - 1); + } +} diff --git a/core/src/ch/asynk/gdx/tabletop/Assets.java b/core/src/ch/asynk/gdx/tabletop/Assets.java deleted file mode 100644 index 4b4382d..0000000 --- a/core/src/ch/asynk/gdx/tabletop/Assets.java +++ /dev/null @@ -1,30 +0,0 @@ -package ch.asynk.gdx.tabletop; - -import com.badlogic.gdx.assets.AssetManager; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.NinePatch; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; - -public class Assets extends AssetManager -{ - public Texture getTexture(String assetName) - { - return get(assetName, Texture.class); - } - - public NinePatch getNinePatch(String assetName, int left, int right, int top, int bottom) - { - return new NinePatch(get(assetName, Texture.class), left, right, top, bottom); - } - - public TextureAtlas getAtlas(String assetName) - { - return get(assetName, TextureAtlas.class); - } - - public BitmapFont getFont(String assetName) - { - return get(assetName, BitmapFont.class); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/Board.java b/core/src/ch/asynk/gdx/tabletop/Board.java deleted file mode 100644 index 5af948e..0000000 --- a/core/src/ch/asynk/gdx/tabletop/Board.java +++ /dev/null @@ -1,9 +0,0 @@ -package ch.asynk.gdx.tabletop; - -import com.badlogic.gdx.math.Vector2; - -public interface Board -{ - public void centerOf(int x, int y, Vector2 v); - public void toBoard(float x, float y, Vector2 v); -} diff --git a/core/src/ch/asynk/gdx/tabletop/Camera.java b/core/src/ch/asynk/gdx/tabletop/Camera.java deleted file mode 100644 index 39c04b9..0000000 --- a/core/src/ch/asynk/gdx/tabletop/Camera.java +++ /dev/null @@ -1,223 +0,0 @@ -package ch.asynk.gdx.tabletop; - -import com.badlogic.gdx.graphics.glutils.HdpiUtils; -import com.badlogic.gdx.graphics.OrthographicCamera; - -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.math.Matrix4; - -public class Camera extends OrthographicCamera -{ - private static final float ZEROF = 0.01f; - - private int padding; - private float boardWidth; - private float boardHeight; - private float boardAspectRatio; - private float zoomMax; - private float zoomMin; - private int screenWidth; - private int screenHeight; - private float widthFactor; - private float heightFactor; - private Rectangle viewport; - - private Rectangle hud; - private Matrix4 hudMatrix; - private Matrix4 hudInvProjMatrix; - private int hudLeft; - private int hudBottom; - private boolean hudInBoard; - - public Camera(int padding, float boardWidth, float boardHeight, float zoomMax, float zoomMin, boolean hudInBoard) - { - super(boardWidth, boardHeight); - this.boardWidth = boardWidth; - this.boardHeight = boardHeight; - this.padding = padding; - this.boardAspectRatio = (boardWidth / boardHeight); - this.zoomMax = zoomMax; - this.zoomMin = zoomMin; - this.viewport = new Rectangle(); - - this.hudInBoard = hudInBoard; - this.hud = new Rectangle(); - this.hudMatrix = new Matrix4(); - this.hudInvProjMatrix = new Matrix4(); - } - - public void setDimension(float boardWidth, float boardHeight) - { - setToOrtho(false, boardWidth, boardHeight); - this.boardWidth = boardWidth; - this.boardHeight = boardHeight; - this.boardAspectRatio = (boardWidth / boardHeight); - } - - public void updateViewport(int screenWidth, int screenHeight) - { - this.screenWidth = screenWidth; - this.screenHeight = screenHeight; - - float screenAvailableWidth = screenWidth - (2 * padding); - float screenAvailableHeight = screenHeight - (2 * padding); - float screenAspectRatio = (screenWidth / (float) screenHeight); - float diff = (boardAspectRatio - screenAspectRatio); - - if (diff <= -ZEROF) { - // screen wider than board : use max height, width grows up until max available on zooming - viewport.height = screenAvailableHeight; - viewport.width = java.lang.Math.min((screenAvailableHeight * boardAspectRatio / zoom), screenAvailableWidth); - viewport.x = padding + ((screenAvailableWidth - viewport.width) / 2f); - viewport.y = padding; - // camera aspect ratio must follow viewport aspect ration - viewportHeight = boardHeight; - viewportWidth = (viewportHeight * (viewport.width / viewport.height)); - // hud - hud.y = 0; - hud.x = (hud.y * viewportWidth / viewportHeight); - } else if (diff > ZEROF) { - // word is wider than screen : use max width, height grows up until max available on zooming - viewport.width = screenAvailableWidth; - viewport.height = java.lang.Math.min((screenAvailableWidth / boardAspectRatio / zoom), screenAvailableHeight); - viewport.y = padding + ((screenAvailableHeight - viewport.height) / 2f); - viewport.x = padding; - // camera aspect ratio must follow viewport aspect ration - viewportWidth = boardWidth; - viewportHeight = (viewportWidth * (viewport.height / viewport.width)); - // hud - hud.x = 0; - hud.y = (hud.x * viewportHeight / viewportWidth); - } - - if (hudInBoard) { - hud.width = (viewport.width - (2 * hud.x)); - hud.height = (viewport.height - (2 * hud.y)); - } else { - hud.x = 0; - hud.y = 0; - hud.width = screenWidth; - hud.height = screenHeight; - } - - // ratio viewport -> camera - widthFactor = (viewportWidth / viewport.width); - heightFactor = (viewportHeight / viewport.height); - - clampPosition(); - update(true); - - hudMatrix.setToOrtho2D(hud.x, hud.y, hud.width, hud.height); - hudInvProjMatrix.set(hudMatrix); - Matrix4.inv(hudInvProjMatrix.val); - } - - public void applyScreenViewport() - { - HdpiUtils.glViewport(0, 0, screenWidth, screenHeight); - } - - public void applyBoardViewport() - { - HdpiUtils.glViewport((int)viewport.x, (int)viewport.y, (int)viewport.width, (int)viewport.height); - } - - public void applyHudViewport() - { - if (hudInBoard) - applyBoardViewport(); - else - applyScreenViewport(); - } - - public void centerOnWorld() - { - position.set((boardWidth / 2f), (boardHeight / 2f), 0f); - } - - public void zoom(float dz) - { - zoom += dz; - clampZoom(); - } - - public void clampZoom() - { - zoom = MathUtils.clamp(zoom, zoomMin, zoomMax); - } - - public void translate(float dx, float dy) - { - float deltaX = (dx * zoom * widthFactor); - float deltaY = (dy * zoom * heightFactor); - translate(deltaX, -deltaY, 0); - clampPosition(); - update(true); - } - - public void clampPosition() - { - float cameraWidth = (viewportWidth * zoom); - float cameraHeight = (viewportHeight * zoom); - - // on each axis, clamp on [ cameraDim/2 ; boardDim - cameraDim/2 ] - - if ((boardWidth - cameraWidth) > ZEROF) { - cameraWidth /= 2f; - position.x = MathUtils.clamp(position.x, cameraWidth, (boardWidth - cameraWidth)); - } else { - position.x = (boardWidth / 2f); - } - - if ((boardHeight - cameraHeight) > ZEROF) { - cameraHeight /= 2f; - position.y = MathUtils.clamp(position.y, cameraHeight, (boardHeight - cameraHeight)); - } else { - position.y = (boardHeight / 2f); - } - } - - public void unproject(int x, int y, Vector3 v) - { - unproject(v.set(x, y, 0), viewport.x, viewport.y, viewport.width, viewport.height); - } - - public void unprojectHud(float x, float y, Vector3 v) - { - Rectangle r = (hudInBoard ? viewport : hud); - x = x - r.x; - y = screenHeight - y - 1; - y = y - r.y; - v.x = (2 * x) / r.width - 1; - v.y = (2 * y) / r.height - 1; - v.z = 2 * v.z - 1; - v.prj(hudInvProjMatrix); - } - - public int getScreenWidth() - { - return screenWidth; - } - - public int getScreenHeight() - { - return screenHeight; - } - - public Matrix4 getHudMatrix() - { - return hudMatrix; - } - - public Rectangle getViewport() - { - return viewport; - } - - public Rectangle getHud() - { - return hud; - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/Drawable.java b/core/src/ch/asynk/gdx/tabletop/Drawable.java deleted file mode 100644 index ce9372b..0000000 --- a/core/src/ch/asynk/gdx/tabletop/Drawable.java +++ /dev/null @@ -1,19 +0,0 @@ -package ch.asynk.gdx.tabletop; - -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; - -public interface Drawable -{ - public float getX(); - public float getY(); - public float getWidth(); - public float getHeight(); - public float getInnerX(); - public float getInnerY(); - public float getInnerWidth(); - public float getInnerHeight(); - public void draw(Batch batch); - default public void drawDebug(ShapeRenderer debugShapes) { } - public void setPosition(float x, float y, float w, float h); -} diff --git a/core/src/ch/asynk/gdx/tabletop/Touchable.java b/core/src/ch/asynk/gdx/tabletop/Touchable.java deleted file mode 100644 index 54ac6e2..0000000 --- a/core/src/ch/asynk/gdx/tabletop/Touchable.java +++ /dev/null @@ -1,6 +0,0 @@ -package ch.asynk.gdx.tabletop; - -public interface Touchable -{ - public boolean touch(float x, float y); -} diff --git a/core/src/ch/asynk/gdx/tabletop/board/BoardFactory.java b/core/src/ch/asynk/gdx/tabletop/board/BoardFactory.java deleted file mode 100644 index e3d6195..0000000 --- a/core/src/ch/asynk/gdx/tabletop/board/BoardFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -package ch.asynk.gdx.tabletop.board; - -import ch.asynk.gdx.tabletop.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/tabletop/board/HexBoard.java b/core/src/ch/asynk/gdx/tabletop/board/HexBoard.java deleted file mode 100644 index 0fd8871..0000000 --- a/core/src/ch/asynk/gdx/tabletop/board/HexBoard.java +++ /dev/null @@ -1,136 +0,0 @@ -package ch.asynk.gdx.tabletop.board; - -import com.badlogic.gdx.math.Vector2; - -import ch.asynk.gdx.tabletop.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/tabletop/board/SquareBoard.java b/core/src/ch/asynk/gdx/tabletop/board/SquareBoard.java deleted file mode 100644 index d0daf41..0000000 --- a/core/src/ch/asynk/gdx/tabletop/board/SquareBoard.java +++ /dev/null @@ -1,39 +0,0 @@ -package ch.asynk.gdx.tabletop.board; - -import com.badlogic.gdx.math.Vector2; - -import ch.asynk.gdx.tabletop.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/tabletop/board/TriangleBoard.java b/core/src/ch/asynk/gdx/tabletop/board/TriangleBoard.java deleted file mode 100644 index 94f93e4..0000000 --- a/core/src/ch/asynk/gdx/tabletop/board/TriangleBoard.java +++ /dev/null @@ -1,108 +0,0 @@ -package ch.asynk.gdx.tabletop.board; - -import com.badlogic.gdx.math.Vector2; - -import ch.asynk.gdx.tabletop.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); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Alignment.java b/core/src/ch/asynk/gdx/tabletop/ui/Alignment.java deleted file mode 100644 index 43ae683..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Alignment.java +++ /dev/null @@ -1,168 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -public enum Alignment -{ - ABSOLUTE, // Root - RELATIVE, // Default - TOP_LEFT, - TOP_RIGHT, - TOP_CENTER, - MIDDLE_LEFT, - MIDDLE_RIGHT, - MIDDLE_CENTER, - BOTTOM_LEFT, - BOTTOM_RIGHT, - BOTTOM_CENTER; - - public Alignment verticalMirror() - { - switch(this) { - case TOP_LEFT: - return TOP_RIGHT; - case MIDDLE_LEFT: - return MIDDLE_RIGHT; - case BOTTOM_LEFT: - return BOTTOM_RIGHT; - case TOP_RIGHT: - return TOP_LEFT; - case MIDDLE_RIGHT: - return MIDDLE_LEFT; - case BOTTOM_RIGHT: - return BOTTOM_LEFT; - } - return this; - } - - public Alignment horizontalMirror() - { - switch(this) { - case TOP_LEFT: - return BOTTOM_LEFT; - case TOP_CENTER: - return BOTTOM_CENTER; - case TOP_RIGHT: - return BOTTOM_RIGHT; - case BOTTOM_LEFT: - return TOP_LEFT; - case BOTTOM_CENTER: - return TOP_CENTER; - case BOTTOM_RIGHT: - return TOP_RIGHT; - } - return this; - } - - public boolean isTop() - { - switch(this) { - case TOP_LEFT: - case TOP_CENTER: - case TOP_RIGHT: - return true; - } - return false; - } - - public boolean isMiddle() - { - boolean r = false; - switch(this) { - case MIDDLE_LEFT: - case MIDDLE_CENTER: - case MIDDLE_RIGHT: - return true; - } - return false; - } - - public boolean isBottom() - { - boolean r = false; - switch(this) { - case BOTTOM_LEFT: - case BOTTOM_CENTER: - case BOTTOM_RIGHT: - return true; - } - return false; - } - - public boolean isLeft() - { - boolean r = false; - switch(this) { - case TOP_LEFT: - case MIDDLE_LEFT: - case BOTTOM_LEFT: - return true; - } - return false; - } - - public boolean isRight() - { - boolean r = false; - switch(this) { - case TOP_RIGHT: - case MIDDLE_RIGHT: - case BOTTOM_RIGHT: - return true; - } - return false; - } - - public boolean isCenter() - { - switch(this) { - case TOP_CENTER: - case MIDDLE_CENTER: - case BOTTOM_CENTER: - return true; - } - return false; - } - - public float getX(Element element, float width) - { - float x = element.getInnerX(); - switch(this) { - case TOP_LEFT: - case MIDDLE_LEFT: - case BOTTOM_LEFT: - break; - case TOP_CENTER: - case MIDDLE_CENTER: - case BOTTOM_CENTER: - x += ((element.getInnerWidth() - width) / 2); - break; - case TOP_RIGHT: - case MIDDLE_RIGHT: - case BOTTOM_RIGHT: - x += (element.getInnerWidth() - width); - break; - } - return x; - } - - public float getY(Element element, float height) - { - float y = element.getInnerY(); - switch(this) { - case TOP_LEFT: - case TOP_CENTER: - case TOP_RIGHT: - y += (element.getInnerHeight() - height); - break; - case MIDDLE_LEFT: - case MIDDLE_CENTER: - case MIDDLE_RIGHT: - y += ((element.getInnerHeight() - height) / 2); - break; - case BOTTOM_LEFT: - case BOTTOM_CENTER: - case BOTTOM_RIGHT: - break; - } - return y; - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Assembly.java b/core/src/ch/asynk/gdx/tabletop/ui/Assembly.java deleted file mode 100644 index e808e50..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Assembly.java +++ /dev/null @@ -1,63 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; - -import ch.asynk.gdx.tabletop.util.IterableSet; - -public abstract class Assembly extends Element -{ - private IterableSet children; - private Element touched; - - public Assembly(int c) - { - this.children = new IterableSet(c); - } - - public void add(Element e) - { - if (children.add(e)) { - e.setParent(this); - } - } - - public void remove(Element e) - { - if (children.remove(e)) { - e.setParent(null); - } - } - - public Element touched() - { - return touched; - } - - @Override public boolean touch(float x, float y) - { - for (Element e : children) - if (e.touch(x, y)) { - touched = e; - return true; - } - touched = null; - return false; - } - - @Override public void taint() - { - children.forEach( c -> c.taint() ); - } - - @Override public void draw(Batch batch) - { - if (tainted) computeGeometry(); - children.forEach( c -> c.draw(batch) ); - } - - @Override public void drawDebug(ShapeRenderer debugShapes) - { - children.forEach( c -> c.drawDebug(debugShapes) ); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Button.java b/core/src/ch/asynk/gdx/tabletop/ui/Button.java deleted file mode 100644 index 59974a9..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Button.java +++ /dev/null @@ -1,67 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.NinePatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; - -public class Button extends Patch -{ - private Label label; - private float spacing; // for label alignment; - - public Button(BitmapFont font, NinePatch patch) - { - this(font, patch, 0); - } - - public Button(BitmapFont font, NinePatch patch, float padding) - { - this(font, patch, padding, 0); - } - - public Button(BitmapFont font, NinePatch patch, float padding, float spacing) - { - super(patch); - this.padding = padding; - this.spacing = spacing; - label = new Label(font); - label.setParent(this); - label.setAlignment(Alignment.MIDDLE_CENTER); - } - - public void write(String text) - { - label.write(text); - this.tainted = true; // might impact Button's geometry - } - - public void setLabelAlignment(Alignment alignment) - { - label.setAlignment(alignment); - } - - @Override public void computeGeometry() - { - float dd = 2 * (padding + spacing); - label.computeGeometry(); // update dimensions - rect.width = label.getWidth() + dd; - rect.height = label.getHeight() + dd; - super.computeGeometry(); - label.computeGeometry(); // update position - } - - @Override public void draw(Batch batch) - { - if (!visible) return; - if (tainted) computeGeometry(); - super.draw(batch); - label.draw(batch); - } - - @Override public void drawDebug(ShapeRenderer debugShapes) - { - super.drawDebug(debugShapes); - label.drawDebug(debugShapes); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Element.java b/core/src/ch/asynk/gdx/tabletop/ui/Element.java deleted file mode 100644 index b2a015a..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Element.java +++ /dev/null @@ -1,116 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.math.Rectangle; - -import ch.asynk.gdx.tabletop.Drawable; -import ch.asynk.gdx.tabletop.Touchable; - -public abstract class Element implements Drawable, Touchable -{ - public boolean blocked; - public boolean visible; - protected float padding; - protected Element parent; - protected Alignment alignment; - protected Rectangle rect; // outer drawing coordinates - protected float x, y; // given position - protected boolean tainted; // geometry must be computed - - protected Element() - { - this.blocked = false; - this.visible = true; - this.padding = 0; - this.parent = null; - this.alignment = alignment.RELATIVE; - this.rect = new Rectangle(0, 0, 0, 0); - this.x = this.y = 0; - this.tainted = true; - } - - @Override public final float getX() { return rect.x; } - @Override public final float getY() { return rect.y; } - @Override public final float getWidth() { return rect.width; } - @Override public final float getHeight() { return rect.height; } - - @Override public final float getInnerX() { return rect.x + padding; } - @Override public final float getInnerY() { return rect.y + padding; } - @Override public final float getInnerWidth() { return rect.width - 2 * padding; } - @Override public final float getInnerHeight() { return rect.height - 2 * padding; } - - @Override public void drawDebug(ShapeRenderer debugShapes) - { - debugShapes.rect(getX(), getY(), getWidth(), getHeight()); - } - - @Override public boolean touch(float x, float y) - { - if (blocked || !visible) return false; - return rect.contains(x, y); - } - - public void taint() - { - this.tainted = true; - } - - @Override public void setPosition(float x, float y, float w, float h) - { - this.x = x; - this.y = y; - this.rect.width = w; - this.rect.height = h; - this.tainted = true; - // rect.(x,y) will be set in computeGeometry - } - - public void setParent(Element parent) - { - this.parent = parent; - this.tainted = true; - } - - public void setPadding(float padding) - { - this.padding = padding; - this.tainted = true; - } - - public void setAlignment(Alignment alignment) - { - this.alignment = alignment; - this.tainted = true; - } - - public final void translate(float dx, float dy) - { - setPosition(x + dx, y + dy); - } - - public final void setPosition(Rectangle r) - { - setPosition(r.x, r.x, r.width, r.height); - } - - public final void setPosition(float x, float y) - { - setPosition(x, y, rect.width, rect.height); - } - - protected void computeGeometry() - { - if (alignment == Alignment.ABSOLUTE || parent == null) { - rect.x = x; - rect.y = y; - } else if (alignment == Alignment.RELATIVE) { - rect.x = x + parent.getInnerX(); - rect.y = y + parent.getInnerX(); - } else { - rect.x = x + alignment.getX(parent, rect.width); - rect.y = y + alignment.getY(parent, rect.height); - } - this.tainted = false; - // System.err.println(String.format("%s : %s", this, rect)); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Label.java b/core/src/ch/asynk/gdx/tabletop/ui/Label.java deleted file mode 100644 index 842597a..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Label.java +++ /dev/null @@ -1,61 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; - -public class Label extends Element -{ - private BitmapFont font; - private GlyphLayout layout; - private float fx; - private float fy; - private String text; - - public Label(BitmapFont font) - { - this(font, 0); - } - - public Label(BitmapFont font, float padding) - { - this(font, padding, Alignment.RELATIVE); - } - - public Label(BitmapFont font, float padding, Alignment alignment) - { - super(); - this.font = font; - this.padding = padding; - this.alignment = alignment; - this.layout = new GlyphLayout(); - } - - public void write(String text) - { - write(text, getX(), getY()); - } - - public void write(String text, float x, float y) - { - this.text = text; - this.layout.setText(font, (text == null) ? "" : text); - this.tainted = true; - } - - @Override protected void computeGeometry() - { - this.rect.width = (layout.width + (2 * padding)); - this.rect.height = (layout.height + (2 * padding)); - super.computeGeometry(); - fx = getInnerX(); - fy = getInnerY() + layout.height; - } - - @Override public void draw(Batch batch) - { - if (!visible) return; - if (tainted) computeGeometry(); - font.draw(batch, layout, fx, fy); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Menu.java b/core/src/ch/asynk/gdx/tabletop/ui/Menu.java deleted file mode 100644 index 38a15dd..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Menu.java +++ /dev/null @@ -1,126 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.NinePatch; -import com.badlogic.gdx.graphics.g2d.BitmapFont; - -public class Menu extends Patch -{ - private Label title; - private Label[] entries; - private Integer touchedItem; - - private int entriesOffset; // horizontal offset - private int titleSpacing; // between title and entries - private int entriesSpacing; // between entries - - public Menu(BitmapFont font, NinePatch patch, String title, String[] entries) - { - super(patch); - this.touchedItem = null; - setTitle(font, title); - setEntries(font, entries); - } - - public void setTitle(BitmapFont font, String title) - { - this.title = new Label(font); - this.title.write(title); - this.tainted = true; - } - - public void setEntries(BitmapFont font, String[] entries) - { - this.entries = new Label[entries.length]; - for (int i = 0; i < entries.length; i++) { - Label l = new Label(font); - l.write(entries[i]); - this.entries[i] = l; - } - this.tainted = true; - } - - public void setLabelsOffset(int entriesOffset) - { - this.entriesOffset = entriesOffset; - this.tainted = true; - } - - public void setPaddings(int titlePadding, int labelPadding) - { - this.title.setPadding(titlePadding); - for (Label label : entries) { - label.setPadding(labelPadding); - } - this.tainted = true; - } - - public void setSpacings(int titleSpacing, int entriesSpacing) - { - this.titleSpacing = titleSpacing; - this.entriesSpacing = entriesSpacing; - this.tainted = true; - } - - @Override public void computeGeometry() - { - title.computeGeometry(); - float h = title.getHeight(); - float w = title.getWidth(); - for (Label label : entries) { - label.computeGeometry(); - h += label.getHeight(); - float t = label.getWidth() + entriesOffset; - if (t > w) - w = t; - } - h += (titleSpacing + (entriesSpacing * (entries.length - 1)) + (2 * padding)); - w += (2 * padding); - - rect.width = w; - rect.height = h; - super.computeGeometry(); - - float x = getInnerX(); - float y = getInnerY(); - - // setPosition() will trigger computeGeometry() from within draw() - for (int i = entries.length - 1; i >= 0; i--) { - entries[i].setPosition(x + entriesOffset, y); - y += entries[i].getHeight() + entriesSpacing; - } - y -= entriesSpacing; - y += titleSpacing; - title.setPosition(x, y); - } - - public Integer touched() - { - return touchedItem; - } - - @Override public boolean touch(float x, float y) - { - touchedItem = null; - if (super.touch(x, y)) { - for (int i = 0; i < entries.length; i++) { - if (entries[i].touch(x, y)) { - touchedItem = i; - return true; - } - } - } - return false; - } - - @Override public void draw(Batch batch) - { - if (!visible) return; - if (tainted) computeGeometry(); - super.draw(batch); - title.draw(batch); - for (Label label : entries) { - label.draw(batch); - } - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Patch.java b/core/src/ch/asynk/gdx/tabletop/ui/Patch.java deleted file mode 100644 index a829ce0..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Patch.java +++ /dev/null @@ -1,23 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.NinePatch; - -public class Patch extends Element -{ - private NinePatch patch; - - public Patch(NinePatch patch) - { - super(); - this.patch = patch; - setPosition(0, 0, patch.getTotalWidth(), patch.getTotalHeight()); - } - - @Override public void draw(Batch batch) - { - if (!visible) return; - if (tainted) computeGeometry(); - patch.draw(batch, getX(), getY(), getWidth(), getHeight()); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/ui/Root.java b/core/src/ch/asynk/gdx/tabletop/ui/Root.java deleted file mode 100644 index 21ffd54..0000000 --- a/core/src/ch/asynk/gdx/tabletop/ui/Root.java +++ /dev/null @@ -1,28 +0,0 @@ -package ch.asynk.gdx.tabletop.ui; - -import com.badlogic.gdx.math.Rectangle; - -public class Root extends Assembly -{ - public Root(int c) - { - super(c); - this.alignment = Alignment.ABSOLUTE; - } - - public void resize(Rectangle r) - { - resize(r.x, r.y, r.width, r.height); - } - - public void resize(float width, float height) - { - resize(getX(), getY(), width, height); - } - - public void resize(float x, float y, float width, float height) - { - setPosition(x, y, width, height); - taint(); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/util/Collection.java b/core/src/ch/asynk/gdx/tabletop/util/Collection.java deleted file mode 100644 index 232420d..0000000 --- a/core/src/ch/asynk/gdx/tabletop/util/Collection.java +++ /dev/null @@ -1,28 +0,0 @@ -package ch.asynk.gdx.tabletop.util; - -import java.util.Iterator; - -public interface Collection extends Iterator, Iterable -{ - public int size(); - - public boolean isEmpty(); - - public void clear(); - - public void ensureCapacity(int c); - - public boolean contains(E e); - - public E get(int idx); - - public int indexOf(E e); - - public boolean add(E e); - - public boolean insert(E e, int idx); - - public E remove(int idx); - - public boolean remove(E e); -} diff --git a/core/src/ch/asynk/gdx/tabletop/util/IterableArray.java b/core/src/ch/asynk/gdx/tabletop/util/IterableArray.java deleted file mode 100644 index e72a8d4..0000000 --- a/core/src/ch/asynk/gdx/tabletop/util/IterableArray.java +++ /dev/null @@ -1,143 +0,0 @@ -package ch.asynk.gdx.tabletop.util; - -import java.util.Arrays; -import java.util.Iterator; - -public class IterableArray implements Collection -{ - private int idx; - private int s; - private int c; - transient E[] data; - - @SuppressWarnings("unchecked") - public IterableArray(int capacity) - { - this.s = 0; - this.c = capacity; - this.data = (E[]) new Object[c]; - } - - @Override public int size() - { - return s; - } - - @Override public boolean isEmpty() - { - return (s == 0); - } - - @Override public void clear() - { - for (int i = 0; i < s; i++) - data[i] = null; - s = 0; - } - - @Override public void ensureCapacity(int min) - { - if (c > min) return; - c += (c >> 1); - if (c < min) - c = min; - data = Arrays.copyOf(data, c); - } - - @Override public boolean contains(E e) - { - if (e == null) { - for (int i = 0; i < s; i++) { - if (data[i] == null) - return true; - } - } else { - for (int i = 0; i < s; i++) { - if (e.equals(data[i])) - return true; - } - } - return false; - } - - @Override public E get(int i) - { - return data[i]; - } - - @Override public int indexOf(E e) - { - for (int i = 0; i < data.length; i++) { - if (data[i] != null && data[i].equals(e)) - return i; - } - return -1; - } - - @Override public boolean add(E e) - { - ensureCapacity(s + 1); - data[s] = e; - s += 1; - return true; - } - - @Override public boolean insert(E e, int idx) - { - ensureCapacity(s + 1); - System.arraycopy(data, idx, data, idx+1, (s - idx)); - data[idx] = e; - s += 1; - return true; - } - - @Override public E remove(int i) - { - E e = data[i]; - int m = (s - i - 1); - if (m > 0) - System.arraycopy(data, i+1, data, i, m); - data[--s] = null; - - return e; - } - - @Override public boolean remove(E e) - { - for (int i = 0; i < s; i++) { - if (e.equals(data[i])) { - int m = (s - i - 1); - if (m > 0) - System.arraycopy(data, i+1, data, i, m); - data[--s] = null; - return true; - } - } - return false; - } - - @SuppressWarnings("unchecked") - @Override public Iterator iterator() - { - this.idx = 0; - return (Iterator) this; - } - - @Override public boolean hasNext() - { - return (idx < s); - } - - @Override public E next() - { - E e = get(idx); - idx += 1; - return e; - } - - @Override public void remove() - { - idx -= 1; - remove(idx); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/util/IterableQueue.java b/core/src/ch/asynk/gdx/tabletop/util/IterableQueue.java deleted file mode 100644 index b7c9d41..0000000 --- a/core/src/ch/asynk/gdx/tabletop/util/IterableQueue.java +++ /dev/null @@ -1,19 +0,0 @@ -package ch.asynk.gdx.tabletop.util; - -public class IterableQueue extends IterableArray -{ - public IterableQueue(int n) - { - super(n); - } - - public void enqueue(E e) - { - add(e); - } - - public E dequeue() - { - return remove(0); - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/util/IterableSet.java b/core/src/ch/asynk/gdx/tabletop/util/IterableSet.java deleted file mode 100644 index 9875f74..0000000 --- a/core/src/ch/asynk/gdx/tabletop/util/IterableSet.java +++ /dev/null @@ -1,16 +0,0 @@ -package ch.asynk.gdx.tabletop.util; - -public class IterableSet extends IterableArray -{ - public IterableSet(int n) - { - super(n); - } - - @Override public boolean add(E e) - { - if (contains(e)) return false; - super.add(e); - return true; - } -} diff --git a/core/src/ch/asynk/gdx/tabletop/util/IterableStack.java b/core/src/ch/asynk/gdx/tabletop/util/IterableStack.java deleted file mode 100644 index f00dde3..0000000 --- a/core/src/ch/asynk/gdx/tabletop/util/IterableStack.java +++ /dev/null @@ -1,26 +0,0 @@ -package ch.asynk.gdx.tabletop.util; - -public class IterableStack extends IterableArray -{ - public IterableStack(int n) - { - super(n); - } - - public void push(E e) - { - add(e); - } - - public E pop() - { - if (size() <= 0) return null; - return remove(size() - 1); - } - - public E getTop() - { - if (size() <= 0) return null; - return get(size() - 1); - } -} diff --git a/test/build.gradle b/test/build.gradle index 6fe56b7..7bfe898 100644 --- a/test/build.gradle +++ b/test/build.gradle @@ -5,7 +5,7 @@ apply plugin: "java" sourceCompatibility = 1.8 sourceSets.main.java.srcDirs = [ "src/" ] -project.ext.mainClassName = "ch.asynk.gdx.tabletop.test.DesktopLauncher" +project.ext.mainClassName = "ch.asynk.gdx.boardgame.test.DesktopLauncher" project.ext.assetsDir = new File("../assets/data"); task run(dependsOn: classes, type: JavaExec) { diff --git a/test/src/ch/asynk/gdx/boardgame/test/AbstractScreen.java b/test/src/ch/asynk/gdx/boardgame/test/AbstractScreen.java new file mode 100644 index 0000000..e564790 --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/AbstractScreen.java @@ -0,0 +1,168 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.InputAdapter; +import com.badlogic.gdx.InputMultiplexer; +import com.badlogic.gdx.input.GestureDetector; +import com.badlogic.gdx.input.GestureDetector.GestureAdapter; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; + +import ch.asynk.gdx.boardgame.ui.Root; + +public abstract class AbstractScreen implements Screen +{ + protected final float WORLD_RATIO = 0.5f; + private static final float INPUT_DELAY = 0.1f; // filter out touches after gesture + private static final float ZOOM_SCROLL_FACTOR = .1f; + private static final float ZOOM_GESTURE_FACTOR = .01f; + + protected final Vector2 dragPos = new Vector2(); + protected final Vector3 boardTouch = new Vector3(); + protected final Vector3 hudTouch = new Vector3(); + + protected final String dom; + protected final GdxBoardTest app; + protected final SpriteBatch batch; + protected final Texture bg; + protected final Root root; + protected Camera camera; + protected boolean inputBlocked; + protected float inputDelay; + protected boolean paused; + + protected abstract void feed(); + public AbstractScreen(final GdxBoardTest app, final String dom) + { + this.app = app; + this.dom = dom; + this.batch = new SpriteBatch(); + this.bg = app.assets.getTexture(app.assets.MAP_00); + this.root = new Root(1); + this.root.setPadding(15); + feed(); + Gdx.input.setInputProcessor(getMultiplexer()); + this.inputBlocked = false; + this.inputDelay = 0f; + this.paused = false; + } + + protected abstract void draw(SpriteBatch batch); + @Override public void render(float delta) + { + if (paused) return; + + Gdx.gl.glClearColor(1, 1, 1, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + camera.update(); + batch.setProjectionMatrix(camera.combined); + batch.begin(); + draw(batch); + batch.end(); + } + + @Override public void resize(int width, int height) + { + GdxBoardTest.debug(dom, String.format("resize (%d,%d)",width, height)); + if (width >= height) { + camera.viewportWidth = bg.getWidth(); + camera.viewportHeight = bg.getHeight() / (float)width * (float)height; + } else { + camera.viewportHeight = bg.getHeight(); + camera.viewportWidth = bg.getWidth() / (float)height * (float)width; + } + camera.viewportWidth *= WORLD_RATIO; + camera.viewportHeight *= WORLD_RATIO; + camera.update(); + root.resize( + camera.position.x - (camera.viewportWidth / 2f), + camera.position.y - (camera.viewportHeight / 2f), + camera.viewportWidth, + camera.viewportHeight + ); + } + + @Override public void dispose() + { + GdxBoardTest.debug(dom, "dispose()"); + batch.dispose(); + } + + @Override public void show() + { + GdxBoardTest.debug(dom, "show()"); + paused = false; + } + + @Override public void hide() + { + GdxBoardTest.debug(dom, "hide()"); + paused = true; + } + + @Override public void pause() + { + GdxBoardTest.debug(dom, "pause() "); + paused = true; + } + + @Override public void resume() + { + GdxBoardTest.debug(dom, "resume() "); + resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + paused = false; + } + + protected abstract void onTouch(int x, int y); + protected abstract void onZoom(float dz); + protected abstract void onDragged(int dx, int dy); + private InputMultiplexer getMultiplexer() + { + final InputMultiplexer multiplexer = new InputMultiplexer(); + multiplexer.addProcessor(new InputAdapter() { + @Override public boolean scrolled(int amount) + { + onZoom(amount * ZOOM_SCROLL_FACTOR); + return true; + } + @Override public boolean touchDown(int x, int y, int pointer, int button) + { + if (inputBlocked) return true; + if (button == Input.Buttons.LEFT) { + dragPos.set(x, y); + onTouch(x, y); + } + return true; + } + @Override public boolean touchDragged(int x, int y, int pointer) + { + int dx = (int) (dragPos.x - x); + int dy = (int) (dragPos.y - y); + dragPos.set(x, y); + onDragged(dx, dy); + return true; + } + }); + multiplexer.addProcessor(new GestureDetector(new GestureAdapter() { + @Override public boolean zoom(float initialDistance, float distance) + { + if (initialDistance > distance) + onZoom(ZOOM_GESTURE_FACTOR); + else + onZoom(-ZOOM_GESTURE_FACTOR); + inputBlocked = true; + inputDelay = INPUT_DELAY; + return true; + } + })); + + return multiplexer; + } +} diff --git a/test/src/ch/asynk/gdx/boardgame/test/Assets.java b/test/src/ch/asynk/gdx/boardgame/test/Assets.java new file mode 100644 index 0000000..0c8ba5c --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/Assets.java @@ -0,0 +1,84 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.assets.loaders.FileHandleResolver; +import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGeneratorLoader; +import com.badlogic.gdx.graphics.g2d.freetype.FreetypeFontLoader; +import com.badlogic.gdx.graphics.g2d.freetype.FreetypeFontLoader.FreeTypeFontLoaderParameter; + +public class Assets extends ch.asynk.gdx.boardgame.Assets +{ + public static final String LOADING = "loading.atlas"; + + public static final String CORNER = "corner.png"; + public static final String MAP_00 = "map_00.png"; + public static final String CHESS = "chess.jpg"; + public static final String TRI = "triangle.png"; + public static final String FONT = "veteran-typewriter.ttf"; + public static final String FONT_20 = "size20.ttf"; + public static final String FONT_25 = "size25.ttf"; + public static final String PATCH = "ui-patch.png"; + public static final String SHERMAN = "sherman.png"; + + private final FreeTypeFontLoaderParameter params20; + private final FreeTypeFontLoaderParameter params25; + + public Assets() + { + super(); + final FileHandleResolver resolver = new InternalFileHandleResolver(); + setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver)); + setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver)); + params20 = new FreeTypeFontLoaderParameter(); + params20.fontFileName = FONT; + params20.fontParameters.size = 20; + params25 = new FreeTypeFontLoaderParameter(); + params25.fontFileName = FONT; + params25.fontParameters.size = 25; + } + + @Override public void dispose() + { + GdxBoardTest.debug("diagnostics:\n" + getDiagnostics() ); + clear(); + super.dispose(); + } + + public void loadLoading() + { + load(LOADING, TextureAtlas.class); + } + + public void unloadLoading() + { + unload(LOADING); + } + + public void loadApp() + { + load(MAP_00, Texture.class); + load(CHESS, Texture.class); + load(TRI, Texture.class); + load(CORNER, Texture.class); + load(PATCH, Texture.class); + load(SHERMAN, Texture.class); + load(FONT_20, BitmapFont.class, params20); + load(FONT_25, BitmapFont.class, params25); + } + + public void unloadApp() + { + unload(MAP_00); + unload(CHESS); + unload(TRI); + unload(CORNER); + unload(PATCH); + unload(SHERMAN); + unload(FONT_20); + unload(FONT_25); + } +} diff --git a/test/src/ch/asynk/gdx/boardgame/test/BoardScreen.java b/test/src/ch/asynk/gdx/boardgame/test/BoardScreen.java new file mode 100644 index 0000000..876c2e8 --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/BoardScreen.java @@ -0,0 +1,240 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.math.Vector2; + +import ch.asynk.gdx.boardgame.Camera; +import ch.asynk.gdx.boardgame.Board; +import ch.asynk.gdx.boardgame.board.BoardFactory; +import ch.asynk.gdx.boardgame.ui.Alignment; +import ch.asynk.gdx.boardgame.ui.Button; +import ch.asynk.gdx.boardgame.ui.Root; + +public class BoardScreen extends AbstractScreen +{ + + private static final boolean DEBUG = true; + + private class MyBoard + { + private final Assets assets; + private final Texture sherman; + private final Vector2 v; + public Texture map; + public Board board; + public int dx; + public int dy; + public int w; + public int h; + public float r; + + public MyBoard(final Assets assets) + { + this.assets = assets; + this.sherman = assets.getTexture(assets.SHERMAN); + this.v = new Vector2(); + } + + public void draw(SpriteBatch batch) + { + batch.draw(map, dx, dy, map.getWidth()/2, map.getHeight()/2, map.getWidth(), map.getHeight(), 1, 1, r, 0, 0, map.getWidth(), map.getHeight(), false, false); + batch.draw(sherman, v.x - (sherman.getWidth() / 2), v.y - (sherman.getHeight() / 2)); + } + + public void reset() + { + board.centerOf(0, 0, v); + } + + public boolean touch(float x, float y) + { + board.toBoard(x, y, v); + GdxBoardTest.debug("BoardScreen", String.format("touchDown [%d;%d] => [%d;%d]", (int)x, (int)y, (int)v.x, (int)v.y)); + board.centerOf((int)v.x, (int)v.y, v); + GdxBoardTest.debug("BoardScreen", String.format(" => [%d;%d]", (int)v.x, (int)v.y)); + return true; + } + + public void setHEX_V() + { + map = assets.getTexture(assets.MAP_00); + r = 0; + dx = 0; + dy = 0; + w = map.getWidth(); + h = map.getHeight(); + board = BoardFactory.getBoard(BoardFactory.BoardType.HEX, 110, 50, 103, BoardFactory.BoardOrientation.VERTICAL); + } + + public void setHEX_H() + { + map = assets.getTexture(assets.MAP_00); + r = 90; + dx = - ( map.getWidth() - map.getHeight() ) / 2; + dy = - dx; + w = map.getHeight(); + h = map.getWidth(); + board = BoardFactory.getBoard(BoardFactory.BoardType.HEX, 110, 103, 50, BoardFactory.BoardOrientation.HORIZONTAL); + } + + public void setSQUARE() + { + map = assets.getTexture(assets.CHESS); + r = 0; + dx = 0; + dy = 0; + w = map.getWidth(); + h = map.getHeight(); + board = BoardFactory.getBoard(BoardFactory.BoardType.SQUARE, 83, 5, 5); + } + + public void setTRI_H() + { + map = assets.getTexture(assets.TRI); + r = 0; + dx = 0; + dy = 0; + w = map.getWidth(); + h = map.getHeight(); + board = BoardFactory.getBoard(BoardFactory.BoardType.TRIANGLE, 150, 109, 53, BoardFactory.BoardOrientation.HORIZONTAL); + } + + public void setTRI_V() + { + map = assets.getTexture(assets.TRI); + r = 90; + dx = - ( map.getWidth() - map.getHeight() ) / 2; + dy = - dx; + w = map.getHeight(); + h = map.getWidth(); + board = BoardFactory.getBoard(BoardFactory.BoardType.TRIANGLE, 150, 16, 110, BoardFactory.BoardOrientation.VERTICAL); + } + } + + public enum State + { + HEX_V, HEX_H, SQUARE, TRI_H, TRI_V, DONE; + public State next() + { + switch(this) { + case HEX_V: + return HEX_H; + case HEX_H: + return SQUARE; + case SQUARE: + return TRI_H; + case TRI_H: + return TRI_V; + case TRI_V: + return DONE; + default: + return HEX_V; + } + } + } + private State state; + + private Camera cam; + private MyBoard board; + private Button btn; + private Root root; + + public BoardScreen(final GdxBoardTest app) + { + super(app, ""); + } + + @Override protected void feed() + { + this.board = new MyBoard(app.assets); + this.camera = this.cam = new Camera(10, board.w, board.h, 1.0f, 0.3f, false); + this.btn = new Button( + app.assets.getFont(app.assets.FONT_25), + app.assets.getNinePatch(app.assets.PATCH, 23, 23, 23 ,23), + 15); + this.btn.setAlignment(Alignment.BOTTOM_RIGHT); + this.btn.write("next"); + this.root = new Root(1); + this.root.add(btn); + this.root.setPadding(5); + setState(State.HEX_V); + } + + @Override public void draw(SpriteBatch batch) { } + @Override public void render(float delta) + { + if (paused) return; + + if (inputBlocked) { + inputDelay -= delta; + if (inputDelay <= 0f) + inputBlocked = false; + } + + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + cam.applyBoardViewport(); + batch.setProjectionMatrix(cam.combined); + batch.begin(); + board.draw(batch); + batch.end(); + + cam.applyHudViewport(); + batch.setProjectionMatrix(cam.getHudMatrix()); + batch.begin(); + root.draw(batch); + batch.end(); + } + + @Override public void resize(int width, int height) + { + GdxBoardTest.debug("BoardScrean", String.format("resize (%d,%d)",width, height)); + cam.updateViewport(width, height); + root.resize(cam.getHud()); + } + + @Override protected void onDragged(int dx, int dy) + { + cam.translate(dx, dy); + } + + @Override protected void onTouch(int x, int y) + { + cam.unproject(x, y, boardTouch); + cam.unprojectHud(x, y, hudTouch); + if (btn.touch(hudTouch.x, hudTouch.y)) { + setState(state.next()); + } else { + board.touch(boardTouch.x, boardTouch.y); + } + } + + @Override protected void onZoom(float dz) + { + cam.zoom(dz); + resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + } + + private void setState(State state) + { + switch (state) { + case HEX_V: board.setHEX_V(); break; + case HEX_H: board.setHEX_H(); break; + case SQUARE: board.setSQUARE(); break; + case TRI_H: board.setTRI_H(); break; + case TRI_V: board.setTRI_V(); break; + case DONE: + cam.applyScreenViewport(); + this.app.switchToMenu(); + return; + } + board.reset(); + cam.setDimension(board.w, board.h); + onZoom(1); + this.state = state; + } +} diff --git a/test/src/ch/asynk/gdx/boardgame/test/DesktopLauncher.java b/test/src/ch/asynk/gdx/boardgame/test/DesktopLauncher.java new file mode 100644 index 0000000..2c9066f --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/DesktopLauncher.java @@ -0,0 +1,14 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.backends.lwjgl.LwjglApplication; +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; + +public class DesktopLauncher { + public static void main (String[] arg) { + LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); + new LwjglApplication(new GdxBoardTest(), config); + config.title = "gdx-boardgame Demo"; + config.width=800; + config.height=600; + } +} diff --git a/test/src/ch/asynk/gdx/boardgame/test/GdxBoardTest.java b/test/src/ch/asynk/gdx/boardgame/test/GdxBoardTest.java new file mode 100644 index 0000000..307f961 --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/GdxBoardTest.java @@ -0,0 +1,97 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.Game; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; + +public class GdxBoardTest extends Game +{ + private static final String DOM = "GdxBoardTest"; + + private enum State + { + NONE, + LOADING, + MENU, + UI, + BOARD, + EXIT + } + private State state; + + public final Assets assets = new Assets(); + + @Override public void create() + { + this.state = State.NONE; + Gdx.app.setLogLevel(Gdx.app.LOG_DEBUG); + debug(String.format("create() [%d;%d] %f", Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Gdx.graphics.getDensity())); + switchToLoading(); + } + + @Override public void dispose() + { + debug("dispose()"); + assets.clear(); + assets.dispose(); + } + + public static void error(String msg) + { + Gdx.app.error(DOM, msg); + } + + public static void debug(String msg) + { + Gdx.app.debug(DOM, msg); + } + + public static void debug(String from, String msg) + { + Gdx.app.debug(DOM, String.format("%s : %s", from, msg)); + } + + private void switchTo(Screen nextScreen, State nextState) + { + if (state == nextState) { + error("switch from and to " + state); + return; + } + if (state == State.LOADING) { + assets.unloadLoading(); + } + if (state != State.NONE) { + getScreen().dispose(); + } + setScreen(nextScreen); + this.state = nextState; + } + + public void switchToLoading() + { + assets.loadLoading(); + assets.finishLoading(); + switchTo(new LoadingScreen(this, () -> assets.loadApp(), () -> switchToMenu()), State.LOADING); + } + + public void switchToMenu() + { + switchTo(new MenuScreen(this), State.MENU); + } + + public void switchToUi() + { + switchTo(new UiScreen(this), State.UI); + } + + public void switchToBoard() + { + switchTo(new BoardScreen(this), State.BOARD); + } + + public void switchToExit() + { + Gdx.app.exit(); + switchTo(null, State.EXIT); + } +} diff --git a/test/src/ch/asynk/gdx/boardgame/test/LoadingScreen.java b/test/src/ch/asynk/gdx/boardgame/test/LoadingScreen.java new file mode 100644 index 0000000..69c7e11 --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/LoadingScreen.java @@ -0,0 +1,168 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion; + +public class LoadingScreen implements Screen +{ + private static final String DOM = "LoadingScreen"; + + private final GdxBoardTest app; + private final SpriteBatch batch; + private final Color c; + private final OrthographicCamera camera; + + private final float BLINK_AFTER = 1f; + private final float ALPHA_FACTOR = 1.5f; + + private boolean paused; + private TextureAtlas atlas; + private AtlasRegion bar; + private AtlasRegion border; + private AtlasRegion loading; + private AtlasRegion loaded; + + private int x, y; + private int count; + private float percent; + private float alpha; + private boolean incr; + private boolean isLoaded; + + public interface LoadAction { + void call(); + } + private LoadAction onLoaded; + + public LoadingScreen(final GdxBoardTest app, LoadAction startLoading, LoadAction onLoaded) + { + this.app = app; + this.onLoaded = onLoaded; + this.batch = new SpriteBatch(); + this.c = batch.getColor(); + this.camera = new OrthographicCamera(); + int w = Gdx.graphics.getWidth(); + int h = Gdx.graphics.getHeight(); + this.camera.setToOrtho(false, w, h); + this.camera.update(); + this.paused = false; + atlas = app.assets.getAtlas(app.assets.LOADING); + bar = atlas.findRegion("bar"); + border = atlas.findRegion("border"); + loading = atlas.findRegion("loading"); + loaded = atlas.findRegion("loaded"); + computeCoords(w, h); + percent = 0f; + alpha = 1f; + incr = false; + isLoaded = false; + startLoading.call(); + } + + private void computeCoords(int width, int height) + { + x = (width - border.getRegionWidth()) / 2; + y = (height - border.getRegionHeight()) / 2; + } + + @Override public void render(float delta) + { + if (paused) return; + + if (!isLoaded) { + if (app.assets.update()) { + GdxBoardTest.debug(DOM, "assets loaded"); + isLoaded = true; + percent = 1f; + } else { + percent = app.assets.getProgress(); + } + } + + if (!isLoaded && percent >= 1f) { + count = 0; + alpha = 1f; + incr = false; + } + + delta *= ALPHA_FACTOR; + if (incr) { + alpha += delta; + if (alpha >= 1f ) { + alpha = 1f; + incr = false; + if (isLoaded) count += 1; + if (count >= BLINK_AFTER) { + onLoaded.call(); + return; + } + } + } else { + alpha -= delta; + if (alpha <= 0f ) { + alpha = 0f; + incr = true; + } + } + + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + batch.setProjectionMatrix(camera.combined); + batch.begin(); + batch.setColor(c.r, c.g, c.b, 1f); + batch.draw(border, x, y); + batch.draw(bar, x + 4, y + 4, percent * bar.getRegionWidth(), bar.getRegionHeight()); + batch.setColor(c.r, c.g, c.b, alpha); + if (!isLoaded) { + batch.draw(loading, x, y + border.getRegionHeight() + 3); + } else { + batch.draw(loaded, x + border.getRegionWidth() - loaded.getRegionWidth(), y - loaded.getRegionHeight() - 3); + } + batch.end(); + } + + @Override public void resize(int width, int height) + { + if (paused) return; + GdxBoardTest.debug("LoadingScreen", String.format("resize (%d,%d)",width, height)); + this.camera.setToOrtho(false, width, height); + this.camera.update(); + computeCoords(width, height); + } + + @Override public void dispose() + { + GdxBoardTest.debug("LoadingScreen", "dispose()"); + batch.dispose(); + } + + @Override public void show() + { + GdxBoardTest.debug("LoadingScreen", "show()"); + } + + @Override public void hide() + { + GdxBoardTest.debug("LoadingScreen", "hide()"); + } + + @Override public void pause() + { + paused = true; + GdxBoardTest.debug("LoadingScreen", "pause() "); + } + + @Override public void resume() + { + GdxBoardTest.debug("LoadingScreen", "resume() "); + resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + paused = false; + } +} diff --git a/test/src/ch/asynk/gdx/boardgame/test/MenuScreen.java b/test/src/ch/asynk/gdx/boardgame/test/MenuScreen.java new file mode 100644 index 0000000..be9ec72 --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/MenuScreen.java @@ -0,0 +1,86 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.OrthographicCamera; + +import ch.asynk.gdx.boardgame.ui.Alignment; +import ch.asynk.gdx.boardgame.ui.Menu; + +public class MenuScreen extends AbstractScreen +{ + private Sprite corner; + private Menu menu; + + public MenuScreen(final GdxBoardTest app) + { + super(app, "MenuScreen"); + } + + @Override protected void feed() + { + final Assets assets = app.assets; + this.corner = new Sprite(assets.getTexture(assets.CORNER)); + + this.menu = new Menu( + assets.getFont(assets.FONT_25), + assets.getNinePatch(assets.PATCH, 23, 23, 23 ,23), + "Menu", new String[]{"UI","Board","Exit"}); + this.menu.setAlignment(Alignment.MIDDLE_CENTER); + this.menu.setPaddings(5, 5); + this.menu.setSpacings(10, 5); + this.menu.setPadding(20); + this.menu.setLabelsOffset(10); + this.root.add(this.menu); + + this.camera = new OrthographicCamera(bg.getWidth() * WORLD_RATIO, bg.getHeight() * WORLD_RATIO); + this.camera.position.set(bg.getWidth() / 2f, bg.getHeight() / 2f, 0); + this.camera.update(); + } + + @Override protected void draw(SpriteBatch batch) + { + batch.draw(bg, 0, 0); + drawCorners(batch); + root.draw(batch); + } + + private void drawCorners(SpriteBatch batch) + { + float right = root.getInnerX() + root.getInnerWidth() - corner.getWidth(); + float top = root.getInnerY() + root.getInnerHeight() - corner.getHeight(); + corner.setRotation(0); + corner.setPosition(root.getInnerX(), top); + corner.draw(batch); + corner.setRotation(90); + corner.setPosition(root.getInnerX(), root.getInnerY()); + corner.draw(batch); + corner.setRotation(180); + corner.setPosition(right, root.getInnerY()); + corner.draw(batch); + corner.setPosition(right, top); + corner.setRotation(270); + corner.draw(batch); + } + + @Override protected void onZoom(float dz) { } + @Override protected void onDragged(int dx, int dy) { } + @Override protected void onTouch(int x, int y) + { + hudTouch.set(x, y, 0); + camera.unproject(hudTouch); + if (root.touch(hudTouch.x, hudTouch.y)) { + switch(menu.touched()) { + case 0: + app.switchToUi(); + break; + case 1: + app.switchToBoard(); + break; + case 2: + app.switchToExit(); + break; + } + } + } +} diff --git a/test/src/ch/asynk/gdx/boardgame/test/UiScreen.java b/test/src/ch/asynk/gdx/boardgame/test/UiScreen.java new file mode 100644 index 0000000..5292af8 --- /dev/null +++ b/test/src/ch/asynk/gdx/boardgame/test/UiScreen.java @@ -0,0 +1,103 @@ +package ch.asynk.gdx.boardgame.test; + +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.OrthographicCamera; + +import ch.asynk.gdx.boardgame.ui.Alignment; +import ch.asynk.gdx.boardgame.ui.Button; + +public class UiScreen extends AbstractScreen +{ + private Button hello; + + public UiScreen(final GdxBoardTest app) + { + super(app, "UiScreen"); + } + + public enum State + { + POSITIONS, DONE; + public State next() + { + switch(this) { + case POSITIONS: + return DONE; + default: + return POSITIONS; + } + } + } + private State state; + + @Override protected void feed() + { + final NinePatch patch = app.assets.getNinePatch(app.assets.PATCH, 23, 23, 23 ,23); + final BitmapFont font = app.assets.getFont(app.assets.FONT_25); + + this.hello = new Button(font, patch, 10, 15); + this.hello.write("Hello"); + this.root.add(this.hello); + + this.camera = new OrthographicCamera(bg.getWidth() * WORLD_RATIO, bg.getHeight() * WORLD_RATIO); + this.camera.position.set(bg.getWidth() / 2f, bg.getHeight() / 2f, 0); + this.camera.update(); + setState(State.POSITIONS); + } + + private void setState(State state) + { + switch (state) { + case DONE: + app.switchToMenu(); + } + this.state = state; + } + + @Override protected void draw(SpriteBatch batch) + { + batch.draw(bg, 0, 0); + switch (state) { + case POSITIONS: + drawButtons(batch); + break; + } + } + + private void drawButtons(SpriteBatch batch) + { + hello.write("hello"); + hello.setAlignment(Alignment.TOP_LEFT); + hello.setLabelAlignment(Alignment.BOTTOM_RIGHT); + root.draw(batch); + drawHello(batch, Alignment.TOP_CENTER, Alignment.BOTTOM_CENTER); + drawHello(batch, Alignment.TOP_RIGHT, Alignment.BOTTOM_LEFT); + drawHello(batch, Alignment.MIDDLE_LEFT, Alignment.MIDDLE_RIGHT); + drawHello(batch, Alignment.MIDDLE_RIGHT, Alignment.MIDDLE_LEFT); + drawHello(batch, Alignment.BOTTOM_LEFT, Alignment.TOP_RIGHT); + drawHello(batch, Alignment.BOTTOM_CENTER, Alignment.TOP_CENTER); + drawHello(batch, Alignment.BOTTOM_RIGHT, Alignment.TOP_LEFT); + hello.write("next"); + drawHello(batch, Alignment.MIDDLE_CENTER, Alignment.MIDDLE_CENTER); + } + + private void drawHello(SpriteBatch batch, Alignment alignment1, Alignment alignment2) + { + hello.setAlignment(alignment1); + hello.setLabelAlignment(alignment2); + hello.draw(batch); + } + + @Override protected void onZoom(float dz) { } + @Override protected void onDragged(int dx, int dy) { } + @Override protected void onTouch(int x, int y) + { + hudTouch.set(x, y, 0); + camera.unproject(hudTouch); + if (root.touch(hudTouch.x, hudTouch.y)) { + setState(state.next()); + } + } +} diff --git a/test/src/ch/asynk/gdx/tabletop/test/AbstractScreen.java b/test/src/ch/asynk/gdx/tabletop/test/AbstractScreen.java deleted file mode 100644 index 0c81bfb..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/AbstractScreen.java +++ /dev/null @@ -1,168 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Screen; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.Camera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.InputAdapter; -import com.badlogic.gdx.InputMultiplexer; -import com.badlogic.gdx.input.GestureDetector; -import com.badlogic.gdx.input.GestureDetector.GestureAdapter; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; - -import ch.asynk.gdx.tabletop.ui.Root; - -public abstract class AbstractScreen implements Screen -{ - protected final float WORLD_RATIO = 0.5f; - private static final float INPUT_DELAY = 0.1f; // filter out touches after gesture - private static final float ZOOM_SCROLL_FACTOR = .1f; - private static final float ZOOM_GESTURE_FACTOR = .01f; - - protected final Vector2 dragPos = new Vector2(); - protected final Vector3 boardTouch = new Vector3(); - protected final Vector3 hudTouch = new Vector3(); - - protected final String dom; - protected final GdxBoardTest app; - protected final SpriteBatch batch; - protected final Texture bg; - protected final Root root; - protected Camera camera; - protected boolean inputBlocked; - protected float inputDelay; - protected boolean paused; - - protected abstract void feed(); - public AbstractScreen(final GdxBoardTest app, final String dom) - { - this.app = app; - this.dom = dom; - this.batch = new SpriteBatch(); - this.bg = app.assets.getTexture(app.assets.MAP_00); - this.root = new Root(1); - this.root.setPadding(15); - feed(); - Gdx.input.setInputProcessor(getMultiplexer()); - this.inputBlocked = false; - this.inputDelay = 0f; - this.paused = false; - } - - protected abstract void draw(SpriteBatch batch); - @Override public void render(float delta) - { - if (paused) return; - - Gdx.gl.glClearColor(1, 1, 1, 1); - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - - camera.update(); - batch.setProjectionMatrix(camera.combined); - batch.begin(); - draw(batch); - batch.end(); - } - - @Override public void resize(int width, int height) - { - GdxBoardTest.debug(dom, String.format("resize (%d,%d)",width, height)); - if (width >= height) { - camera.viewportWidth = bg.getWidth(); - camera.viewportHeight = bg.getHeight() / (float)width * (float)height; - } else { - camera.viewportHeight = bg.getHeight(); - camera.viewportWidth = bg.getWidth() / (float)height * (float)width; - } - camera.viewportWidth *= WORLD_RATIO; - camera.viewportHeight *= WORLD_RATIO; - camera.update(); - root.resize( - camera.position.x - (camera.viewportWidth / 2f), - camera.position.y - (camera.viewportHeight / 2f), - camera.viewportWidth, - camera.viewportHeight - ); - } - - @Override public void dispose() - { - GdxBoardTest.debug(dom, "dispose()"); - batch.dispose(); - } - - @Override public void show() - { - GdxBoardTest.debug(dom, "show()"); - paused = false; - } - - @Override public void hide() - { - GdxBoardTest.debug(dom, "hide()"); - paused = true; - } - - @Override public void pause() - { - GdxBoardTest.debug(dom, "pause() "); - paused = true; - } - - @Override public void resume() - { - GdxBoardTest.debug(dom, "resume() "); - resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - paused = false; - } - - protected abstract void onTouch(int x, int y); - protected abstract void onZoom(float dz); - protected abstract void onDragged(int dx, int dy); - private InputMultiplexer getMultiplexer() - { - final InputMultiplexer multiplexer = new InputMultiplexer(); - multiplexer.addProcessor(new InputAdapter() { - @Override public boolean scrolled(int amount) - { - onZoom(amount * ZOOM_SCROLL_FACTOR); - return true; - } - @Override public boolean touchDown(int x, int y, int pointer, int button) - { - if (inputBlocked) return true; - if (button == Input.Buttons.LEFT) { - dragPos.set(x, y); - onTouch(x, y); - } - return true; - } - @Override public boolean touchDragged(int x, int y, int pointer) - { - int dx = (int) (dragPos.x - x); - int dy = (int) (dragPos.y - y); - dragPos.set(x, y); - onDragged(dx, dy); - return true; - } - }); - multiplexer.addProcessor(new GestureDetector(new GestureAdapter() { - @Override public boolean zoom(float initialDistance, float distance) - { - if (initialDistance > distance) - onZoom(ZOOM_GESTURE_FACTOR); - else - onZoom(-ZOOM_GESTURE_FACTOR); - inputBlocked = true; - inputDelay = INPUT_DELAY; - return true; - } - })); - - return multiplexer; - } -} diff --git a/test/src/ch/asynk/gdx/tabletop/test/Assets.java b/test/src/ch/asynk/gdx/tabletop/test/Assets.java deleted file mode 100644 index 112d2ae..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/Assets.java +++ /dev/null @@ -1,84 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.assets.loaders.FileHandleResolver; -import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGeneratorLoader; -import com.badlogic.gdx.graphics.g2d.freetype.FreetypeFontLoader; -import com.badlogic.gdx.graphics.g2d.freetype.FreetypeFontLoader.FreeTypeFontLoaderParameter; - -public class Assets extends ch.asynk.gdx.tabletop.Assets -{ - public static final String LOADING = "loading.atlas"; - - public static final String CORNER = "corner.png"; - public static final String MAP_00 = "map_00.png"; - public static final String CHESS = "chess.jpg"; - public static final String TRI = "triangle.png"; - public static final String FONT = "veteran-typewriter.ttf"; - public static final String FONT_20 = "size20.ttf"; - public static final String FONT_25 = "size25.ttf"; - public static final String PATCH = "ui-patch.png"; - public static final String SHERMAN = "sherman.png"; - - private final FreeTypeFontLoaderParameter params20; - private final FreeTypeFontLoaderParameter params25; - - public Assets() - { - super(); - final FileHandleResolver resolver = new InternalFileHandleResolver(); - setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver)); - setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver)); - params20 = new FreeTypeFontLoaderParameter(); - params20.fontFileName = FONT; - params20.fontParameters.size = 20; - params25 = new FreeTypeFontLoaderParameter(); - params25.fontFileName = FONT; - params25.fontParameters.size = 25; - } - - @Override public void dispose() - { - GdxBoardTest.debug("diagnostics:\n" + getDiagnostics() ); - clear(); - super.dispose(); - } - - public void loadLoading() - { - load(LOADING, TextureAtlas.class); - } - - public void unloadLoading() - { - unload(LOADING); - } - - public void loadApp() - { - load(MAP_00, Texture.class); - load(CHESS, Texture.class); - load(TRI, Texture.class); - load(CORNER, Texture.class); - load(PATCH, Texture.class); - load(SHERMAN, Texture.class); - load(FONT_20, BitmapFont.class, params20); - load(FONT_25, BitmapFont.class, params25); - } - - public void unloadApp() - { - unload(MAP_00); - unload(CHESS); - unload(TRI); - unload(CORNER); - unload(PATCH); - unload(SHERMAN); - unload(FONT_20); - unload(FONT_25); - } -} diff --git a/test/src/ch/asynk/gdx/tabletop/test/BoardScreen.java b/test/src/ch/asynk/gdx/tabletop/test/BoardScreen.java deleted file mode 100644 index 2fd3c4f..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/BoardScreen.java +++ /dev/null @@ -1,240 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.math.Vector2; - -import ch.asynk.gdx.tabletop.Camera; -import ch.asynk.gdx.tabletop.Board; -import ch.asynk.gdx.tabletop.board.BoardFactory; -import ch.asynk.gdx.tabletop.ui.Alignment; -import ch.asynk.gdx.tabletop.ui.Button; -import ch.asynk.gdx.tabletop.ui.Root; - -public class BoardScreen extends AbstractScreen -{ - - private static final boolean DEBUG = true; - - private class MyBoard - { - private final Assets assets; - private final Texture sherman; - private final Vector2 v; - public Texture map; - public Board board; - public int dx; - public int dy; - public int w; - public int h; - public float r; - - public MyBoard(final Assets assets) - { - this.assets = assets; - this.sherman = assets.getTexture(assets.SHERMAN); - this.v = new Vector2(); - } - - public void draw(SpriteBatch batch) - { - batch.draw(map, dx, dy, map.getWidth()/2, map.getHeight()/2, map.getWidth(), map.getHeight(), 1, 1, r, 0, 0, map.getWidth(), map.getHeight(), false, false); - batch.draw(sherman, v.x - (sherman.getWidth() / 2), v.y - (sherman.getHeight() / 2)); - } - - public void reset() - { - board.centerOf(0, 0, v); - } - - public boolean touch(float x, float y) - { - board.toBoard(x, y, v); - GdxBoardTest.debug("BoardScreen", String.format("touchDown [%d;%d] => [%d;%d]", (int)x, (int)y, (int)v.x, (int)v.y)); - board.centerOf((int)v.x, (int)v.y, v); - GdxBoardTest.debug("BoardScreen", String.format(" => [%d;%d]", (int)v.x, (int)v.y)); - return true; - } - - public void setHEX_V() - { - map = assets.getTexture(assets.MAP_00); - r = 0; - dx = 0; - dy = 0; - w = map.getWidth(); - h = map.getHeight(); - board = BoardFactory.getBoard(BoardFactory.BoardType.HEX, 110, 50, 103, BoardFactory.BoardOrientation.VERTICAL); - } - - public void setHEX_H() - { - map = assets.getTexture(assets.MAP_00); - r = 90; - dx = - ( map.getWidth() - map.getHeight() ) / 2; - dy = - dx; - w = map.getHeight(); - h = map.getWidth(); - board = BoardFactory.getBoard(BoardFactory.BoardType.HEX, 110, 103, 50, BoardFactory.BoardOrientation.HORIZONTAL); - } - - public void setSQUARE() - { - map = assets.getTexture(assets.CHESS); - r = 0; - dx = 0; - dy = 0; - w = map.getWidth(); - h = map.getHeight(); - board = BoardFactory.getBoard(BoardFactory.BoardType.SQUARE, 83, 5, 5); - } - - public void setTRI_H() - { - map = assets.getTexture(assets.TRI); - r = 0; - dx = 0; - dy = 0; - w = map.getWidth(); - h = map.getHeight(); - board = BoardFactory.getBoard(BoardFactory.BoardType.TRIANGLE, 150, 109, 53, BoardFactory.BoardOrientation.HORIZONTAL); - } - - public void setTRI_V() - { - map = assets.getTexture(assets.TRI); - r = 90; - dx = - ( map.getWidth() - map.getHeight() ) / 2; - dy = - dx; - w = map.getHeight(); - h = map.getWidth(); - board = BoardFactory.getBoard(BoardFactory.BoardType.TRIANGLE, 150, 16, 110, BoardFactory.BoardOrientation.VERTICAL); - } - } - - public enum State - { - HEX_V, HEX_H, SQUARE, TRI_H, TRI_V, DONE; - public State next() - { - switch(this) { - case HEX_V: - return HEX_H; - case HEX_H: - return SQUARE; - case SQUARE: - return TRI_H; - case TRI_H: - return TRI_V; - case TRI_V: - return DONE; - default: - return HEX_V; - } - } - } - private State state; - - private Camera cam; - private MyBoard board; - private Button btn; - private Root root; - - public BoardScreen(final GdxBoardTest app) - { - super(app, ""); - } - - @Override protected void feed() - { - this.board = new MyBoard(app.assets); - this.camera = this.cam = new Camera(10, board.w, board.h, 1.0f, 0.3f, false); - this.btn = new Button( - app.assets.getFont(app.assets.FONT_25), - app.assets.getNinePatch(app.assets.PATCH, 23, 23, 23 ,23), - 15); - this.btn.setAlignment(Alignment.BOTTOM_RIGHT); - this.btn.write("next"); - this.root = new Root(1); - this.root.add(btn); - this.root.setPadding(5); - setState(State.HEX_V); - } - - @Override public void draw(SpriteBatch batch) { } - @Override public void render(float delta) - { - if (paused) return; - - if (inputBlocked) { - inputDelay -= delta; - if (inputDelay <= 0f) - inputBlocked = false; - } - - Gdx.gl.glClearColor(0, 0, 0, 1); - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - - cam.applyBoardViewport(); - batch.setProjectionMatrix(cam.combined); - batch.begin(); - board.draw(batch); - batch.end(); - - cam.applyHudViewport(); - batch.setProjectionMatrix(cam.getHudMatrix()); - batch.begin(); - root.draw(batch); - batch.end(); - } - - @Override public void resize(int width, int height) - { - GdxBoardTest.debug("BoardScrean", String.format("resize (%d,%d)",width, height)); - cam.updateViewport(width, height); - root.resize(cam.getHud()); - } - - @Override protected void onDragged(int dx, int dy) - { - cam.translate(dx, dy); - } - - @Override protected void onTouch(int x, int y) - { - cam.unproject(x, y, boardTouch); - cam.unprojectHud(x, y, hudTouch); - if (btn.touch(hudTouch.x, hudTouch.y)) { - setState(state.next()); - } else { - board.touch(boardTouch.x, boardTouch.y); - } - } - - @Override protected void onZoom(float dz) - { - cam.zoom(dz); - resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - } - - private void setState(State state) - { - switch (state) { - case HEX_V: board.setHEX_V(); break; - case HEX_H: board.setHEX_H(); break; - case SQUARE: board.setSQUARE(); break; - case TRI_H: board.setTRI_H(); break; - case TRI_V: board.setTRI_V(); break; - case DONE: - cam.applyScreenViewport(); - this.app.switchToMenu(); - return; - } - board.reset(); - cam.setDimension(board.w, board.h); - onZoom(1); - this.state = state; - } -} diff --git a/test/src/ch/asynk/gdx/tabletop/test/DesktopLauncher.java b/test/src/ch/asynk/gdx/tabletop/test/DesktopLauncher.java deleted file mode 100644 index ca0b44a..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/DesktopLauncher.java +++ /dev/null @@ -1,14 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.backends.lwjgl.LwjglApplication; -import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; - -public class DesktopLauncher { - public static void main (String[] arg) { - LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); - new LwjglApplication(new GdxBoardTest(), config); - config.title = "gdx-tabletop Demo"; - config.width=800; - config.height=600; - } -} diff --git a/test/src/ch/asynk/gdx/tabletop/test/GdxBoardTest.java b/test/src/ch/asynk/gdx/tabletop/test/GdxBoardTest.java deleted file mode 100644 index 7e6bcd4..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/GdxBoardTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.Game; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Screen; - -public class GdxBoardTest extends Game -{ - private static final String DOM = "GdxBoardTest"; - - private enum State - { - NONE, - LOADING, - MENU, - UI, - BOARD, - EXIT - } - private State state; - - public final Assets assets = new Assets(); - - @Override public void create() - { - this.state = State.NONE; - Gdx.app.setLogLevel(Gdx.app.LOG_DEBUG); - debug(String.format("create() [%d;%d] %f", Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Gdx.graphics.getDensity())); - switchToLoading(); - } - - @Override public void dispose() - { - debug("dispose()"); - assets.clear(); - assets.dispose(); - } - - public static void error(String msg) - { - Gdx.app.error(DOM, msg); - } - - public static void debug(String msg) - { - Gdx.app.debug(DOM, msg); - } - - public static void debug(String from, String msg) - { - Gdx.app.debug(DOM, String.format("%s : %s", from, msg)); - } - - private void switchTo(Screen nextScreen, State nextState) - { - if (state == nextState) { - error("switch from and to " + state); - return; - } - if (state == State.LOADING) { - assets.unloadLoading(); - } - if (state != State.NONE) { - getScreen().dispose(); - } - setScreen(nextScreen); - this.state = nextState; - } - - public void switchToLoading() - { - assets.loadLoading(); - assets.finishLoading(); - switchTo(new LoadingScreen(this, () -> assets.loadApp(), () -> switchToMenu()), State.LOADING); - } - - public void switchToMenu() - { - switchTo(new MenuScreen(this), State.MENU); - } - - public void switchToUi() - { - switchTo(new UiScreen(this), State.UI); - } - - public void switchToBoard() - { - switchTo(new BoardScreen(this), State.BOARD); - } - - public void switchToExit() - { - Gdx.app.exit(); - switchTo(null, State.EXIT); - } -} diff --git a/test/src/ch/asynk/gdx/tabletop/test/LoadingScreen.java b/test/src/ch/asynk/gdx/tabletop/test/LoadingScreen.java deleted file mode 100644 index 61dce4c..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/LoadingScreen.java +++ /dev/null @@ -1,168 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Screen; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion; - -public class LoadingScreen implements Screen -{ - private static final String DOM = "LoadingScreen"; - - private final GdxBoardTest app; - private final SpriteBatch batch; - private final Color c; - private final OrthographicCamera camera; - - private final float BLINK_AFTER = 1f; - private final float ALPHA_FACTOR = 1.5f; - - private boolean paused; - private TextureAtlas atlas; - private AtlasRegion bar; - private AtlasRegion border; - private AtlasRegion loading; - private AtlasRegion loaded; - - private int x, y; - private int count; - private float percent; - private float alpha; - private boolean incr; - private boolean isLoaded; - - public interface LoadAction { - void call(); - } - private LoadAction onLoaded; - - public LoadingScreen(final GdxBoardTest app, LoadAction startLoading, LoadAction onLoaded) - { - this.app = app; - this.onLoaded = onLoaded; - this.batch = new SpriteBatch(); - this.c = batch.getColor(); - this.camera = new OrthographicCamera(); - int w = Gdx.graphics.getWidth(); - int h = Gdx.graphics.getHeight(); - this.camera.setToOrtho(false, w, h); - this.camera.update(); - this.paused = false; - atlas = app.assets.getAtlas(app.assets.LOADING); - bar = atlas.findRegion("bar"); - border = atlas.findRegion("border"); - loading = atlas.findRegion("loading"); - loaded = atlas.findRegion("loaded"); - computeCoords(w, h); - percent = 0f; - alpha = 1f; - incr = false; - isLoaded = false; - startLoading.call(); - } - - private void computeCoords(int width, int height) - { - x = (width - border.getRegionWidth()) / 2; - y = (height - border.getRegionHeight()) / 2; - } - - @Override public void render(float delta) - { - if (paused) return; - - if (!isLoaded) { - if (app.assets.update()) { - GdxBoardTest.debug(DOM, "assets loaded"); - isLoaded = true; - percent = 1f; - } else { - percent = app.assets.getProgress(); - } - } - - if (!isLoaded && percent >= 1f) { - count = 0; - alpha = 1f; - incr = false; - } - - delta *= ALPHA_FACTOR; - if (incr) { - alpha += delta; - if (alpha >= 1f ) { - alpha = 1f; - incr = false; - if (isLoaded) count += 1; - if (count >= BLINK_AFTER) { - onLoaded.call(); - return; - } - } - } else { - alpha -= delta; - if (alpha <= 0f ) { - alpha = 0f; - incr = true; - } - } - - Gdx.gl.glClearColor(0, 0, 0, 1); - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - - batch.setProjectionMatrix(camera.combined); - batch.begin(); - batch.setColor(c.r, c.g, c.b, 1f); - batch.draw(border, x, y); - batch.draw(bar, x + 4, y + 4, percent * bar.getRegionWidth(), bar.getRegionHeight()); - batch.setColor(c.r, c.g, c.b, alpha); - if (!isLoaded) { - batch.draw(loading, x, y + border.getRegionHeight() + 3); - } else { - batch.draw(loaded, x + border.getRegionWidth() - loaded.getRegionWidth(), y - loaded.getRegionHeight() - 3); - } - batch.end(); - } - - @Override public void resize(int width, int height) - { - if (paused) return; - GdxBoardTest.debug("LoadingScreen", String.format("resize (%d,%d)",width, height)); - this.camera.setToOrtho(false, width, height); - this.camera.update(); - computeCoords(width, height); - } - - @Override public void dispose() - { - GdxBoardTest.debug("LoadingScreen", "dispose()"); - batch.dispose(); - } - - @Override public void show() - { - GdxBoardTest.debug("LoadingScreen", "show()"); - } - - @Override public void hide() - { - GdxBoardTest.debug("LoadingScreen", "hide()"); - } - - @Override public void pause() - { - paused = true; - GdxBoardTest.debug("LoadingScreen", "pause() "); - } - - @Override public void resume() - { - GdxBoardTest.debug("LoadingScreen", "resume() "); - resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - paused = false; - } -} diff --git a/test/src/ch/asynk/gdx/tabletop/test/MenuScreen.java b/test/src/ch/asynk/gdx/tabletop/test/MenuScreen.java deleted file mode 100644 index bf94e75..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/MenuScreen.java +++ /dev/null @@ -1,86 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.Sprite; -import com.badlogic.gdx.graphics.OrthographicCamera; - -import ch.asynk.gdx.tabletop.ui.Alignment; -import ch.asynk.gdx.tabletop.ui.Menu; - -public class MenuScreen extends AbstractScreen -{ - private Sprite corner; - private Menu menu; - - public MenuScreen(final GdxBoardTest app) - { - super(app, "MenuScreen"); - } - - @Override protected void feed() - { - final Assets assets = app.assets; - this.corner = new Sprite(assets.getTexture(assets.CORNER)); - - this.menu = new Menu( - assets.getFont(assets.FONT_25), - assets.getNinePatch(assets.PATCH, 23, 23, 23 ,23), - "Menu", new String[]{"UI","Board","Exit"}); - this.menu.setAlignment(Alignment.MIDDLE_CENTER); - this.menu.setPaddings(5, 5); - this.menu.setSpacings(10, 5); - this.menu.setPadding(20); - this.menu.setLabelsOffset(10); - this.root.add(this.menu); - - this.camera = new OrthographicCamera(bg.getWidth() * WORLD_RATIO, bg.getHeight() * WORLD_RATIO); - this.camera.position.set(bg.getWidth() / 2f, bg.getHeight() / 2f, 0); - this.camera.update(); - } - - @Override protected void draw(SpriteBatch batch) - { - batch.draw(bg, 0, 0); - drawCorners(batch); - root.draw(batch); - } - - private void drawCorners(SpriteBatch batch) - { - float right = root.getInnerX() + root.getInnerWidth() - corner.getWidth(); - float top = root.getInnerY() + root.getInnerHeight() - corner.getHeight(); - corner.setRotation(0); - corner.setPosition(root.getInnerX(), top); - corner.draw(batch); - corner.setRotation(90); - corner.setPosition(root.getInnerX(), root.getInnerY()); - corner.draw(batch); - corner.setRotation(180); - corner.setPosition(right, root.getInnerY()); - corner.draw(batch); - corner.setPosition(right, top); - corner.setRotation(270); - corner.draw(batch); - } - - @Override protected void onZoom(float dz) { } - @Override protected void onDragged(int dx, int dy) { } - @Override protected void onTouch(int x, int y) - { - hudTouch.set(x, y, 0); - camera.unproject(hudTouch); - if (root.touch(hudTouch.x, hudTouch.y)) { - switch(menu.touched()) { - case 0: - app.switchToUi(); - break; - case 1: - app.switchToBoard(); - break; - case 2: - app.switchToExit(); - break; - } - } - } -} diff --git a/test/src/ch/asynk/gdx/tabletop/test/UiScreen.java b/test/src/ch/asynk/gdx/tabletop/test/UiScreen.java deleted file mode 100644 index 261d461..0000000 --- a/test/src/ch/asynk/gdx/tabletop/test/UiScreen.java +++ /dev/null @@ -1,103 +0,0 @@ -package ch.asynk.gdx.tabletop.test; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.NinePatch; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.OrthographicCamera; - -import ch.asynk.gdx.tabletop.ui.Alignment; -import ch.asynk.gdx.tabletop.ui.Button; - -public class UiScreen extends AbstractScreen -{ - private Button hello; - - public UiScreen(final GdxBoardTest app) - { - super(app, "UiScreen"); - } - - public enum State - { - POSITIONS, DONE; - public State next() - { - switch(this) { - case POSITIONS: - return DONE; - default: - return POSITIONS; - } - } - } - private State state; - - @Override protected void feed() - { - final NinePatch patch = app.assets.getNinePatch(app.assets.PATCH, 23, 23, 23 ,23); - final BitmapFont font = app.assets.getFont(app.assets.FONT_25); - - this.hello = new Button(font, patch, 10, 15); - this.hello.write("Hello"); - this.root.add(this.hello); - - this.camera = new OrthographicCamera(bg.getWidth() * WORLD_RATIO, bg.getHeight() * WORLD_RATIO); - this.camera.position.set(bg.getWidth() / 2f, bg.getHeight() / 2f, 0); - this.camera.update(); - setState(State.POSITIONS); - } - - private void setState(State state) - { - switch (state) { - case DONE: - app.switchToMenu(); - } - this.state = state; - } - - @Override protected void draw(SpriteBatch batch) - { - batch.draw(bg, 0, 0); - switch (state) { - case POSITIONS: - drawButtons(batch); - break; - } - } - - private void drawButtons(SpriteBatch batch) - { - hello.write("hello"); - hello.setAlignment(Alignment.TOP_LEFT); - hello.setLabelAlignment(Alignment.BOTTOM_RIGHT); - root.draw(batch); - drawHello(batch, Alignment.TOP_CENTER, Alignment.BOTTOM_CENTER); - drawHello(batch, Alignment.TOP_RIGHT, Alignment.BOTTOM_LEFT); - drawHello(batch, Alignment.MIDDLE_LEFT, Alignment.MIDDLE_RIGHT); - drawHello(batch, Alignment.MIDDLE_RIGHT, Alignment.MIDDLE_LEFT); - drawHello(batch, Alignment.BOTTOM_LEFT, Alignment.TOP_RIGHT); - drawHello(batch, Alignment.BOTTOM_CENTER, Alignment.TOP_CENTER); - drawHello(batch, Alignment.BOTTOM_RIGHT, Alignment.TOP_LEFT); - hello.write("next"); - drawHello(batch, Alignment.MIDDLE_CENTER, Alignment.MIDDLE_CENTER); - } - - private void drawHello(SpriteBatch batch, Alignment alignment1, Alignment alignment2) - { - hello.setAlignment(alignment1); - hello.setLabelAlignment(alignment2); - hello.draw(batch); - } - - @Override protected void onZoom(float dz) { } - @Override protected void onDragged(int dx, int dy) { } - @Override protected void onTouch(int x, int y) - { - hudTouch.set(x, y, 0); - camera.unproject(hudTouch); - if (root.touch(hudTouch.x, hudTouch.y)) { - setState(state.next()); - } - } -} -- cgit v1.1-2-g2b99