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>
|
></Studied>
|
||||||
<Fixed v-if="showStatusBar && useFixed"></Fixed>
|
<Fixed v-if="showStatusBar && useFixed"></Fixed>
|
||||||
<Chapter v-if="chapterShowed" :chapter="chapterContent"></Chapter>
|
<Chapter v-if="chapterShowed" :chapter="chapterContent"></Chapter>
|
||||||
|
<CompleteAchievement
|
||||||
|
v-if="showComplete"
|
||||||
|
:complete="completeAchi"
|
||||||
|
></CompleteAchievement>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -21,12 +25,14 @@ import {
|
|||||||
import { chapterContent, chapterShowed } from './plugin/ui/chapter';
|
import { chapterContent, chapterShowed } from './plugin/ui/chapter';
|
||||||
import { showMarkedEnemy } from './plugin/mark';
|
import { showMarkedEnemy } from './plugin/mark';
|
||||||
import { showStudied, useFixed } from './plugin/settings';
|
import { showStudied, useFixed } from './plugin/settings';
|
||||||
|
import { showComplete, completeAchi } from './plugin/ui/achievement';
|
||||||
import MarkedEnemy from './ui/markedEnemy.vue';
|
import MarkedEnemy from './ui/markedEnemy.vue';
|
||||||
import StatusBar from './ui/statusBar.vue';
|
import StatusBar from './ui/statusBar.vue';
|
||||||
import Chapter from './ui/chapter.vue';
|
import Chapter from './ui/chapter.vue';
|
||||||
import Studied from './ui/studied.vue';
|
import Studied from './ui/studied.vue';
|
||||||
import Fixed from './ui/fixed.vue';
|
import Fixed from './ui/fixed.vue';
|
||||||
import Start from './ui/start.vue';
|
import Start from './ui/start.vue';
|
||||||
|
import CompleteAchievement from './ui/completeAchievement.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
@ -1,17 +1,58 @@
|
|||||||
|
import { ref } from 'vue';
|
||||||
import list from '../../data/achievement.json';
|
import list from '../../data/achievement.json';
|
||||||
import { has } from '../utils';
|
import { has } from '../utils';
|
||||||
|
|
||||||
type AchievementList = typeof list;
|
type AchievementList = typeof list;
|
||||||
type AchievementType = keyof AchievementList;
|
export type AchievementType = keyof AchievementList;
|
||||||
|
|
||||||
type AchievementData = Record<AchievementType, boolean[]>;
|
type AchievementData = Record<AchievementType, boolean[]>;
|
||||||
|
|
||||||
|
export interface Achievement {
|
||||||
|
name: string;
|
||||||
|
text: string[];
|
||||||
|
point: number;
|
||||||
|
hide?: string;
|
||||||
|
progress?: string;
|
||||||
|
percent?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export default function init() {
|
export default function init() {
|
||||||
return {};
|
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) {
|
export function hasCompletedAchievement(type: AchievementType, index: number) {
|
||||||
let data = core.getLocalStorage<AchievementData>('achievement');
|
let data = core.getLocalStorage<AchievementData>('achievement');
|
||||||
if (!has(data)) {
|
if (!has(data)) {
|
||||||
@ -25,3 +66,18 @@ export function hasCompletedAchievement(type: AchievementType, index: number) {
|
|||||||
}
|
}
|
||||||
return data[type][index] ?? false;
|
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 { achievementOpened, noClosePanel } from '../plugin/uiController';
|
||||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||||
import list from '../data/achievement.json';
|
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 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 AchievementList = typeof list;
|
||||||
type AchievementType = keyof AchievementList;
|
type AchievementType = keyof AchievementList;
|
||||||
@ -151,17 +145,7 @@ const totalPoint = Object.values(list)
|
|||||||
}, 0)
|
}, 0)
|
||||||
)
|
)
|
||||||
.reduce((prev, curr) => prev + curr);
|
.reduce((prev, curr) => prev + curr);
|
||||||
const nowPoint = (function () {
|
const nowPoint = 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;
|
|
||||||
})();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取一个类型的所有成就
|
* 获取一个类型的所有成就
|
||||||
|
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 ids = ['start-game', 'load-game', 'replay', 'achievement'].reverse();
|
||||||
const hardIds = ['easy', 'hard-hard', 'back'].reverse();
|
const hardIds = ['easy', 'hard-hard', 'back'].reverse();
|
||||||
const text = ref(text1);
|
|
||||||
const hard = ['简单', '困难', '返回'].reverse();
|
const hard = ['简单', '困难', '返回'].reverse();
|
||||||
|
const text = ref(text1);
|
||||||
const toshow = reactive<string[]>([]);
|
const toshow = reactive<string[]>([]);
|
||||||
|
|
||||||
const selected = ref('start-game');
|
const selected = ref('start-game');
|
||||||
|
Loading…
Reference in New Issue
Block a user