diff options
Diffstat (limited to 'frontend/src/components/game')
-rw-r--r-- | frontend/src/components/game/GameScene.jsx | 10 | ||||
-rw-r--r-- | frontend/src/components/game/Hand.css | 6 | ||||
-rw-r--r-- | frontend/src/components/game/ProductionBar.css | 49 | ||||
-rw-r--r-- | frontend/src/components/game/ProductionBar.jsx | 74 |
4 files changed, 133 insertions, 6 deletions
diff --git a/frontend/src/components/game/GameScene.jsx b/frontend/src/components/game/GameScene.jsx index 035d9694..18d7ca26 100644 --- a/frontend/src/components/game/GameScene.jsx +++ b/frontend/src/components/game/GameScene.jsx @@ -11,6 +11,7 @@ import { getCurrentGame } from '../../redux/games'; import { getCurrentPlayer, getPlayers } from '../../redux/players'; import { Hand } from './Hand'; import './GameScene.css' +import { ProductionBar } from './ProductionBar'; type GameSceneProps = { game: Game, @@ -38,11 +39,14 @@ class GameScenePresenter extends Component<GameSceneProps> { } turnInfoScene() { + let turnInfo = this.props.turnInfo; + let board = turnInfo.table.boards[turnInfo.playerIndex]; return <div> - <p>{this.props.turnInfo.message}</p> - <Hand cards={this.props.turnInfo.hand} - wonderUpgradable={this.props.turnInfo.wonderBuildability.buildable} + <p>{turnInfo.message}</p> + <Hand cards={turnInfo.hand} + wonderUpgradable={turnInfo.wonderBuildability.buildable} prepareMove={this.props.prepareMove}/> + <ProductionBar production={board.production}/> </div> } } diff --git a/frontend/src/components/game/Hand.css b/frontend/src/components/game/Hand.css index 01c17763..c1aed09f 100644 --- a/frontend/src/components/game/Hand.css +++ b/frontend/src/components/game/Hand.css @@ -1,6 +1,6 @@ .hand { align-items: center; - bottom: -14rem; + bottom: -11rem; display: flex; height: 345px; /* can hold enhanced cards */ left: 50%; @@ -9,7 +9,7 @@ transition: 0.5s } .hand:hover { - bottom: 1rem; + bottom: 4rem; } .hand-card { @@ -20,7 +20,7 @@ .hand-card .hand-card-img { border-radius: 0.5rem; - box-shadow: 0 0 10px black; + box-shadow: 2px 2px 5px black; grid-row: 1; grid-column: 1; opacity: 1; diff --git a/frontend/src/components/game/ProductionBar.css b/frontend/src/components/game/ProductionBar.css new file mode 100644 index 00000000..34765128 --- /dev/null +++ b/frontend/src/components/game/ProductionBar.css @@ -0,0 +1,49 @@ +.production-bar { + align-items: center; + background: lightgray; + bottom: 0; + border-top: 1px #8b8b8b solid; + background: linear-gradient(#eaeaea, #888 7%); + box-shadow: 0 0 15px 0 #747474; + display: flex; + height: 3.5rem; + position: fixed; + width: 100vw; +} + +.fixed-resources { + margin: auto; + display: flex; +} +.alternative-resources { + margin: auto; + display: flex; +} + +.resource-with-count { + margin-left: 2px +} +.resource-choice { + margin-left: 2px; +} + +.resource-img { + height: 3rem; + vertical-align: middle; + width: 3rem; +} + +.resource-count { + font-family: fantasy; + font-size: 1.5rem; + margin-left: 0.2rem; + vertical-align: middle; +} + +.choice-separator { + font-size: 2rem; + vertical-align: middle; + margin: 5px; + color: #c29929; + text-shadow: 0 0 1px black; +} diff --git a/frontend/src/components/game/ProductionBar.jsx b/frontend/src/components/game/ProductionBar.jsx new file mode 100644 index 00000000..623389aa --- /dev/null +++ b/frontend/src/components/game/ProductionBar.jsx @@ -0,0 +1,74 @@ +import React from 'react'; +import type { ApiCountedResource, ApiProduction, ApiResourceType } from '../../api/model'; +import './ProductionBar.css' + +type ProductionBarProps = { + production: ApiProduction, +} + +export const ProductionBar = ({production}: ProductionBarProps) => { + return <div className='production-bar'> + <FixedResources resources={production.fixedResources}/> + <AlternativeResources resources={production.alternativeResources}/> + </div>; +}; + +type FixedResourcesProps = { + resources: ApiCountedResource[], +} + +const FixedResources = ({resources}: FixedResourcesProps) => { + return <div className="fixed-resources"> + {resources.map(r => <ResourceCount key={r.type} resource={r}/>)} + </div> +}; + +type ResourceCountProps = { + resource: ApiCountedResource, +} + +const ResourceCount = ({resource}: ResourceCountProps) => { + return <div className="resource-with-count"> + <ResourceImage type={resource.type}/> + <span className="resource-count">× {resource.count}</span> + </div> +}; + +type AlternativeResourcesProps = { + resources: ApiResourceType[][], +} + +const AlternativeResources = ({resources}: AlternativeResourcesProps) => { + return <div className="alternative-resources"> + {resources.map((types, i) => <ResourceChoice key={i} types={types}/>)} + </div> +}; + +type ResourceChoiceProps = { + types: ApiResourceType[], +} + +const ResourceChoice = ({types}: ResourceChoiceProps) => { + let typeImages = types.map(type => <ResourceImage key={type} type={type}/>); + let separator = <span className="choice-separator">∕</span>; + return <div className="resource-choice"> + {intersperce(typeImages, separator)} + </div> +}; + +function intersperce(array: T[], separator: T): T[] { + let result = array.reduce((acc, elt) => acc.concat(elt, separator), []); + return result.slice(0, -1); +} + +type ResourceImageProps = { + type: ApiResourceType, +} + +const ResourceImage = ({type}: ResourceImageProps) => { + return <img src={getImagePath(type)} title={type} alt={type} className="resource-img"/> +}; + +function getImagePath(resourceType: ApiResourceType): string { + return `/images/resources/${resourceType.toLowerCase()}.png`; +} |