|
|
@@ -0,0 +1,439 @@
|
|
|
+<template>
|
|
|
+ <div class="game-view">
|
|
|
+ <img
|
|
|
+ class="title"
|
|
|
+ src="@/assets/images/pair-up-title.png"
|
|
|
+ alt=""
|
|
|
+ draggable="false"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ v-show="!isOver"
|
|
|
+ class="tip"
|
|
|
+ >
|
|
|
+ 请翻开相同的企业logo
|
|
|
+ </div>
|
|
|
+ <!-- 卡牌列表 -->
|
|
|
+ <div
|
|
|
+ v-show="!isOver"
|
|
|
+ class="card-list"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ v-for="(card, cardIdx) in cardList"
|
|
|
+ :key="cardIdx"
|
|
|
+ class="card"
|
|
|
+ :class="{
|
|
|
+ active: activeCardIdxList.includes(cardIdx),
|
|
|
+ hide: card.isDone,
|
|
|
+ }"
|
|
|
+ @click="onClickCard(card, cardIdx)"
|
|
|
+ >
|
|
|
+ <div class="front">
|
|
|
+ <img
|
|
|
+ class="card-frame"
|
|
|
+ src="@/assets/images/pair-up-card-front-side.png"
|
|
|
+ alt=""
|
|
|
+ draggable="false"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ class="card-content"
|
|
|
+ :src="require(`@/assets/images/pair-up-logos/${logoFileNameList[card.logoIdx]}`)"
|
|
|
+ alt=""
|
|
|
+ draggable="false"
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <img
|
|
|
+ class="back"
|
|
|
+ src="@/assets/images/pair-up-card-back-side.png"
|
|
|
+ alt=""
|
|
|
+ draggable="false"
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 左上角按钮 -->
|
|
|
+ <div class="btn-group">
|
|
|
+ <button
|
|
|
+ class="return-home"
|
|
|
+ @click="onClickReturnHome"
|
|
|
+ />
|
|
|
+ <button class="game-rule" />
|
|
|
+ </div>
|
|
|
+ <!-- 底部信息栏 -->
|
|
|
+ <div
|
|
|
+ v-show="!isOver"
|
|
|
+ class="common-info-group"
|
|
|
+ >
|
|
|
+ <div class="info-item bonus-point">
|
|
|
+ <img
|
|
|
+ class="icon"
|
|
|
+ src="@/assets/images/icon_bonus_point.png"
|
|
|
+ alt=""
|
|
|
+ draggable="false"
|
|
|
+ >
|
|
|
+ <span class="number">{{ bonusPoint }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item time-count">
|
|
|
+ <img
|
|
|
+ class="icon"
|
|
|
+ src="@/assets/images/icon_time_count.png"
|
|
|
+ alt=""
|
|
|
+ draggable="false"
|
|
|
+ >
|
|
|
+ <span class="number">{{ timeCountForShow }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <PairUpOver
|
|
|
+ v-show="isOver"
|
|
|
+ :corp-count="recognizedCorpList.length"
|
|
|
+ :bonus-count="bonusPoint"
|
|
|
+ @replay="replay"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import useSizeAdapt from "@/useFunctions/useSizeAdapt"
|
|
|
+import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from "vue"
|
|
|
+import { useRoute, useRouter } from "vue-router"
|
|
|
+import { useStore } from "vuex"
|
|
|
+import dayjs from 'dayjs'
|
|
|
+import { shuffle } from 'lodash'
|
|
|
+import PairUpOver from '@/components/PairUpOver.vue'
|
|
|
+
|
|
|
+const route = useRoute()
|
|
|
+const router = useRouter()
|
|
|
+const store = useStore()
|
|
|
+
|
|
|
+const {
|
|
|
+ windowSizeInCssForRef,
|
|
|
+ windowSizeWhenDesignForRef,
|
|
|
+} = useSizeAdapt(390, 752)
|
|
|
+
|
|
|
+function onClickReturnHome() {
|
|
|
+ router.push({
|
|
|
+ name: 'HomeView',
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const isOver = ref(false)
|
|
|
+
|
|
|
+/**
|
|
|
+ * 倒计时
|
|
|
+ */
|
|
|
+const timeCount = ref(120)
|
|
|
+let timeCountIntervalId = null
|
|
|
+timeCountIntervalId = setInterval(() => {
|
|
|
+ timeCount.value--
|
|
|
+ if (timeCount.value === 0) {
|
|
|
+ clearInterval(timeCountIntervalId)
|
|
|
+ isOver.value = true
|
|
|
+ }
|
|
|
+}, 1000)
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ clearInterval(timeCountIntervalId)
|
|
|
+})
|
|
|
+const timeCountForShow = computed(() => {
|
|
|
+ return dayjs(timeCount.value * 1000).format('m:ss')
|
|
|
+})
|
|
|
+
|
|
|
+/**
|
|
|
+ * 本次游戏积分
|
|
|
+ */
|
|
|
+const bonusPoint = ref(0)
|
|
|
+
|
|
|
+/**
|
|
|
+ * 本次游戏识别企业数
|
|
|
+ */
|
|
|
+const recognizedCorpList = ref([])
|
|
|
+
|
|
|
+/**
|
|
|
+ * 重玩
|
|
|
+ */
|
|
|
+function replay() {
|
|
|
+ isOver.value = false
|
|
|
+ timeCount.value = 10
|
|
|
+ timeCountIntervalId = setInterval(() => {
|
|
|
+ timeCount.value--
|
|
|
+ if (timeCount.value === 0) {
|
|
|
+ clearInterval(timeCountIntervalId)
|
|
|
+ isOver.value = true
|
|
|
+ }
|
|
|
+ }, 1000)
|
|
|
+ recognizedCorpList.value = 0
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 具体游戏规则
|
|
|
+ */
|
|
|
+const logoFileNameList = [
|
|
|
+ '中海基金管理有限公司.png',
|
|
|
+ '中航证券有限公司.png',
|
|
|
+ '中欧基金管理有限公司.png',
|
|
|
+ '中信期货有限公司.png',
|
|
|
+ '中信证券股份有限公司.png',
|
|
|
+ '中证数据有限责任公司.png',
|
|
|
+ '朱雀基金管理有限公司.png',
|
|
|
+ '北京中金公益基金会.png',
|
|
|
+ '创金合信基金管理有限公司.png',
|
|
|
+ '德邦基金管理有限公司.png',
|
|
|
+ '东方财富证券股份有限公司.gif',
|
|
|
+ '东海证券股份有限公司.jpg',
|
|
|
+ '富国基金管理有限公司.png',
|
|
|
+ '广发证券股份有限公司.png',
|
|
|
+ '国盛证券有限责任公司.png',
|
|
|
+ '国元证券股份有限公司.png',
|
|
|
+ '华安基金管理有限公司.png',
|
|
|
+ '华泰证券股份有限公司.jpg',
|
|
|
+ '汇添富基金管理股份有限公司.jpg',
|
|
|
+ '金信期货有限公司.png',
|
|
|
+ '南华期货股份有限公司.png',
|
|
|
+ '鹏华基金管理有限公司.png',
|
|
|
+ '鹏扬基金管理有限公司.jpg',
|
|
|
+ '平安证券股份有限公司.png',
|
|
|
+ '睿远公益基金会.jpg',
|
|
|
+ '上海东方证券资产管理有限公司.png',
|
|
|
+ '上海证券交易所公益基金会.png',
|
|
|
+ '深圳市银华公益基金会.jpg',
|
|
|
+ '泰达宏利基金.png',
|
|
|
+ '万家基金管理有限公司.png',
|
|
|
+ '兴业证券股份有限公司.png',
|
|
|
+ '兴证全球基金管理有限公司.png',
|
|
|
+ '圆信永丰基金管理有限公司.png',
|
|
|
+ '长江证券股份有限公司.png',
|
|
|
+ '郑州商品交易所.jpg',
|
|
|
+ '中国金融期货交易所.jpg',
|
|
|
+ '中国期货市场监控中心有限责任公司.png',
|
|
|
+ '中国证券登记结算有限责任公司.png',
|
|
|
+]
|
|
|
+const cardList = ref([])
|
|
|
+function setCardList() {
|
|
|
+ cardList.value = []
|
|
|
+ nextTick(() => {
|
|
|
+ for (let index = 0; index < 8; index++) {
|
|
|
+ const logoIdx = Math.floor(Math.random() * logoFileNameList.length)
|
|
|
+ cardList.value.push({
|
|
|
+ logoIdx,
|
|
|
+ isDone: false,
|
|
|
+ })
|
|
|
+ cardList.value.push({
|
|
|
+ logoIdx,
|
|
|
+ isDone: false,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (process.env.VUE_APP_CLI_MODE !== 'dev') {
|
|
|
+ cardList.value = shuffle(cardList.value)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+setCardList()
|
|
|
+
|
|
|
+const activeCardIdxList = ref([])
|
|
|
+const activeCardIdxListRealTime = ref([])
|
|
|
+function onClickCard(card, cardIdx) {
|
|
|
+ if (activeCardIdxList.value.includes(cardIdx)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ activeCardIdxList.value.push(cardIdx)
|
|
|
+ activeCardIdxListRealTime.value.push(cardIdx)
|
|
|
+ if (activeCardIdxListRealTime.value.length === 2 && cardList.value[activeCardIdxListRealTime.value[0]].logoIdx === cardList.value[activeCardIdxListRealTime.value[1]].logoIdx) {
|
|
|
+ const logoIdx = cardList.value[activeCardIdxListRealTime.value[0]].logoIdx
|
|
|
+ const toDeleteValue1 = activeCardIdxListRealTime.value.shift()
|
|
|
+ const toDeleteValue2 = activeCardIdxListRealTime.value.shift()
|
|
|
+ setTimeout(() => {
|
|
|
+ cardList.value[toDeleteValue1].isDone = true
|
|
|
+ cardList.value[toDeleteValue2].isDone = true
|
|
|
+ bonusPoint.value += 1
|
|
|
+ if (!recognizedCorpList.value.includes(logoIdx)) {
|
|
|
+ recognizedCorpList.value.push(logoIdx)
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ const toDeleteIdx1 = activeCardIdxList.value.findIndex((item) => {
|
|
|
+ return item === toDeleteValue1
|
|
|
+ })
|
|
|
+ activeCardIdxList.value.splice(toDeleteIdx1, 1)
|
|
|
+ const toDeleteIdx2 = activeCardIdxList.value.findIndex((item) => {
|
|
|
+ return item === toDeleteValue2
|
|
|
+ })
|
|
|
+ activeCardIdxList.value.splice(toDeleteIdx2, 1)
|
|
|
+
|
|
|
+ if (cardList.value.every((item) => {
|
|
|
+ return item.isDone
|
|
|
+ })) {
|
|
|
+ setCardList()
|
|
|
+ }
|
|
|
+ }, 400)
|
|
|
+ }, 400)
|
|
|
+ } else if (activeCardIdxListRealTime.value.length === 3) {
|
|
|
+ const toDeleteValue1 = activeCardIdxListRealTime.value.shift()
|
|
|
+ const toDeleteValue2 = activeCardIdxListRealTime.value.shift()
|
|
|
+ setTimeout(() => {
|
|
|
+ const toDeleteIdx1 = activeCardIdxList.value.findIndex((item) => {
|
|
|
+ return item === toDeleteValue1
|
|
|
+ })
|
|
|
+ activeCardIdxList.value.splice(toDeleteIdx1, 1)
|
|
|
+ const toDeleteIdx2 = activeCardIdxList.value.findIndex((item) => {
|
|
|
+ return item === toDeleteValue2
|
|
|
+ })
|
|
|
+ activeCardIdxList.value.splice(toDeleteIdx2, 1)
|
|
|
+ }, 400)
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.game-view{
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-image: url(@/assets/images/pair-up-bg.jpg);
|
|
|
+ background-size: cover;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: center center;
|
|
|
+ >img.title{
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ top: calc(35 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ transform: translate(-50%, 0);
|
|
|
+ width: calc(244 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ height: calc(80 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+
|
|
|
+ }
|
|
|
+ >.tip{
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ top: calc(122 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ transform: translate(-50%, 0);
|
|
|
+ font-size: calc(14 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ font-family: Source Han Sans SC, Source Han Sans SC;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ }
|
|
|
+ >.card-list{
|
|
|
+ position: absolute;
|
|
|
+ top: calc(163 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ left: calc(31 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ right: calc((31 - 9) / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ margin-right: calc(-12 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ >.card{
|
|
|
+ position: relative;
|
|
|
+ display: inline-block;
|
|
|
+ margin-right: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ margin-bottom: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ width: calc(75 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ height: calc(115 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ border-radius: calc(3 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ cursor: pointer;
|
|
|
+ transition: transform 0.4s;
|
|
|
+ >.front{
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ transition: transform 0.4s;
|
|
|
+ transform: rotateY(180deg);
|
|
|
+ >img.card-frame{
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ >img.card-content{
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ top: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ width: 70%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >img.back{
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ backface-visibility: hidden;
|
|
|
+ transition: transform 0.4s;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.card.active{
|
|
|
+ >.front{
|
|
|
+ transform: rotateY(0);
|
|
|
+ }
|
|
|
+ >img.back{
|
|
|
+ transform: rotateY(180deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.card.hide{
|
|
|
+ pointer-events: none;
|
|
|
+ transform: scale(0) rotateZ(360deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.btn-group{
|
|
|
+ position: absolute;
|
|
|
+ top: calc(36 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ right: calc(12 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ >button.return-home{
|
|
|
+ background-image: url(@/assets/images/icon_home.png);
|
|
|
+ background-size: contain;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: center center;
|
|
|
+ width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ }
|
|
|
+ >button.game-rule{
|
|
|
+ background-image: url(@/assets/images/icon_rules.png);
|
|
|
+ background-size: contain;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: center center;
|
|
|
+ width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.common-info-group{
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ bottom: calc(41 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ transform: translate(-50%, 0);
|
|
|
+ display: flex;
|
|
|
+ gap: calc(11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ >.info-item{
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-end;
|
|
|
+ width: calc(145 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ height: calc(31 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ padding-left: calc(5 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ padding-right: calc(18 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ >.icon{
|
|
|
+ }
|
|
|
+ >.number{
|
|
|
+ font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ font-family: Inter, Inter;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: calc(23 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.bonus-point{
|
|
|
+ >.icon{
|
|
|
+ width: calc(46 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ height: calc(41 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.time-count{
|
|
|
+ >.icon{
|
|
|
+ width: calc(37 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ height: calc(46 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|