Board layout coming along
Signed-off-by: James Ketrenos <james_gitlab@ketrenos.com>
Before Width: | Height: | Size: 338 KiB |
Before Width: | Height: | Size: 1.8 MiB |
BIN
assets/original/card-army-1.png
Normal file
After Width: | Height: | Size: 412 KiB |
BIN
assets/original/card-army-10.png
Normal file
After Width: | Height: | Size: 432 KiB |
BIN
assets/original/card-army-11.png
Normal file
After Width: | Height: | Size: 442 KiB |
BIN
assets/original/card-army-12.png
Normal file
After Width: | Height: | Size: 444 KiB |
BIN
assets/original/card-army-13.png
Normal file
After Width: | Height: | Size: 433 KiB |
BIN
assets/original/card-army-14.png
Normal file
After Width: | Height: | Size: 442 KiB |
BIN
assets/original/card-army-2.png
Normal file
After Width: | Height: | Size: 434 KiB |
BIN
assets/original/card-army-3.png
Normal file
After Width: | Height: | Size: 434 KiB |
BIN
assets/original/card-army-4.png
Normal file
After Width: | Height: | Size: 428 KiB |
BIN
assets/original/card-army-5.png
Normal file
After Width: | Height: | Size: 428 KiB |
BIN
assets/original/card-army-6.png
Normal file
After Width: | Height: | Size: 436 KiB |
BIN
assets/original/card-army-7.png
Normal file
After Width: | Height: | Size: 458 KiB |
BIN
assets/original/card-army-8.png
Normal file
After Width: | Height: | Size: 458 KiB |
BIN
assets/original/card-army-9.png
Normal file
After Width: | Height: | Size: 448 KiB |
BIN
assets/original/card-brick.png
Normal file
After Width: | Height: | Size: 438 KiB |
BIN
assets/original/card-monopoly.png
Normal file
After Width: | Height: | Size: 477 KiB |
BIN
assets/original/card-road-1.png
Normal file
After Width: | Height: | Size: 484 KiB |
BIN
assets/original/card-road-2.png
Normal file
After Width: | Height: | Size: 488 KiB |
BIN
assets/original/card-sheep.png
Normal file
After Width: | Height: | Size: 446 KiB |
BIN
assets/original/card-stone.png
Normal file
After Width: | Height: | Size: 423 KiB |
BIN
assets/original/card-vp-library.png
Normal file
After Width: | Height: | Size: 468 KiB |
BIN
assets/original/card-vp-market.png
Normal file
After Width: | Height: | Size: 433 KiB |
BIN
assets/original/card-vp-palace.png
Normal file
After Width: | Height: | Size: 462 KiB |
BIN
assets/original/card-vp-university.png
Normal file
After Width: | Height: | Size: 466 KiB |
BIN
assets/original/card-wheat.png
Normal file
After Width: | Height: | Size: 452 KiB |
BIN
assets/original/card-wood.png
Normal file
After Width: | Height: | Size: 435 KiB |
Before Width: | Height: | Size: 338 KiB |
Before Width: | Height: | Size: 243 KiB |
BIN
assets/original/placard-blue.png
Normal file
After Width: | Height: | Size: 983 KiB |
BIN
assets/original/placard-largest-army.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
assets/original/placard-longest-road.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
assets/original/placard-orange.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
assets/original/placard-red.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/original/placard-white.png
Normal file
After Width: | Height: | Size: 1014 KiB |
Before Width: | Height: | Size: 9.4 KiB |
BIN
assets/original/table.png
Executable file → Normal file
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 453 KiB After Width: | Height: | Size: 453 KiB |
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 2.5 MiB |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
Before Width: | Height: | Size: 2.5 MiB |
BIN
assets/original/uncut/army.png
Normal file
After Width: | Height: | Size: 6.3 MiB |
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.2 MiB |
Before Width: | Height: | Size: 3.4 MiB After Width: | Height: | Size: 3.4 MiB |
BIN
assets/original/uncut/cards.xcf
Normal file
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 14 MiB After Width: | Height: | Size: 14 MiB |
98
src/App.css
@ -2,47 +2,89 @@ body {
|
|||||||
font-family: 'Droid Sans', 'Arial Narrow', Arial, sans-serif;
|
font-family: 'Droid Sans', 'Arial Narrow', Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#PCILOOKUP {
|
.Cards {
|
||||||
margin: 1em;
|
position: absolute;
|
||||||
padding: 1em;
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: right;
|
||||||
|
vertical-align: bottom;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Stack {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: lightyellow;
|
display: inline-block;
|
||||||
border: 1px solid #252525;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#PCILOOKUP p {
|
.Stack:not(:first-child) {
|
||||||
margin: 0;
|
margin-left: -3em;
|
||||||
|
transition: margin-left 1s ease-in-out 0.25s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#PCIRESULTS {
|
.Stack > * {
|
||||||
margin-top: 0.5em;
|
transition: margin-left 1s ease-in-out 0.25s, margin-right 1s ease-in-out 0.25s;
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#PCIDEVICE {
|
.Development:hover,
|
||||||
padding: 0.5em 1em;
|
.Placard:hover,
|
||||||
font-family: 'Courier New'
|
.Resource:hover {
|
||||||
|
filter: brightness(150%);
|
||||||
}
|
}
|
||||||
|
|
||||||
#PCIBASH::before {
|
.Stack > *:not(:first-child) {
|
||||||
content: '# ';
|
margin-left: -4.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#PCIBASH {
|
.Hand:hover .Stack:hover > *:not(:first-child) {
|
||||||
margin-top: 0.5em;
|
margin-left: -2em;
|
||||||
background-color: #fff;
|
|
||||||
color: #040;
|
|
||||||
font-weight: bold;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
font-family: 'Courier New';
|
|
||||||
padding: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#PCIID {
|
.Hand:hover .Stack:hover:not(:last-child) > *:last-child {
|
||||||
margin-left: 0.25em;
|
margin-right: 3em;
|
||||||
padding: 0.1em;
|
}
|
||||||
width: 4em;
|
|
||||||
text-transform: uppercase;
|
.Placard {
|
||||||
|
position: relative;
|
||||||
|
width: 9.4em;
|
||||||
|
height: 11.44em;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
margin: 0.25em;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Development {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 4.9em;
|
||||||
|
height: 7.2em;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
margin: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resource {
|
||||||
|
position: relative;
|
||||||
|
width: 4.9em;
|
||||||
|
height: 7.2em;
|
||||||
|
display: inline-block;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
margin: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Statistics > div:nth-child(2) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Statistics div:nth-child(2) div {
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MarkdownLoader {
|
.MarkdownLoader {
|
||||||
|
157
src/Board.js
@ -49,7 +49,7 @@ const Tiles = (board) => {
|
|||||||
|
|
||||||
[ "robber", "brick", "wood", "sheep", "stone", "wheat" ].forEach((type) => {
|
[ "robber", "brick", "wood", "sheep", "stone", "wheat" ].forEach((type) => {
|
||||||
const image = new Image(),
|
const image = new Image(),
|
||||||
file = type + ".png";
|
file = "tiles-" + type + ".png";
|
||||||
tiles.forEach((tile) => {
|
tiles.forEach((tile) => {
|
||||||
if (tile.type == type) {
|
if (tile.type == type) {
|
||||||
tile.image = image;
|
tile.image = image;
|
||||||
@ -158,6 +158,62 @@ function shuffle(array) {
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Placard extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="Placard"
|
||||||
|
style={{backgroundImage:`url(assets/original/placard-${this.props.type}.png)`}}>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Development extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const array = [];
|
||||||
|
for (let i = 0; i < this.props.count; i++) {
|
||||||
|
if (this.props.type.match(/-$/)) {
|
||||||
|
array.push(Math.ceil(Math.random() * this.props.max));
|
||||||
|
} else {
|
||||||
|
array.push("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="Stack">
|
||||||
|
{ React.Children.map(array, i => (
|
||||||
|
<div className="Development"
|
||||||
|
style={{backgroundImage:`url(assets/original/card-${this.props.type}${i}.png)`}}>
|
||||||
|
</div>
|
||||||
|
)) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Resource extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const array = new Array(Number(this.props.count));
|
||||||
|
return (
|
||||||
|
<div className="Stack">
|
||||||
|
{ React.Children.map(array, i => (
|
||||||
|
<div className="Resource"
|
||||||
|
style={{backgroundImage:`url(assets/original/card-${this.props.type}.png)`}}>
|
||||||
|
</div>
|
||||||
|
)) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Board extends React.Component {
|
class Board extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -307,11 +363,56 @@ class Board extends React.Component {
|
|||||||
ctx.filleStyle = 'rgba(0, 0, 0, 0)';
|
ctx.filleStyle = 'rgba(0, 0, 0, 0)';
|
||||||
|
|
||||||
this.minSize = Math.min(this.canvas.height, this.canvas.width);
|
this.minSize = Math.min(this.canvas.height, this.canvas.width);
|
||||||
ctx.drawImage(this.table,
|
/*
|
||||||
0, 0,
|
* Table tiling:
|
||||||
this.table.width, this.table.height,
|
* Image width: 1080
|
||||||
0, 0, this.minSize, this.minSize);
|
* Left start: 32
|
||||||
|
* Right edge: 1010 (1010 - 32 = 978)
|
||||||
|
*
|
||||||
|
* If the view is wider than taller, then
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If view is taller than wide, tile the table vertically */
|
||||||
|
ctx.save();
|
||||||
|
if (this.canvas.height > this.canvas.width) {
|
||||||
|
const tableHeight = this.canvas.width * this.table.height / this.table.width;
|
||||||
|
for (let top = 0, step = 0; top < this.canvas.height; top += tableHeight, step++) {
|
||||||
|
if (step % 2) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(0, tableHeight - 1);
|
||||||
|
ctx.transform(1, 0, 0, -1, 0, 0);
|
||||||
|
ctx.drawImage(this.table,
|
||||||
|
0, 0,
|
||||||
|
this.table.width, this.table.height,
|
||||||
|
0, 0, this.canvas.width, this.canvas.width * this.table.height / this.table.width);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(this.table,
|
||||||
|
0, 0,
|
||||||
|
this.table.width, this.table.height,
|
||||||
|
0, 0,
|
||||||
|
this.canvas.width, this.canvas.width * this.table.height / this.table.width);
|
||||||
|
}
|
||||||
|
ctx.translate(0, tableHeight);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const tableWidth = this.canvas.height * this.table.width / this.table.height;
|
||||||
|
ctx.drawImage(this.table,
|
||||||
|
0, 0,
|
||||||
|
1010, this.table.height,
|
||||||
|
0, 0,
|
||||||
|
this.canvas.height * 1010 / this.table.height, this.canvas.height);
|
||||||
|
let left = this.canvas.height * 1010 / this.table.height;
|
||||||
|
while (left < this.canvas.width) {
|
||||||
|
ctx.drawImage(this.table,
|
||||||
|
32, 0,
|
||||||
|
978, this.table.height,
|
||||||
|
left, 0,
|
||||||
|
this.canvas.height * 978 / this.table.height, this.canvas.height);
|
||||||
|
left += this.canvas.height * 978 / this.table.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
ctx.scale(this.minSize / hexagonRatio, this.minSize / hexagonRatio);
|
ctx.scale(this.minSize / hexagonRatio, this.minSize / hexagonRatio);
|
||||||
ctx.translate(0.5 * hexagonRatio, 0.5 * hexagonRatio);
|
ctx.translate(0.5 * hexagonRatio, 0.5 * hexagonRatio);
|
||||||
ctx.lineWidth = 2. / this.minSize;
|
ctx.lineWidth = 2. / this.minSize;
|
||||||
@ -514,7 +615,51 @@ class Board extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<canvas className="Board" ref={el => this.canvas = el}></canvas>
|
<>
|
||||||
|
<canvas className="Board" ref={el => this.canvas = el}></canvas>
|
||||||
|
<div className="Cards">
|
||||||
|
<div>In hand</div>
|
||||||
|
<div className="Hand">
|
||||||
|
<Resource type="wood" count="0"/>
|
||||||
|
<Resource type="wheat" count="3"/>
|
||||||
|
<Resource type="stone" count="8"/>
|
||||||
|
<Resource type="brick" count="2"/>
|
||||||
|
<Resource type="sheep" count="5"/>
|
||||||
|
</div>
|
||||||
|
<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>Points</div>
|
||||||
|
<div className="Hand">
|
||||||
|
<div className="Stack">
|
||||||
|
<Development type="vp-library" count="1"/>
|
||||||
|
<Development type="vp-palace" count="1"/>
|
||||||
|
<Development type="army-" max="14" count="6"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="Hand">
|
||||||
|
<Placard type="largest-army" count="1"/>
|
||||||
|
<Placard type="longest-road" count="1"/>
|
||||||
|
</div>
|
||||||
|
<div className="Statistics">
|
||||||
|
<div>Stats</div>
|
||||||
|
<div>
|
||||||
|
<div>Points: 7</div>
|
||||||
|
<div>Cards: 8</div>
|
||||||
|
<div>Roads remaining: 4</div>
|
||||||
|
<div>Longest road: 7</div>
|
||||||
|
<div>Cities remaining: 4</div>
|
||||||
|
<div>Settlements remaining: 5</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|