123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <script setup lang="ts">
- import { showSuccessToast } from 'vant'
- import GameAPI, { type GameResultVO, type GameVO, type Result, type ResultLevel } from '@/api/game'
- const router = useRouter()
- const subjectInfo = ref<GameVO>({})
- // 控制倒计时的显隐
- const showCountDown = ref(true)
- // 显示题目文本
- const showSpanText = ref('')
- // 测试总次数
- const totalCount = ref(0)
- // 当前题答案
- const currentAnswer = ref(0)
- // 正确总次数
- const rightCount = ref(0)
- // 当前轮正确次数
- const currentRoundRightCount = ref(0)
- // 连续对3次
- const rightThree = ref(0)
- // 连续错两次
- const wrongTwo = ref(0)
- // 当前轮需要计算的数字个数
- const additionNumCount = ref(2)
- // 统计每个层级答对个数
- const rightCountList: Result[] = reactive([])
- // 测试时长 100 秒
- const gameDuration = ref(100 * 1000)
- // 游戏结束时间戳
- const gameEndTime = ref(0)
- // 游戏开始时间戳
- const gameStartTime = ref(0)
- // 游戏收集的数据
- const gameData: GameResultVO = {
- finish: '1',
- gameId: subjectInfo.value.id,
- gameName: subjectInfo.value.name,
- userId: sessionStorage.getItem('userId'),
- paramList: [],
- levelList: [],
- }
- function nNumRightCount() {
- const isIndex = rightCountList.findIndex(item => Number.parseInt(item.name) === additionNumCount.value)
- if (isIndex !== -1) {
- if (typeof rightCountList[isIndex].value === 'number') {
- rightCountList[isIndex].value++
- }
- }
- else {
- rightCountList.push({
- name: additionNumCount.value.toString(),
- value: 1,
- })
- }
- }
- function createComputeSpanText() {
- // 生成下一道题和答案
- const tempSpanText: number[] = []
- let additionResult = 0
- for (let i = additionNumCount.value; i > 0; i--) {
- const tempNum = Math.floor(Math.random() * 10)
- additionResult += tempNum
- tempSpanText.push(tempNum)
- }
- showSpanText.value = tempSpanText.join('+')
- currentAnswer.value = additionResult % 10
- }
- function userClick(answer: number) {
- // 如果游戏时长大于或等于 100 秒,则游戏结束
- gameEndTime.value = performance.now()
- const duration = gameEndTime.value - gameStartTime.value
- if (duration >= gameDuration.value) {
- // 游戏结束,发送数据
- sendData()
- return
- }
- // 用户点击动作
- totalCount.value++
- if (answer === currentAnswer.value) {
- // 正确次数
- rightCount.value++
- // 当前数字个数计算正确数加1
- nNumRightCount()
- // 本轮正确次数
- currentRoundRightCount.value++
- rightThree.value++
- wrongTwo.value = 0
- if (rightThree.value >= 3 && wrongTwo.value === 0) {
- additionNumCount.value++
- rightThree.value = 0
- wrongTwo.value = 0
- }
- }
- else {
- // 正式测试时要做降级处理
- currentRoundRightCount.value = 0
- rightThree.value = 0
- wrongTwo.value++
- if (additionNumCount.value > 2 && rightThree.value === 0 && wrongTwo.value >= 2) {
- additionNumCount.value--
- rightThree.value = 0
- wrongTwo.value = 0
- }
- }
- // 生成下一道题
- createComputeSpanText()
- }
- /**
- * 倒计时结束时的回调
- */
- function endCountDown() {
- // 隐藏倒计时组件
- showCountDown.value = false
- // 开始生成游戏的第一道题
- createComputeSpanText()
- // 记录游戏开始时间戳
- gameStartTime.value = performance.now()
- // 重置游戏结束时间戳
- gameEndTime.value = 0
- // 重置收集的游戏数据
- }
- function sendData() {
- const totalScore = rightCountList.reduce((acc, curr) => {
- acc += curr.value as number * 2 ** (Number.parseInt(curr.name) - 2)
- return acc
- }, 0)
- gameData.levelList = rightCountList.map((item) => {
- return {
- level: item.name,
- levelParamList: [{ ...item }],
- } as ResultLevel
- })
- gameData.paramList = [
- {
- code: 'totalScore',
- name: '总分',
- value: totalScore === 0 ? 0 : Number.parseFloat(Math.log2(totalScore).toString()).toFixed(2),
- },
- {
- code: 'totalCount',
- name: '题目总数',
- value: totalCount.value,
- },
- {
- code: 'rightCount',
- name: '总正确数',
- value: rightCount.value,
- },
- ]
- GameAPI.add(gameData).then(() => {
- showSuccessToast('本次训练已结束')
- setTimeout(() => {
- router.go(-1)
- }, 1300)
- })
- }
- onMounted(() => {
- const temp = sessionStorage.getItem('subjectInfo')
- if (temp) {
- subjectInfo.value = JSON.parse(temp)
- }
- })
- </script>
- <template>
- <section class="app-container">
- <van-nav-bar class="self-nav-bar" :title="subjectInfo.name" left-arrow @click-left="router.go(-1)" />
- <count-down v-if="showCountDown" :time="5" color="white" @end-count-down="endCountDown" />
- <div v-else style="" class="w-[90%] mx-auto mt-[15px] p-[15px] border-6 border-white border-solid rounded-[8px] bg-[#425363]">
- <div class="h-[80px] flex flex-row justify-center items-center bg-[#D2E2F1] rounded-[8px]">
- <span class="text-[40px] text-[#222222]">{{ showSpanText }}</span>
- </div>
- <div class="flex flex-row justify-between mt-[24px]">
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(1)">
- <span class="text-[32px] text-[#222222]">1</span>
- </div>
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(2)">
- <span class="text-[32px] text-[#222222]">2</span>
- </div>
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(3)">
- <span class="text-[32px] text-[#222222]">3</span>
- </div>
- </div>
- <div class="flex flex-row justify-between mt-[24px]">
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(4)">
- <span class="text-[32px] text-[#222222]">4</span>
- </div>
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(5)">
- <span class="text-[32px] text-[#222222]">5</span>
- </div>
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(6)">
- <span class="text-[32px] text-[#222222]">6</span>
- </div>
- </div>
- <div class="flex flex-row justify-between mt-[24px]">
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(7)">
- <span class="text-[32px] text-[#222222]">7</span>
- </div>
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(8)">
- <span class="text-[32px] text-[#222222]">8</span>
- </div>
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(9)">
- <span class="text-[32px] text-[#222222]">9</span>
- </div>
- </div>
- <div class="flex flex-row justify-center mt-[24px]">
- <div class="w-[72px] h-[72px] flex flex-row justify-center items-center bg-white rounded-[8px]" @click="userClick(0)">
- <span class="text-[32px] text-[#222222]">0</span>
- </div>
- </div>
- </div>
- </section>
- </template>
- <style scoped lang="less">
- .app-container {
- background-image: url('/static/image/game/bg-continue-addition.png');
- background-size: 100% 100%;
- background-position: center center;
- background-repeat: no-repeat;
- :deep(.van-nav-bar) {
- &.self-nav-bar {
- .van-nav-bar__title {
- color: #ffffff;
- }
- .van-icon {
- color: #ffffff;
- }
- }
- }
- }
- </style>
|