diff --git a/src/ui/components/game-screen.js b/src/ui/components/game-screen.js index b86b8c3f..0f827015 100644 --- a/src/ui/components/game-screen.js +++ b/src/ui/components/game-screen.js @@ -27,12 +27,12 @@ export default class App extends Component { get didWin() { return isCurrRoomCompleted(this.state) } - get isDead() { - return this.state.player.currentHealth < 1 - } get didWinEntireGame() { return isDungeonCompleted(this.state) } + get isDead() { + return this.state.player.currentHealth < 1 + } constructor() { super() @@ -46,7 +46,7 @@ export default class App extends Component { this.playCard = this.playCard.bind(this) this.handlePlayerReward = this.handlePlayerReward.bind(this) this.handleCampfireChoice = this.handleCampfireChoice.bind(this) - this.goToNextRoom = this.goToNextRoom.bind(this) + this.continueRoom = this.continueRoom.bind(this) this.toggleOverlay = this.toggleOverlay.bind(this) this.handleMapMove = this.handleMapMove.bind(this) } @@ -228,7 +228,7 @@ stw.dealCards()`) this.game.enqueue({type: 'addCardToDeck', card}) this.setState({didPickCard: card}) this.update() - this.goToNextRoom() + this.continueRoom() } handleCampfireChoice(choice, reward) { @@ -247,15 +247,16 @@ stw.dealCards()`) this.game.enqueue({type: 'makeCampfireChoice', choice, reward}) // Update twice (because two actions were enqueued) this.update(this.update) - this.goToNextRoom() + this.continueRoom() } - goToNextRoom() { + continueRoom() { console.log('Go to next room, toggling map') this.toggleOverlay('#Map') } handleMapMove(move) { + console.log('handleMapMove', move) this.toggleOverlay('#Map') this.setState({didPickCard: false}) this.game.enqueue({type: 'move', move}) @@ -279,6 +280,7 @@ stw.dealCards()`) if (!state.player) return const room = getCurrRoom(state) const showCombat = room.type === 'monster' + const showVictory = room.type === 'monster' && this.didWin && !this.didWinEntireGame return html`
this.handleShortcuts(e)}> @@ -299,7 +301,7 @@ stw.dealCards()`) ${ state.won && html`<${Overlay}> -
+

You won!

<${PublishRun} game=${this.game}> <${DungeonStats} dungeon=${state.dungeon}> @@ -308,7 +310,7 @@ stw.dealCards()`) ` } - ${room.type === 'start' && html`<${Overlay}><${StartRoom} onContinue=${this.goToNextRoom} />`} + ${room.type === 'start' && html`<${Overlay}><${StartRoom} onContinue=${this.continueRoom} />`} ${ room.type === 'campfire' && @@ -316,26 +318,22 @@ stw.dealCards()`) <${CampfireRoom} gameState=${state} onChoose=${this.handleCampfireChoice} - onContinue=${this.goToNextRoom} + onContinue=${this.continueRoom} > ` } - ${ - !this.didWinEntireGame && - this.didWin && - room.type === 'monster' && + ${showVictory && html`<${Overlay}> <${VictoryRoom} gameState=${state} onSelectCard=${(card) => this.handlePlayerReward('addCard', card)} - onContinue=${() => this.goToNextRoom()} + onContinue=${() => this.continueRoom()} > ` } - ${ - showCombat && + ${showCombat && html`
@@ -343,7 +341,7 @@ stw.dealCards()`)
${room.monsters && - room.monsters.map((monster) => html`<${Monster} model=${monster} gameState=${state} />`)} + room.monsters.map((monster) => html`<${Monster} key=${monster.id} model=${monster} gameState=${state} />`)}
diff --git a/src/ui/dragdrop.js b/src/ui/dragdrop.js index ba19575e..f2cb5c15 100644 --- a/src/ui/dragdrop.js +++ b/src/ui/dragdrop.js @@ -36,25 +36,36 @@ export default function enableDragDrop(container, afterRelease) { }, // While dragging, highlight any targets we are dragging over. onDrag() { - if (this.target.attributes.disabled) { + const cardEl = this.target + + if (cardEl.attributes.disabled) { this.endDrag() } let i = targets.length + const validTargets = new Set() while (--i > -1) { // Highlight only if valid target. if (this.hitTest(targets[i], '40%')) { if ( cardHasValidTarget( - this.target.getAttribute('data-card-target'), - getTargetStringFromElement(targets[i]), + cardEl.getAttribute('data-card-target'), + getTargetStringFromElement(targets[i]) ) ) { + validTargets.add(targets[i]) targets[i].classList.add(overClass) + } else { + validTargets.delete(targets[i]) } } else { targets[i].classList.remove(overClass) } } + if (validTargets.size > 0) { + cardEl.classList.add('is-releasable') + } else { + cardEl.classList.remove('is-releasable') + } }, onRelease() { const cardEl = this.target @@ -69,6 +80,8 @@ export default function enableDragDrop(container, afterRelease) { } } + cardEl.classList.remove('is-releasable') + if (!targetEl) return animateCardToHand(this) // If card is allowed here, trigger the callback with target, else animate back. diff --git a/src/ui/styles/card.css b/src/ui/styles/card.css index f8991f23..cedd7e3d 100644 --- a/src/ui/styles/card.css +++ b/src/ui/styles/card.css @@ -95,3 +95,35 @@ color: #fb1515; background-color: hsl(0deg 73% 25%); } + +.Card:hover { + --wiggle-distance: 1px; + /* animation: wiggle 100ms ease-in-out; */ +} + +@keyframes wiggle { + 0%, 100% { + transform: translate(0); + } + 20% { + transform: translate(calc(var(--wiggle-distance) * -1), calc(var(--wiggle-distance) * 1)); + } + 40% { + transform: translate(calc(var(--wiggle-distance) * 1), calc(var(--wiggle-distance) * -1)); + } + 60% { + transform: translate(calc(var(--wiggle-distance) * -1), calc(var(--wiggle-distance) * 1)); + } + 80% { + transform: translate(calc(var(--wiggle-distance) * 1), calc(var(--wiggle-distance) * -1)); + } +} + +.Card.is-releasable { + /* transition: box-shadow 300ms var(--easing); */ + /* transform: scale(1.1) rotate(6deg); */ + box-shadow: 1em 0 3em var(--yellow); +} +.Card.is-releasable .Card-name { + color: red; +}