mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 04:19:30 +08:00
完成成就
This commit is contained in:
parent
f3938bf1bb
commit
355378de9a
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
/**
|
||||
* 获取一个类型的所有成就
|
||||
|
107
src/ui/completeAchievement.vue
Normal file
107
src/ui/completeAchievement.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<Box id="complete-box">
|
||||
<div id="complete">
|
||||
<span>完成成就 {{ 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>
|
@ -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');
|
||||
|
Loading…
Reference in New Issue
Block a user