1
0

Added BoardPieces and PlayerStatus

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-03-06 14:48:51 -08:00
parent a4f75c8c0b
commit b92f638dda
6 changed files with 236 additions and 16 deletions

View File

@ -0,0 +1,49 @@
.BoardPieces {
display: flex;
flex-direction: column;
position: absolute;
height: 6rem;
left: 1rem;
bottom: 8rem; /* 1rem over top of Resource cards in hand */
width: 20rem;
z-index: 1000;
border-bottom: 1px solid black;
padding-bottom: 0.5rem;
margin-bottom: 0.5rem;
}
.BoardPieces > div {
display: flex;
justify-items: flex-start;
}
.BoardPieces[data-active="true"] > div > div {
filter: drop-shadow(0px 0px 5px black);
cursor: pointer;
}
.BoardPieces[data-active="true"] > div > div:hover {
filter: drop-shadow(0px 0px 5px white);
}
.BoardPieces .Shape {
margin: 0.25rem;
margin-bottom: 0.5rem;
}
.BoardPieces .Road .Shape {
width: 0.5rem;
height: 1.5rem;
}
.BoardPieces .Settlement .Shape {
width: 1.25rem;
height: 1.25rem;
clip-path: polygon(50% 0%,70% 15%,70% 2%,90% 2%,90% 30%,100% 40%,100% 100%,65% 100%,65% 65%,35% 65%,35% 100%,0% 100%,0% 40%);
}
.BoardPieces .City .Shape {
width: 1.25rem;
height: 1.25rem;
clip-path: polygon(15% 0%,39% 23%,39% 52%,100% 56%,100% 74%,100% 100%,80% 100%,63% 100%,62% 75%,46% 75%,47% 100%,0% 100%,0% 24%);
}

54
client/src/BoardPieces.js Normal file
View File

@ -0,0 +1,54 @@
import React from "react";
import "./BoardPieces.css";
import { useStyles } from './Styles.js';
const Road = ({ color, onClick }) => {
const classes = useStyles();
return <div className="Road" onClick={() => onClick('road')}><div className={['Shape', classes[color]].join(' ')}/></div>;
}
const Settlement = ({ color, onClick }) => {
const classes = useStyles();
return <div className="Settlement" onClick={() => onClick('settlement')}><div className={['Shape', classes[color]].join(' ')}/></div>;
}
const City = ({ color, onClick }) => {
const classes = useStyles();
return <div className="City" onClick={() => onClick('city')}><div className={['Shape', classes[color]].join(' ')}/></div>;
}
const BoardPieces = ({ table, color, onClick }) => {
if (!table.game || !table.game.player) {
return <></>;
}
const player = table.game.players[color];
if (!player) {
return <></>;
}
const roads = [];
for (let i = 0; i < player.roads; i++) {
roads.push(<Road onClick={onClick} key={`road-${i}`} color={color}/>);
}
const settlements = [];
for (let i = 0; i < player.settlements; i++) {
settlements.push(<Settlement onClick={onClick} key={`settlement-${i}`} color={color}/>);
}
const cities = [];
for (let i = 0; i < player.cities; i++) {
cities.push(<City onClick={onClick} key={`city-${i}`} color={color}/>);
}
return (
<div className='BoardPieces' data-active={onClick !== undefined}>
<div className='Cities'>{cities}</div>
<div className='Settlements'>{settlements}</div>
<div className='Roads'>{roads}</div>
</div>
);
};
export default BoardPieces;

View File

@ -0,0 +1,46 @@
.PlayersStatus {
display: flex;
flex-direction: column;
position: absolute;
left: 1rem;
bottom: 15rem;
border-bottom: 1px solid black;
margin-bottom: 0.5rem;
color: #d0d0d0;
pointer-events: none;
}
.PlayersStatus .Player {
margin-bottom: 0.5rem;
}
.PlayersStatus .Player .Who {
color: white;
display: inline-flex;
align-items: center;
}
.PlayersStatus .What {
margin-left: 0.25rem;
margin-top: 0.25rem;
}
.PlayersStatus .PlayerColor {
width: 1rem;
height: 1rem;
}
.PlayersStatus .Shrunken {
position: relative;
height: 5.75rem;
display: flex;
}
.PlayersStatus .Shrunken .BoardPieces {
transform-origin: 0 100%;
transform: scale(0.75);
bottom: 0;
left: 0;
border-bottom: none;
margin-bottom: 0;
}

View File

@ -0,0 +1,41 @@
import React from "react";
import Resource from './Resource.js';
import "./PlayersStatus.css";
import BoardPieces from './BoardPieces.js';
import { getPlayerName } from './Common.js';
import PlayerColor from './PlayerColor.js';
const Player = ({ table, color }) => {
const player = table.game.players[color];
return <div className="Player">
<div className="Who">
<PlayerColor color={color}/>{getPlayerName(table.game.sessions, color)}
</div>
<div className="What">
<div>Victory points: {player.points}</div>
<div>Development cards: {player.unplayed}</div>
<div>Army: {player.army}</div>
<div className="Shrunken"><BoardPieces table={table} color={color}/></div>
</div>
</div>
};
const PlayersStatus = ({ table }) => {
if (!table.game) {
return <></>;
}
const players = Object.getOwnPropertyNames(table.game.players)
.filter(color => table.game.players[color].status === 'Active' && table.game.color !== color)
.map(color => {
const player = table.game.players[color];
return <Player
key={`PlayerStatus-${getPlayerName(table.game.sessions, color)}`}
table={table}
color={color}/>;
});
return <div className="PlayersStatus">{ players }</div>;
}
export default PlayersStatus;

30
client/src/Styles.js Normal file
View File

@ -0,0 +1,30 @@
import { makeStyles } from '@material-ui/core/styles';
import { orange,lightBlue, red, grey } from '@material-ui/core/colors';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
'& > *': {
margin: theme.spacing(1),
},
},
R: {
color: theme.palette.getContrastText(red[500]),
backgroundColor: red[500],
},
O: {
color: theme.palette.getContrastText(orange[500]),
backgroundColor: orange[500],
},
W: {
color: theme.palette.getContrastText(grey[50]),
backgroundColor: grey[50],
},
B: {
color: theme.palette.getContrastText(lightBlue[500]),
backgroundColor: lightBlue[500],
},
}));
export { useStyles };

View File

@ -21,6 +21,7 @@ import { CircularProgress } from "@material-ui/core";
import 'moment-timezone'; import 'moment-timezone';
import Activities from './Activities.js'; import Activities from './Activities.js';
import BoardPieces from './BoardPieces.js'; import BoardPieces from './BoardPieces.js';
import PlayersStatus from './PlayersStatus.js';
/* Start of withRouter polyfill */ /* Start of withRouter polyfill */
// https://reactrouter.com/docs/en/v6/faq#what-happened-to-withrouter-i-need-it // https://reactrouter.com/docs/en/v6/faq#what-happened-to-withrouter-i-need-it
@ -352,16 +353,10 @@ const Players = ({ table }) => {
if (!inLobby && item.status === 'Not active') { if (!inLobby && item.status === 'Not active') {
continue; continue;
} }
const name = getPlayerName(table.game.sessions, color), let name = getPlayerName(table.game.sessions, color),
selectable = table.game.state === 'lobby' && (item.status === 'Not active' || table.game.color === color); selectable = table.game.state === 'lobby' && (item.status === 'Not active' || table.game.color === color);
let toggleText; if (!name) {
if (name) { name = "Available";
toggleText = `${name} has ${item.points} VP`;
if (item.unplayed) {
toggleText += ` and ${item.unplayed} unplayed DCs`;
}
} else {
toggleText = "Available";
} }
players.push(( players.push((
<div <div
@ -370,12 +365,7 @@ const Players = ({ table }) => {
className="PlayerEntry" className="PlayerEntry"
onClick={() => { inLobby && selectable && toggleSelected(color) }} onClick={() => { inLobby && selectable && toggleSelected(color) }}
key={`player-${color}`}> key={`player-${color}`}>
<PlayerColor color={color}/> <PlayerColor color={color}/>{name}
<ListItemText primary={toggleText} secondary={(
<>
{ item.status + ' ' }
{ item.status !== 'Not active' && <Moment fromNow date={item.lastActive > Date.now() ? Date.now() : item.lastActive}/>}
</>)} />
</div> </div>
)); ));
} }
@ -431,6 +421,7 @@ class Table extends React.Component {
this.closeCard = this.closeCard.bind(this); this.closeCard = this.closeCard.bind(this);
this.playCard = this.playCard.bind(this); this.playCard = this.playCard.bind(this);
this.selectResources = this.selectResources.bind(this); this.selectResources = this.selectResources.bind(this);
this.buildItem = this.buildItem.bind(this);
this.mouse = { x: 0, y: 0 }; this.mouse = { x: 0, y: 0 };
this.radius = 0.317; this.radius = 0.317;
@ -917,6 +908,10 @@ class Table extends React.Component {
}); });
} }
buildItem(item) {
return this.sendAction(`buy-${item}`);
}
componentWillUnmount() { componentWillUnmount() {
if (this.ws) { if (this.ws) {
this.ws.close(); this.ws.close();
@ -983,6 +978,10 @@ class Table extends React.Component {
development = <>/</>; development = <>/</>;
} }
if (!this.game) {
return <></>;
}
return ( return (
<div className="Table"> <div className="Table">
{ this.state.loading > 0 && <CircularProgress className='Loading'/> } { this.state.loading > 0 && <CircularProgress className='Loading'/> }
@ -994,7 +993,8 @@ class Table extends React.Component {
<div style={{display: "inline-flex", flex: 1, flexDirection: "column"}}> <div style={{display: "inline-flex", flex: 1, flexDirection: "column"}}>
<Board table={this} game={game}/> <Board table={this} game={game}/>
{ player !== undefined && <> { player !== undefined && <>
<BoardPieces table={this}/> <PlayersStatus table={this}/>
<BoardPieces onClick={this.buildItem} table={this} color={this.game.color}/>
<div className="BottomBar"> <div className="BottomBar">
<div className="Hand"> <div className="Hand">
<Resource type="wood" count={player.wood}/> <Resource type="wood" count={player.wood}/>