完成成就

This commit is contained in:
unanmed 2023-02-22 22:27:42 +08:00
parent f3938bf1bb
commit 355378de9a
5 changed files with 178 additions and 25 deletions

View File

@ -8,6 +8,10 @@
></Studied>
<Fixed v-if="showStatusBar && useFixed"></Fixed>
<Chapter v-if="chapterShowed" :chapter="chapterContent"></Chapter>
<CompleteAchievement
v-if="showComplete"
:complete="completeAchi"
></CompleteAchievement>
</div>
</template>
@ -21,12 +25,14 @@ import {
import { chapterContent, chapterShowed } from './plugin/ui/chapter';
import { showMarkedEnemy } from './plugin/mark';
import { showStudied, useFixed } from './plugin/settings';
import { showComplete, completeAchi } from './plugin/ui/achievement';
import MarkedEnemy from './ui/markedEnemy.vue';
import StatusBar from './ui/statusBar.vue';
import Chapter from './ui/chapter.vue';
import Studied from './ui/studied.vue';
import Fixed from './ui/fixed.vue';
import Start from './ui/start.vue';
import CompleteAchievement from './ui/completeAchievement.vue';
</script>
<style lang="less" scoped>

View File

@ -1,17 +1,58 @@
import { ref } from 'vue';
import list from '../../data/achievement.json';
import { has } from '../utils';
type AchievementList = typeof list;
type AchievementType = keyof AchievementList;
export type AchievementType = keyof AchievementList;
type AchievementData = Record<AchievementType, boolean[]>;
export interface Achievement {
name: string;
text: string[];
point: number;
hide?: string;
progress?: string;
percent?: boolean;
}
export default function init() {
return {};
}
export function completeAchievement(type: AchievementType, index: number) {}
export const showComplete = ref(false);
export const completeAchi = ref('explore,1');
export const totalPoint = Object.values(list)
.map((v: Achievement[]) =>
v.reduce((prev, curr) => {
return curr.point + prev;
}, 0)
)
.reduce((prev, curr) => prev + curr);
/**
*
* @param type
* @param index
*/
export function completeAchievement(type: AchievementType, index: number) {
const now = core.getLocalStorage<AchievementData>('achievement', {
normal: [],
challenge: [],
explore: []
});
now[type][index] = true;
core.setLocalStorage('achievement', now);
completeAchi.value = `${type},${index}`;
showComplete.value = true;
}
/**
*
* @param type
* @param index
*/
export function hasCompletedAchievement(type: AchievementType, index: number) {
let data = core.getLocalStorage<AchievementData>('achievement');
if (!has(data)) {
@ -25,3 +66,18 @@ export function hasCompletedAchievement(type: AchievementType, index: number) {
}
return data[type][index] ?? false;
}
/**
*
*/
export function getNowPoint() {
let res = 0;
for (const [type, achi] of Object.entries(list)) {
achi.forEach((v, i) => {
if (hasCompletedAchievement(type as AchievementType, i)) {
res += v.point;
}
});
}
return res;
}

View File

@ -101,18 +101,12 @@ import { computed, ref } from 'vue';
import { achievementOpened, noClosePanel } from '../plugin/uiController';
import { LeftOutlined } from '@ant-design/icons-vue';
import list from '../data/achievement.json';
import { hasCompletedAchievement } from '../plugin/ui/achievement';
import {
Achievement,
getNowPoint,
hasCompletedAchievement
} from '../plugin/ui/achievement';
import Scroll from '../components/scroll.vue';
import { has } from '../plugin/utils';
interface Achievement {
name: string;
text: string[];
point: number;
hide?: string;
progress?: string;
percent?: boolean;
}
type AchievementList = typeof list;
type AchievementType = keyof AchievementList;
@ -151,17 +145,7 @@ const totalPoint = Object.values(list)
}, 0)
)
.reduce((prev, curr) => prev + curr);
const nowPoint = (function () {
let res = 0;
for (const [type, achi] of Object.entries(list)) {
achi.forEach((v, i) => {
if (hasCompletedAchievement(type as AchievementType, i)) {
res += v.point;
}
});
}
return res;
})();
const nowPoint = getNowPoint();
/**
* 获取一个类型的所有成就

View File

@ -0,0 +1,107 @@
<template>
<Box id="complete-box">
<div id="complete">
<span>完成成就&nbsp;&nbsp;&nbsp;&nbsp;{{ achi.name }}</span>
<a-progress
id="progress"
:percent="progress * 100"
:strokeColor="{
'0%': '#108ee9',
'100%': '#87d068'
}"
:strokeWidth="height / 200"
:showInfo="false"
></a-progress>
<span id="point-number">成就点: {{ now }} / {{ totalPoint }}</span>
</div>
</Box>
</template>
<script lang="ts" setup>
import { now } from 'lodash';
import { sleep, Ticker } from 'mutate-animate';
import { computed, onMounted, ref } from 'vue';
import Box from '../components/box.vue';
import list from '../data/achievement.json';
import {
AchievementType,
getNowPoint,
showComplete,
totalPoint
} from '../plugin/ui/achievement';
const height = window.innerHeight;
const props = defineProps<{
complete: string;
}>();
const c = props.complete.split(',');
const type = c[0] as AchievementType;
const index = parseInt(c[1]);
const achi = list[type][index];
const point = achi.point;
const nowPoint = getNowPoint() - point;
const now = ref(nowPoint);
const progress = computed(() => now.value / totalPoint);
onMounted(async () => {
await sleep(500);
const ticker = new Ticker();
const time = Date.now();
ticker.add(() => {
const nowTime = Date.now();
if (nowTime - time > 1000) {
now.value = nowPoint + point;
ticker.destroy();
}
const ratio = (nowTime - time) / 1000;
now.value = Math.round(nowPoint + point * ratio);
});
await sleep(4600);
showComplete.value = false;
});
</script>
<style lang="less" scoped>
#complete-box {
width: 30vw;
height: 13vh;
left: 35vw;
position: fixed;
background-color: #000d;
animation: ani 5s ease 0s 1 forwards running;
}
#complete {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
font-family: 'normal';
font-size: 2.2vh;
align-items: center;
justify-content: center;
}
#progress {
width: 90%;
}
@keyframes ani {
0% {
top: -30vh;
}
20% {
top: 4vh;
}
80% {
top: 4vh;
}
100% {
top: -30vh;
}
}
</style>

View File

@ -89,8 +89,8 @@ const text2 = ['轮回', '分支', '观测', '回忆'].reverse();
const ids = ['start-game', 'load-game', 'replay', 'achievement'].reverse();
const hardIds = ['easy', 'hard-hard', 'back'].reverse();
const text = ref(text1);
const hard = ['简单', '困难', '返回'].reverse();
const text = ref(text1);
const toshow = reactive<string[]>([]);
const selected = ref('start-game');