COrner and road selection is possible
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
ade3bb0830
commit
63a41723be
@ -30,5 +30,61 @@
|
|||||||
.Pip {
|
.Pip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-size: 600% auto; /* pip-numbers is a 6x6 grid of pip images */
|
background-size: 600% auto; /* pip-numbers is a 6x6 grid of pip images */
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
transform: translate(-50%, -50%);
|
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;
|
||||||
}
|
}
|
@ -5,32 +5,218 @@ const base = process.env.PUBLIC_URL;
|
|||||||
const assetsPath = `${base}/assets`;
|
const assetsPath = `${base}/assets`;
|
||||||
|
|
||||||
const Board = ({ game }) => {
|
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 [signature, setSignature] = useState("");
|
||||||
const [pips, setPips] = useState(<></>);
|
const [pips, setPips] = useState(<></>);
|
||||||
const [borders, setBorders] = useState(<></>);
|
const [borders, setBorders] = useState(<></>);
|
||||||
const [tiles, setTiles] = useState(<></>);
|
const [tiles, setTiles] = useState(<></>);
|
||||||
|
const [corners, setCorners] = useState(<></>);
|
||||||
|
const [roads, setRoads] = useState(<></>);
|
||||||
|
|
||||||
const [transform, setTransform] = useState(1);
|
const [transform, setTransform] = useState(1);
|
||||||
|
|
||||||
const scale = 1;
|
|
||||||
const
|
const
|
||||||
hexRatio = 1.1547,
|
hexRatio = 1.1547,
|
||||||
tileWidth = scale * 67,
|
tileWidth = 67,
|
||||||
tileHalfWidth = tileWidth * 0.5,
|
tileHalfWidth = tileWidth * 0.5,
|
||||||
tileHeight = tileWidth * hexRatio,
|
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 */
|
/* Actual sizing */
|
||||||
const
|
const
|
||||||
tileImageWidth = scale * 90, /* Based on hand tuned and image width */
|
tileImageWidth = 90, /* Based on hand tuned and image width */
|
||||||
tileImageHeight = tileImageWidth/hexRatio,
|
tileImageHeight = tileImageWidth/hexRatio,
|
||||||
borderImageWidth = (2 + 2/3) * tileImageWidth, /* 2.667 * .Tile.width */
|
borderImageWidth = (2 + 2/3) * tileImageWidth, /* 2.667 * .Tile.width */
|
||||||
borderImageHeight = borderImageWidth * 0.29; /* 0.29 * .Border.height */
|
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 <div className="Road"
|
||||||
|
onClick={onClick}
|
||||||
|
style={{
|
||||||
|
transform: `translate(-50%, -50%) rotate(${road.angle}deg)`,
|
||||||
|
top: `${road.top}px`,
|
||||||
|
left: `${road.left}px`
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 <div className="Corner"
|
||||||
|
onClick={onClick}
|
||||||
|
style={{
|
||||||
|
top: `${corner.top}px`,
|
||||||
|
left: `${corner.left}px`
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 key={`road-${index}}`} road={road}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
road = {
|
||||||
|
index: index++,
|
||||||
|
angle: 240,
|
||||||
|
top: y,
|
||||||
|
left: x
|
||||||
|
};
|
||||||
|
corners.push(<Road key={`road-${index}}`} road={road}/>);
|
||||||
|
|
||||||
|
road = {
|
||||||
|
index: index++,
|
||||||
|
angle: -60,
|
||||||
|
top: y-0.5*tileHalfHeight,
|
||||||
|
left: x+tileHalfHeight
|
||||||
|
};
|
||||||
|
corners.push(<Road key={`road-${index}}`} road={road}/>);
|
||||||
|
|
||||||
|
if (!lastRow) {
|
||||||
|
road = {
|
||||||
|
index: index++,
|
||||||
|
angle: 0,
|
||||||
|
top: y,
|
||||||
|
left: x
|
||||||
|
};
|
||||||
|
corners.push(<Road key={`road-${index}}`} road={road}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++rowCount === rows[row]) {
|
||||||
|
if (!lastRow) {
|
||||||
|
road = {
|
||||||
|
index: index++,
|
||||||
|
angle: 0,
|
||||||
|
top: y,
|
||||||
|
left: x+2.*tileHalfHeight
|
||||||
|
};
|
||||||
|
corners.push(<Road key={`road-${index}}`} road={road}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row > 2) {
|
||||||
|
road = {
|
||||||
|
index: index++,
|
||||||
|
angle: 60,
|
||||||
|
top: y-0.5*tileHalfHeight,
|
||||||
|
left: x+3.*tileHalfHeight
|
||||||
|
};
|
||||||
|
corners.push(<Road key={`road-${index}}`} road={road}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 key={`corner-${index}}`} corner={corner}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
corner = {
|
||||||
|
index: index++,
|
||||||
|
top: y,
|
||||||
|
left: x
|
||||||
|
};
|
||||||
|
corners.push(<Corner key={`corner-${index}}`} corner={corner}/>);
|
||||||
|
|
||||||
|
corner = {
|
||||||
|
index: index++,
|
||||||
|
top: y-0.5*tileHalfHeight,
|
||||||
|
left: x+tileHalfHeight
|
||||||
|
};
|
||||||
|
corners.push(<Corner key={`corner-${index}}`} corner={corner}/>);
|
||||||
|
|
||||||
|
if (++rowCount === rows[row]) {
|
||||||
|
corner = {
|
||||||
|
index: index++,
|
||||||
|
top: y,
|
||||||
|
left: x+2.*tileHalfHeight
|
||||||
|
};
|
||||||
|
corners.push(<Corner key={`corner-${index}}`} corner={corner}/>);
|
||||||
|
|
||||||
|
if (row > 2) {
|
||||||
|
corner = {
|
||||||
|
index: index++,
|
||||||
|
top: y-0.5*tileHalfHeight,
|
||||||
|
left: x+3.*tileHalfHeight
|
||||||
|
};
|
||||||
|
corners.push(<Corner key={`corner-${index}}`} corner={corner}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
row++;
|
||||||
|
rowCount = 0;
|
||||||
|
y += tileHeight - 10.5;
|
||||||
|
x = -tileHalfHeight - (rows[row] - 1) * 0.5 * tileHeight;
|
||||||
|
} else {
|
||||||
|
x += tileHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return corners;
|
||||||
|
}
|
||||||
|
|
||||||
const generatePips = () => {
|
const generatePips = () => {
|
||||||
let row = 0, rowCount = 0;
|
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;
|
x = -(rows[row] - 1) * 0.5 * tileHeight;
|
||||||
return game.pipOrder.map(order => {
|
return game.pipOrder.map(order => {
|
||||||
const pip = game.pips[order];
|
const pip = game.pips[order];
|
||||||
@ -39,8 +225,6 @@ const Board = ({ game }) => {
|
|||||||
key={`pip-${order}`}
|
key={`pip-${order}`}
|
||||||
className="Pip"
|
className="Pip"
|
||||||
style={{
|
style={{
|
||||||
width: `${scale*2}em`,
|
|
||||||
height: `${scale*2}em`,
|
|
||||||
top: `${y}px`,
|
top: `${y}px`,
|
||||||
left: `${x}px`,
|
left: `${x}px`,
|
||||||
backgroundImage: `url(${assetsPath}/gfx/pip-numbers.png)`,
|
backgroundImage: `url(${assetsPath}/gfx/pip-numbers.png)`,
|
||||||
@ -64,7 +248,7 @@ const Board = ({ game }) => {
|
|||||||
|
|
||||||
const generateTiles = () => {
|
const generateTiles = () => {
|
||||||
let row = 0, rowCount = 0;
|
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;
|
x = -(rows[row] - 1) * 0.5 * tileHeight;
|
||||||
return game.tileOrder.map(order => {
|
return game.tileOrder.map(order => {
|
||||||
const tile = game.tiles[order];
|
const tile = game.tiles[order];
|
||||||
@ -95,8 +279,7 @@ const Board = ({ game }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const generateBorders = () => {
|
const generateBorders = () => {
|
||||||
const radius = tileHeight * 2,
|
const sides = 6;
|
||||||
sides = 6;
|
|
||||||
let side = -1;
|
let side = -1;
|
||||||
return game.borderOrder.map(order => {
|
return game.borderOrder.map(order => {
|
||||||
const border = game.borders[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) {
|
if (game && game.signature !== signature) {
|
||||||
console.log(`Generate for ${game.signature}`);
|
console.log(`Generate for ${game.signature}`);
|
||||||
setPips(generatePips);
|
setPips(generatePips);
|
||||||
setBorders(generateBorders);
|
setBorders(generateBorders);
|
||||||
setTiles(generateTiles);
|
setTiles(generateTiles);
|
||||||
|
setCorners(generateCorners);
|
||||||
|
setRoads(generateRoads);
|
||||||
setSignature(game.signature);
|
setSignature(game.signature);
|
||||||
} else {
|
} else {
|
||||||
if (!game) {
|
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');
|
const board = document.querySelector('.Board');
|
||||||
if (board) {
|
if (board) {
|
||||||
const width = board.offsetWidth,
|
const width = board.offsetWidth,
|
||||||
@ -143,7 +332,7 @@ const Board = ({ game }) => {
|
|||||||
} else {
|
} else {
|
||||||
_transform = width / (450. * hexRatio);
|
_transform = width / (450. * hexRatio);
|
||||||
}
|
}
|
||||||
if (_transform != transform) {
|
if (_transform !== transform) {
|
||||||
const boardBox = board.querySelector('.BoardBox');
|
const boardBox = board.querySelector('.BoardBox');
|
||||||
if (boardBox) {
|
if (boardBox) {
|
||||||
console.log(`Setting transofrm scale to ${_transform}`);
|
console.log(`Setting transofrm scale to ${_transform}`);
|
||||||
@ -159,6 +348,14 @@ const Board = ({ game }) => {
|
|||||||
{ borders }
|
{ borders }
|
||||||
{ tiles }
|
{ tiles }
|
||||||
{ pips }
|
{ pips }
|
||||||
|
{ game && <>
|
||||||
|
<div className="Corners" disabled={game.state !== 'active'}>
|
||||||
|
{ corners }
|
||||||
|
</div>
|
||||||
|
<div className="Roads" disabled={true || game.state !== 'active'}>
|
||||||
|
{ roads }
|
||||||
|
</div>
|
||||||
|
</> }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1021,50 +1021,52 @@ class Table extends React.Component {
|
|||||||
<GameOrder table={this}/>
|
<GameOrder table={this}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className="Cards">
|
{ game && game.showCards &&
|
||||||
{ game && game.state === "active" && <>
|
<div className="Cards">
|
||||||
<div>In hand</div>
|
{ game && game.state === "active" && <>
|
||||||
<div className="Hand">
|
<div>In hand</div>
|
||||||
<Resource type="wood" count={this.state.wood}/>
|
<div className="Hand">
|
||||||
<Resource type="wheat" count={this.state.wheat}/>
|
<Resource type="wood" count={this.state.wood}/>
|
||||||
<Resource type="stone" count={this.state.stone}/>
|
<Resource type="wheat" count={this.state.wheat}/>
|
||||||
<Resource type="brick" count={this.state.brick}/>
|
<Resource type="stone" count={this.state.stone}/>
|
||||||
<Resource type="sheep" count={this.state.sheep}/>
|
<Resource type="brick" count={this.state.brick}/>
|
||||||
</div>
|
<Resource type="sheep" count={this.state.sheep}/>
|
||||||
<div>Available to play</div>
|
|
||||||
<div className="Hand">
|
|
||||||
<Development type="monopoly" count="1"/>
|
|
||||||
<Development type="army-" max="14" count="4"/>
|
|
||||||
<div className="Stack">
|
|
||||||
<Development type="vp-library" count="1"/>
|
|
||||||
<Development type="vp-market" count="1"/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>Available to play</div>
|
||||||
<div>Points</div>
|
<div className="Hand">
|
||||||
<div className="Hand">
|
<Development type="monopoly" count="1"/>
|
||||||
<div className="Stack">
|
<Development type="army-" max="14" count="4"/>
|
||||||
<Development type="vp-library" count="1"/>
|
<div className="Stack">
|
||||||
<Development type="vp-palace" count="1"/>
|
<Development type="vp-library" count="1"/>
|
||||||
<Development type="army-" max="14" count="6"/>
|
<Development type="vp-market" count="1"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>Points</div>
|
||||||
<div className="Hand">
|
<div className="Hand">
|
||||||
<Placard type="largest-army" count="1"/>
|
<div className="Stack">
|
||||||
<Placard type="longest-road" count="1"/>
|
<Development type="vp-library" count="1"/>
|
||||||
</div>
|
<Development type="vp-palace" count="1"/>
|
||||||
<div className="Statistics">
|
<Development type="army-" max="14" count="6"/>
|
||||||
<div>Stats</div>
|
</div>
|
||||||
<div>
|
|
||||||
<div>Points: 7</div>
|
|
||||||
<div>Cards: {this.state.total} </div>
|
|
||||||
<div>Roads remaining: 4</div>
|
|
||||||
<div>Longest road: 7</div>
|
|
||||||
<div>Cities remaining: 4</div>
|
|
||||||
<div>Settlements remaining: 5</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="Hand">
|
||||||
</> }
|
<Placard type="largest-army" count="1"/>
|
||||||
</div>
|
<Placard type="longest-road" count="1"/>
|
||||||
|
</div>
|
||||||
|
<div className="Statistics">
|
||||||
|
<div>Stats</div>
|
||||||
|
<div>
|
||||||
|
<div>Points: 7</div>
|
||||||
|
<div>Cards: {this.state.total} </div>
|
||||||
|
<div>Roads remaining: 4</div>
|
||||||
|
<div>Longest road: 7</div>
|
||||||
|
<div>Cities remaining: 4</div>
|
||||||
|
<div>Settlements remaining: 5</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</> }
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
{ this.state.error && <Paper className="Error"><div>{this.state.error}</div></Paper> }
|
{ this.state.error && <Paper className="Error"><div>{this.state.error}</div></Paper> }
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
Loading…
x
Reference in New Issue
Block a user