diff --git a/client/src/Board.css b/client/src/Board.css index ffdbabe..39aed27 100644 --- a/client/src/Board.css +++ b/client/src/Board.css @@ -30,5 +30,61 @@ .Pip { position: absolute; background-size: 600% auto; /* pip-numbers is a 6x6 grid of pip images */ + width: 2em; + height: 2em; transform: translate(-50%, -50%); + clip-path: circle(48%); +} + +.Roads[disabled], +.Corners[disabled] { + pointer-events: none; +} + +.Corner { + position: absolute; + display: flex; + align-items: center; + justify-items: center; + box-sizing: border-box; + border: 1px solid transparent; +/* border: 2px solid black;*/ + border-radius: 50%; + width: 2.5em; + height: 2.5em; + transform: translate(-50%, -50%); +} + +.Corner .Option { + background-color: rgba(255, 255, 255, 0.5); +} + +.Corner:hover { + border-color: black; +} + +.Road { + position: absolute; + display: flex; + align-items: center; + justify-items: center; + box-sizing: border-box; + border: 1px solid transparent; +/* border: 2px solid black; */ + transform-origin: 50% 0; + width: 1.75em; + height: 2.5em; +} + +.Road .Option { + background-color: rgba(255, 255, 255, 0.5); +} + +.Road:hover { + border-color: black; +} + +.Selected { + background-color: rgba(255, 238, 0, 0.5); + box-shadow: 5px 5px 5px black; } \ No newline at end of file diff --git a/client/src/Board.js b/client/src/Board.js index 8f45fcc..5d380bd 100644 --- a/client/src/Board.js +++ b/client/src/Board.js @@ -5,32 +5,218 @@ const base = process.env.PUBLIC_URL; const assetsPath = `${base}/assets`; const Board = ({ game }) => { - const rows = [3, 4, 5, 4, 3]; + const rows = [3, 4, 5, 4, 3, 2]; /* The final row of 2 is to place roads and corners */ const [signature, setSignature] = useState(""); const [pips, setPips] = useState(<>); const [borders, setBorders] = useState(<>); const [tiles, setTiles] = useState(<>); + const [corners, setCorners] = useState(<>); + const [roads, setRoads] = useState(<>); + const [transform, setTransform] = useState(1); - const scale = 1; const hexRatio = 1.1547, - tileWidth = scale * 67, + tileWidth = 67, tileHalfWidth = tileWidth * 0.5, tileHeight = tileWidth * hexRatio, - borderOffset = scale * 86; /* ~1/10th border image width... hand tuned */ + tileHalfHeight = tileHeight * 0.5, + radius = tileHeight * 2, + borderOffset = 86; /* ~1/10th border image width... hand tuned */ /* Actual sizing */ const - tileImageWidth = scale * 90, /* Based on hand tuned and image width */ + tileImageWidth = 90, /* Based on hand tuned and image width */ tileImageHeight = tileImageWidth/hexRatio, borderImageWidth = (2 + 2/3) * tileImageWidth, /* 2.667 * .Tile.width */ borderImageHeight = borderImageWidth * 0.29; /* 0.29 * .Border.height */ + + const Road = ({road}) => { + const onClick = (event) => { + console.log(`Road clicked: ${road.index}`); + const nodes = document.querySelectorAll('.Road.Selected'); + for (let i = 0; i < nodes.length; i++) { + const el = nodes[i]; + if (el !== event.target) { + el.classList.remove('Selected'); + } + } + event.target.classList.toggle('Selected'); + }; + return
; + }; + const Corner = ({corner}) => { + const onClick = (event) => { + console.log(`Corner clicked: ${corner.index}`); + const nodes = document.querySelectorAll('.Corner.Selected'); + for (let i = 0; i < nodes.length; i++) { + const el = nodes[i]; + if (el !== event.target) { + el.classList.remove('Selected'); + } + } + event.target.classList.toggle('Selected'); + }; + return
; + }; + + const generateRoads = () => { + let row = 0, rowCount = 0; + let y = -2.5 + tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, + x = -tileHalfHeight -(rows[row] - 1) * 0.5 * tileHeight; + + let index = 0; + let road; + + const corners = []; + + for (let i = 0; i < 21; i++) { + const lastRow = row === rows.length - 1; + if (row > 2 && rowCount === 0) { + road = { + index: index++, + angle: -60, + top: y-0.5*tileHalfHeight, + left: x-tileHalfHeight + }; + corners.push(); + } + + road = { + index: index++, + angle: 240, + top: y, + left: x + }; + corners.push(); + + road = { + index: index++, + angle: -60, + top: y-0.5*tileHalfHeight, + left: x+tileHalfHeight + }; + corners.push(); + + if (!lastRow) { + road = { + index: index++, + angle: 0, + top: y, + left: x + }; + corners.push(); + } + + if (++rowCount === rows[row]) { + if (!lastRow) { + road = { + index: index++, + angle: 0, + top: y, + left: x+2.*tileHalfHeight + }; + corners.push(); + } + + if (row > 2) { + road = { + index: index++, + angle: 60, + top: y-0.5*tileHalfHeight, + left: x+3.*tileHalfHeight + }; + corners.push(); + } + + row++; + rowCount = 0; + y += tileHeight - 10.5; + x = -tileHalfHeight - (rows[row] - 1) * 0.5 * tileHeight; + } else { + x += tileHeight; + } + } + return corners; + } + + const generateCorners = () => { + let row = 0, rowCount = 0; + let y = -8 + 0.5 * tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, + x = -tileHalfHeight -(rows[row] - 1) * 0.5 * tileHeight; + let index = 0; + const corners = []; + let corner; + + for (let i = 0; i < 21; i++) { + if (row > 2 && rowCount === 0) { + corner = { + index: index++, + top: y-0.5*tileHalfHeight, + left: x-tileHalfHeight + }; + corners.push(); + } + + corner = { + index: index++, + top: y, + left: x + }; + corners.push(); + + corner = { + index: index++, + top: y-0.5*tileHalfHeight, + left: x+tileHalfHeight + }; + corners.push(); + + if (++rowCount === rows[row]) { + corner = { + index: index++, + top: y, + left: x+2.*tileHalfHeight + }; + corners.push(); + + if (row > 2) { + corner = { + index: index++, + top: y-0.5*tileHalfHeight, + left: x+3.*tileHalfHeight + }; + corners.push(); + } + + row++; + rowCount = 0; + y += tileHeight - 10.5; + x = -tileHalfHeight - (rows[row] - 1) * 0.5 * tileHeight; + } else { + x += tileHeight; + } + } + return corners; + } const generatePips = () => { let row = 0, rowCount = 0; - let y = tileHalfWidth - rows.length * 0.5 * tileWidth, + let y = tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, x = -(rows[row] - 1) * 0.5 * tileHeight; return game.pipOrder.map(order => { const pip = game.pips[order]; @@ -39,8 +225,6 @@ const Board = ({ game }) => { key={`pip-${order}`} className="Pip" style={{ - width: `${scale*2}em`, - height: `${scale*2}em`, top: `${y}px`, left: `${x}px`, backgroundImage: `url(${assetsPath}/gfx/pip-numbers.png)`, @@ -64,7 +248,7 @@ const Board = ({ game }) => { const generateTiles = () => { let row = 0, rowCount = 0; - let y = tileHalfWidth - rows.length * 0.5 * tileWidth, + let y = tileHalfWidth - (rows.length - 1) * 0.5 * tileWidth, x = -(rows[row] - 1) * 0.5 * tileHeight; return game.tileOrder.map(order => { const tile = game.tiles[order]; @@ -95,8 +279,7 @@ const Board = ({ game }) => { }; const generateBorders = () => { - const radius = tileHeight * 2, - sides = 6; + const sides = 6; let side = -1; return game.borderOrder.map(order => { const border = game.borders[order]; @@ -121,11 +304,15 @@ const Board = ({ game }) => { }); }; + /* If the game is loaded, and the signature is different, + * regenerate everything */ if (game && game.signature !== signature) { console.log(`Generate for ${game.signature}`); setPips(generatePips); setBorders(generateBorders); setTiles(generateTiles); + setCorners(generateCorners); + setRoads(generateRoads); setSignature(game.signature); } else { if (!game) { @@ -133,6 +320,8 @@ const Board = ({ game }) => { } } + /* Adjust the 'transform: scale' for the BoardBox + * so the board fills the Board */ const board = document.querySelector('.Board'); if (board) { const width = board.offsetWidth, @@ -143,7 +332,7 @@ const Board = ({ game }) => { } else { _transform = width / (450. * hexRatio); } - if (_transform != transform) { + if (_transform !== transform) { const boardBox = board.querySelector('.BoardBox'); if (boardBox) { console.log(`Setting transofrm scale to ${_transform}`); @@ -159,6 +348,14 @@ const Board = ({ game }) => { { borders } { tiles } { pips } + { game && <> +
+ { corners } +
+
+ { roads } +
+ }
); diff --git a/client/src/Table.js b/client/src/Table.js index f52e75d..d0c49cc 100755 --- a/client/src/Table.js +++ b/client/src/Table.js @@ -1021,50 +1021,52 @@ class Table extends React.Component { } -
- { game && game.state === "active" && <> -
In hand
-
- - - - - -
-
Available to play
-
- - -
- - + { game && game.showCards && +
+ { game && game.state === "active" && <> +
In hand
+
+ + + + +
-
-
Points
-
-
- - - +
Available to play
+
+ + +
+ + +
-
-
- - -
-
-
Stats
-
-
Points: 7
-
Cards: {this.state.total}
-
Roads remaining: 4
-
Longest road: 7
-
Cities remaining: 4
-
Settlements remaining: 5
+
Points
+
+
+ + + +
-
- } -
+
+ + +
+
+
Stats
+
+
Points: 7
+
Cards: {this.state.total}
+
Roads remaining: 4
+
Longest road: 7
+
Cities remaining: 4
+
Settlements remaining: 5
+
+
+ } +
+ } { this.state.error &&
{this.state.error}
} diff --git a/client/src/assets/tabletop.png b/client/src/assets/tabletop.png index e08cc14..70e9d66 100644 Binary files a/client/src/assets/tabletop.png and b/client/src/assets/tabletop.png differ