From ce0e91cf356172a17b5ef6c258e1a2c14a0c6026 Mon Sep 17 00:00:00 2001 From: Vitalij Ryndin Date: Fri, 18 Oct 2024 03:02:00 +0800 Subject: [PATCH] feat: guide and element about --- apps/frontend/src/app.vue | 5 +- .../frontend/src/components/alchemy-board.vue | 4 +- .../src/components/alchemy-counter.vue | 13 ++- .../src/components/alchemy-draggable-item.vue | 2 +- .../src/components/alchemy-element-about.vue | 91 +++++++++++++++++++ .../src/components/alchemy-elements.vue | 40 ++++++-- .../frontend/src/components/alchemy-guide.vue | 71 +++++++++------ apps/frontend/src/stores/use-drawer.ts | 27 ------ apps/frontend/src/stores/use-element-about.ts | 53 +++++++++++ apps/frontend/src/stores/use-game.ts | 13 +-- apps/frontend/src/stores/use-guide.ts | 20 ++++ .../src/stores/use-opened-elements.ts | 17 +++- apps/frontend/src/styles/main.scss | 6 ++ apps/frontend/src/ui/drawer/drawer-header.vue | 10 +- apps/frontend/src/ui/drawer/drawer.vue | 16 +++- 15 files changed, 295 insertions(+), 93 deletions(-) create mode 100644 apps/frontend/src/components/alchemy-element-about.vue delete mode 100644 apps/frontend/src/stores/use-drawer.ts create mode 100644 apps/frontend/src/stores/use-element-about.ts create mode 100644 apps/frontend/src/stores/use-guide.ts diff --git a/apps/frontend/src/app.vue b/apps/frontend/src/app.vue index 265f73b..234f68a 100644 --- a/apps/frontend/src/app.vue +++ b/apps/frontend/src/app.vue @@ -2,12 +2,15 @@ import AlchemyBoard from '@/components/alchemy-board.vue' import AlchemyElements from '@/components/alchemy-elements.vue' import AlchemyCounter from '@/components/alchemy-counter.vue' -import AlchemyGuide from './components/alchemy-guide.vue' +import AlchemyElementAbout from './components/alchemy-element-about.vue' +import AlchemyGuide from './components/alchemy-guide.vue'; diff --git a/apps/frontend/src/components/alchemy-board.vue b/apps/frontend/src/components/alchemy-board.vue index abe0812..35c08eb 100644 --- a/apps/frontend/src/components/alchemy-board.vue +++ b/apps/frontend/src/components/alchemy-board.vue @@ -100,8 +100,8 @@ function createElement( ...newElement, uuid: crypto.randomUUID(), position: { - x: isCopy ? boardElement.position.x + 15 : boardElement.position.x, - y: isCopy ? boardElement.position.y + 15 : boardElement.position.y + x: isCopy ? boardElement.position.x + 30 : boardElement.position.x, + y: isCopy ? boardElement.position.y + 30 : boardElement.position.y } }) } diff --git a/apps/frontend/src/components/alchemy-counter.vue b/apps/frontend/src/components/alchemy-counter.vue index 73f350c..2f5427b 100644 --- a/apps/frontend/src/components/alchemy-counter.vue +++ b/apps/frontend/src/components/alchemy-counter.vue @@ -1,20 +1,19 @@ diff --git a/apps/frontend/src/components/alchemy-elements.vue b/apps/frontend/src/components/alchemy-elements.vue index 9077869..9c4f9ed 100644 --- a/apps/frontend/src/components/alchemy-elements.vue +++ b/apps/frontend/src/components/alchemy-elements.vue @@ -4,12 +4,14 @@ import AlchemyItem from './alchemy-item.vue' import { useGame } from '@/stores/use-game.js' import { useBoard } from '@/stores/use-board.js' import { useOpenedElements } from '@/stores/use-opened-elements.js' -import { useDrawer } from '@/stores/use-drawer' +import { useElementAbout } from '@/stores/use-element-about' +import { useGuide } from '@/stores/use-guide' import type { AlchemyElement } from '@/types.js' +const guide = useGuide() const game = useGame() const board = useBoard() -const drawer = useDrawer() +const elementAbout = useElementAbout() const openedElements = useOpenedElements() const searchInput = ref('') @@ -38,7 +40,7 @@ function createElement(element: AlchemyElement) { class="search-input" type="text" name="search" - placeholder="Искать элемент" + placeholder="Искать элемент..." />
-
Новая игра
-
Очистить поле
+
+ Новая игра +
+
+ Помощь +
+
+ Очистить поле +
@@ -95,9 +117,10 @@ function createElement(element: AlchemyElement) { border: none; outline: none; border-bottom: 1px solid var(--vt-c-divider-dark-2); - font-size: inherit; + font-size: 18px; text-align: center; color: var(--vt-c-text-dark-2); + height: 52px; } .controls { @@ -114,6 +137,9 @@ function createElement(element: AlchemyElement) { text-align: center; width: 50%; height: 100%; + display: flex; + align-items: center; + justify-content: center; } .border-right { diff --git a/apps/frontend/src/components/alchemy-guide.vue b/apps/frontend/src/components/alchemy-guide.vue index 78da3ac..73d4a28 100644 --- a/apps/frontend/src/components/alchemy-guide.vue +++ b/apps/frontend/src/components/alchemy-guide.vue @@ -2,46 +2,63 @@ import Drawer from '@/ui/drawer/drawer.vue' import DrawerBody from '@/ui/drawer/drawer-body.vue' import DrawerHeader from '@/ui/drawer/drawer-header.vue' -import { useDrawer } from '@/stores/use-drawer' import { storeToRefs } from 'pinia' -import { sprites } from '@/assets/sprites' +import { useGuide } from '@/stores/use-guide' -const { isOpen, openedElement } = storeToRefs(useDrawer()) +const { isOpen } = storeToRefs(useGuide()) diff --git a/apps/frontend/src/stores/use-drawer.ts b/apps/frontend/src/stores/use-drawer.ts deleted file mode 100644 index 2015dc5..0000000 --- a/apps/frontend/src/stores/use-drawer.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ref } from 'vue' -import { defineStore } from 'pinia' -import recipes from '@/assets/recipes.json' -import type { AlchemyElement, AlchemyElementOnBoard } from '@/types' - -interface AlchemyRecipe { - id: string - name: string - description: string - recipes: string[][] -} - -export const useDrawer = defineStore("drawer", () => { - const isOpen = ref(false) - const openedElement = ref(null) - - function openDrawer(element: AlchemyElement) { - isOpen.value = true - openedElement.value = recipes.find((recipe) => recipe.id === element.id)! - } - - return { - isOpen, - openedElement, - openDrawer - } -}) diff --git a/apps/frontend/src/stores/use-element-about.ts b/apps/frontend/src/stores/use-element-about.ts new file mode 100644 index 0000000..b7cf1d8 --- /dev/null +++ b/apps/frontend/src/stores/use-element-about.ts @@ -0,0 +1,53 @@ +import { ref } from 'vue' +import { defineStore } from 'pinia' +import { useOpenedElements } from '@/stores/use-opened-elements' +import recipes from '@/assets/recipes.json' +import type { AlchemyElement } from '@/types' + +interface AlchemyRecipe { + id: string + name: string + ended?: boolean +} + +interface AlchemyAboutElement { + id: string + name: string + description: string + recipes: AlchemyRecipe[][] +} + +export const useElementAbout = defineStore('element-about', () => { + const isOpen = ref(false) + const activeElement = ref(null) + const openedElements = useOpenedElements() + + function openElementAbout(element: AlchemyElement) { + isOpen.value = true + + const el = recipes.find((recipe) => recipe.id === element.id)! + const openedRecipes: AlchemyRecipe[][] = [] + + for (const recipe of el.recipes) { + const [el1, el2] = recipe as [string, string] + const first = openedElements.isCreatedElement(el1) + const second = openedElements.isCreatedElement(el2) + if (first && second) { + openedRecipes.push([first, second]) + } + } + + activeElement.value = { + id: element.id, + name: element.name, + description: el.description, + recipes: openedRecipes + } + } + + return { + isOpen, + activeElement, + openElementAbout + } +}) diff --git a/apps/frontend/src/stores/use-game.ts b/apps/frontend/src/stores/use-game.ts index acf3d2d..2a54fda 100644 --- a/apps/frontend/src/stores/use-game.ts +++ b/apps/frontend/src/stores/use-game.ts @@ -1,4 +1,4 @@ -import { computed, ref, watch } from 'vue' +import { onWatcherCleanup, ref, watch } from 'vue' import { defineStore } from 'pinia' import { useBoard } from './use-board.js' import { useOpenedElements } from './use-opened-elements.js' @@ -8,11 +8,6 @@ import type { AlchemyElementOnBoard, Position } from '@/types.js' export const useGame = defineStore('game', () => { const board = useBoard() const openedElements = useOpenedElements() - - const availableRecipes = computed(() => { - return `${openedElements.openedElements.length} / ${recipes.length}` - }) - const basicElements = ref([]) function getRandomPosition(): Position { @@ -29,7 +24,8 @@ export const useGame = defineStore('game', () => { openedElements.$reset() } - watch(board.boardSize, () => { + watch(() => board.boardSize, (board) => { + if (board.bottom === 0) return; basicElements.value = recipes.slice(0, 4).map((element) => { return { uuid: crypto.randomUUID(), @@ -39,10 +35,9 @@ export const useGame = defineStore('game', () => { position: getRandomPosition() } }) - }, { deep: true, once: true }) + }) return { - availableRecipes, basicElements, getRandomPosition, $reset diff --git a/apps/frontend/src/stores/use-guide.ts b/apps/frontend/src/stores/use-guide.ts new file mode 100644 index 0000000..6b84976 --- /dev/null +++ b/apps/frontend/src/stores/use-guide.ts @@ -0,0 +1,20 @@ +import { ref } from 'vue' +import { defineStore } from 'pinia' + +export const useGuide = defineStore('guide', () => { + const isOpen = ref(false) + + function toggleGuide() { + isOpen.value = !isOpen.value + } + + function closeGuide() { + isOpen.value = false + } + + return { + isOpen, + closeGuide, + toggleGuide + } +}) diff --git a/apps/frontend/src/stores/use-opened-elements.ts b/apps/frontend/src/stores/use-opened-elements.ts index de724f0..499b34c 100644 --- a/apps/frontend/src/stores/use-opened-elements.ts +++ b/apps/frontend/src/stores/use-opened-elements.ts @@ -1,8 +1,9 @@ -import { watchEffect } from 'vue' +import { computed, watchEffect } from 'vue' import { defineStore } from 'pinia' import * as vueuse from '@vueuse/core' import { useGame } from './use-game.js' import { useSounds } from './use-sounds.js' +import recipes from '@/assets/recipes.json' import type { AlchemyElement } from '@/types.js' type OpenedAlchemyElements = Omit[] @@ -14,10 +15,20 @@ export const useOpenedElements = defineStore('opened-elements', () => { 'alchemy-opened-elements', [] ) + const elementsCounter = computed(() => { + return `${openedElements.value.length} / ${recipes.length}` + }) + function $reset(): void { openedElements.value = [] } + function isCreatedElement(elementId: string) { + return openedElements.value.find((openedElement) => { + return openedElement.id === elementId + }) + } + function addElement(element: AlchemyElement): void { const isExist = openedElements.value .some((openedElement) => openedElement.id === element.id) @@ -48,7 +59,9 @@ export const useOpenedElements = defineStore('opened-elements', () => { return { openedElements, + elementsCounter, $reset, - addElement + addElement, + isCreatedElement } }) diff --git a/apps/frontend/src/styles/main.scss b/apps/frontend/src/styles/main.scss index 691b247..5cf7cc5 100644 --- a/apps/frontend/src/styles/main.scss +++ b/apps/frontend/src/styles/main.scss @@ -80,3 +80,9 @@ body { ::-webkit-scrollbar-thumb:hover { background: var(--vt-c-black-soft); } + +.h6 { + font-size: 20px; + line-height: 32px; + font-weight: 600; +} diff --git a/apps/frontend/src/ui/drawer/drawer-header.vue b/apps/frontend/src/ui/drawer/drawer-header.vue index 1f331a6..516c64c 100644 --- a/apps/frontend/src/ui/drawer/drawer-header.vue +++ b/apps/frontend/src/ui/drawer/drawer-header.vue @@ -25,8 +25,10 @@ const { toggleDrawer } = inject(drawerInjectionKey)! justify-content: space-between; align-items: center; gap: 24px; - padding: 16px 24px; + padding: 0 24px; border-bottom: 1px solid var(--vt-c-divider-dark-2); + height: 52px; + flex-shrink: 0; &__close { width: 24px; @@ -34,10 +36,4 @@ const { toggleDrawer } = inject(drawerInjectionKey)! cursor: pointer; } } - -.h6 { - font-size: 20px; - line-height: 32px; - font-weight: 600; -} diff --git a/apps/frontend/src/ui/drawer/drawer.vue b/apps/frontend/src/ui/drawer/drawer.vue index 9a81891..a17371d 100644 --- a/apps/frontend/src/ui/drawer/drawer.vue +++ b/apps/frontend/src/ui/drawer/drawer.vue @@ -1,7 +1,12 @@