Browse Source

新增装备图鉴

dev
许孟阳 2 months ago
parent
commit
791220e0e9
  1. BIN
      src/assets/icons/menu/illustrated.png
  2. 137
      src/components/drawer.vue
  3. 9
      src/components/equip-icon.vue
  4. 5
      src/components/index.ts
  5. 4
      src/components/tabs/index.ts
  6. 36
      src/components/tabs/tab.vue
  7. 102
      src/components/tabs/tabs.vue
  8. 6
      src/config/equips/armor.ts
  9. 6
      src/config/equips/neck.ts
  10. 7
      src/config/equips/ring.ts
  11. 6
      src/config/equips/weapon.ts
  12. 8
      src/config/i18n/zh.ts
  13. 1
      src/config/icons.ts
  14. 76
      src/views/illustrated/equips.vue
  15. 69
      src/views/illustrated/illustrated.vue
  16. 3
      src/views/illustrated/index.ts
  17. 4
      src/views/menu.vue

BIN
src/assets/icons/menu/illustrated.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

137
src/components/drawer.vue

@ -0,0 +1,137 @@ @@ -0,0 +1,137 @@
<template>
<teleport to="#app">
<div class="drawer" @click="show = false" v-show="show"
@contextmenu.prevent="console.log('禁用浏览器默认右键功能')">
<div class="content" :style="style" @click.native.stop>
<div class="title" v-if="showHeader">
<span>{{ title }}</span>
<i class="close" @click="show = false; emit('close')"></i>
</div>
<slot />
</div>
</div>
</teleport>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { watch, onMounted, ref, onBeforeUnmount } from "vue";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const show = ref(false);
const style = ref({})
const emit = defineEmits(['update:modelValue', 'close'])
const prop = defineProps({
modelValue: {
type: Boolean,
default: false
},
showHeader: {
type: Boolean,
default: true
},
title: {
type: String,
defalut: ""
},
width: {
type: String,
default: ''
},
height: {
type: String,
default: ''
},
direction: {
type: String,
default: 'left'
},
padding: {
type: String,
default: '10px'
},
})
watch(show, (n, o) => {
emit('update:modelValue', n);
})
watch(() => prop.modelValue, (n, o) => {
show.value = n;
})
const setDirection = () => {
switch (prop.direction) {
case 'left':
style.value = { left: '0', width: prop.width, height: '100%' };
break;
case 'right':
style.value = { right: '0', width: prop.width, height: '100%' };
break;
case 'top':
style.value = { top: '0', width: '100%', height: prop.height };
break;
case 'bottom':
style.value = { bottom: '0', width: '100%', height: prop.height };
break;
}
}
watch(() => prop.direction, setDirection);
const keydown = (e) => {
if (e.keyCode == 27) {
show.value = false;
}
}
onMounted(() => {
setDirection();
document.addEventListener('keydown', keydown)
});
onBeforeUnmount(() => {
document.removeEventListener('keydown', keydown)
});
</script>
<style lang="scss" scoped>
.drawer {
width: 100%;
height: 100%;
position: absolute;
z-index: 9;
background: rgba(0, 0, 0, 0.5);
.content {
position: absolute;
background: rgba(0, 0, 0, 0.7);
padding: v-bind('prop.padding');
width: v-bind('prop.width');
}
}
.title {
display: flex;
position: relative;
align-items: center;
justify-content: center;
font-size: 1.8rem;
height: 3.5rem;
line-height: 3.5rem;
width: 100%;
color: white;
margin-bottom: 0.5rem;
.close {
cursor: pointer;
position: absolute;
top: 0.5rem;
right: 0.5rem;
display: block;
width: 2rem;
height: 2rem;
background-image: url(@/assets/icons/close.png);
background-size: cover;
}
}
</style>

9
src/components/equip-icon.vue

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
:style="{ 'box-shadow': 'inset 0 0 7px 2px ' + ((equip && equip.quality.color) || '#a1a1a1') }">
<span v-if="equip">
<img :src="require('@/assets/icons/equips/' + equip.base.icon)">
<div class="lv">lv{{ equip.lv }}</div>
<div class="lv" v-if="equip.lv">lv{{ equip.lv }}</div>
</span>
</div>
</template>
@ -25,12 +25,12 @@ const prop = defineProps({ @@ -25,12 +25,12 @@ const prop = defineProps({
})
const isUnique = (equip) => {
if(!equip){
if (!equip) {
return false;
}
const quality = equip.quality.quality;
return quality && quality == qualitys[4];
}
}
const iconClass = computed(() => {
if (prop.equip && prop.equip.isUnique()) {
@ -51,7 +51,8 @@ onMounted(() => { }); @@ -51,7 +51,8 @@ onMounted(() => { });
justify-content: center;
border-radius: 0.3rem;
position: relative;
.lv{
.lv {
position: absolute;
left: 0.1rem;
bottom: 0.1rem;

5
src/components/index.ts

@ -4,6 +4,9 @@ import EquipTip from './equip-tip.vue'; @@ -4,6 +4,9 @@ import EquipTip from './equip-tip.vue';
import EquipTips from './equip-tips.vue';
import EquipIcon from './equip-icon.vue';
import Dialog from './dialog.vue';
import Drawer from './drawer.vue';
import PopoverMenu from './popover-menu.vue';
import Confirm from './confirm.vue';
export { Tooltip, Equip, EquipTip, EquipTips, EquipIcon, Dialog, PopoverMenu, Confirm };
export { Tooltip, Equip, EquipTip, EquipTips, EquipIcon, Dialog, Drawer, PopoverMenu, Confirm };
export * from './tabs';

4
src/components/tabs/index.ts

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
import Tab from './tab.vue';
import Tabs from './tabs.vue';
export { Tabs, Tab };

36
src/components/tabs/tab.vue

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
<template>
<div v-show="isSelected" class="tab__pane">
<slot />
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { getCurrentInstance, onMounted, ref, computed, watch } from "vue";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const parent: any = getCurrentInstance()?.parent;
const name = ref("");
const props = defineProps({
label: {
type: String,
default: ''
},
name: {
type: String,
default: ''
}
})
const isSelected = computed(() => {
return parent.exposed.curActive.value == props.name;
})
onMounted(() => {
name.value = props.name;
});
</script>
<style lang="scss" scoped></style>

102
src/components/tabs/tabs.vue

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
<template>
<div class="tabs">
<div class="tabs__nav">
<div v-for="item in tabs" :key="item.name" ref="tabs" @click="curActive = item.name" class="tab"
:class="{ 'tab--active': item.name === curActive }">
<span>{{ item.label || item.name }}</span>
</div>
</div>
<slot />
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { watch, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const curActive = ref('');
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue: {
type: String,
default: ''
},
active: {
type: String,
default: ''
},
tabs: {
type: Array as () => any[],
default: []
}
})
watch(curActive, (n, o) => {
emit('update:modelValue', n);
})
watch(() => props.modelValue, (n, o) => {
curActive.value = n;
})
defineExpose({ curActive })
onMounted(() => {
curActive.value = props.active || props.tabs[0]?.name;
});
</script>
<style lang="scss" scoped>
*{
color: white;
}
.tab {
// flex: 1;
cursor: pointer;
min-width: 0;
padding: 0.3rem 0.3rem;
font-size: 14px;
position: relative;
color: #000;
line-height: 50px;
text-align: center;
box-sizing: border-box;
margin-right: 2rem;
span {
display: block;
}
&--active {
font-weight: 500 !important;
}
}
.tab--active {
border-bottom: 2px solid #ccc;
}
.tabs {
position: relative;
&__nav {
display: flex;
user-select: none;
position: relative;
height: 100%;
box-sizing: content-box;
}
&__line {
z-index: 1;
left: 0;
bottom: 0px;
height: 3px;
position: absolute;
border-radius: 3px;
background-color: red;
}
}
</style>

6
src/config/equips/armor.ts

@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './ @@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './
const extraEntrys = ['atk', 'hp', 'def', 'defPercent', 'hpPercent'];
const uniqueCategorys = [
export const armorUniqueCategorys = [
{
name: 'dispute',
icon: 'U_Armor01.png',
@ -67,7 +67,7 @@ const uniqueCategorys = [ @@ -67,7 +67,7 @@ const uniqueCategorys = [
],
},
];
const categorys = [
export const armorCategorys = [
{
name: 'guard',
icon: 'A_A2.png',
@ -141,7 +141,7 @@ export const armorExtraEntry = (quality, lv) => { @@ -141,7 +141,7 @@ export const armorExtraEntry = (quality, lv) => {
};
const createBase = (quality, lv) => {
const array = quality == 'unique' ? uniqueCategorys : categorys;
const array = quality == 'unique' ? armorUniqueCategorys : armorCategorys;
const category = array[Math.floor(Math.random() * array.length)];
const entry = new Array();
category.entry.forEach((item) => {

6
src/config/equips/neck.ts

@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './ @@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './
const extraEntrys = ['atk', 'crit', 'critDmg', 'hp', 'def', 'bloc'];
const uniqueCategorys = [
export const neckUniqueCategorys = [
{
name: 'demonSlayer',
icon: 'U_neck01.png',
@ -49,7 +49,7 @@ const uniqueCategorys = [ @@ -49,7 +49,7 @@ const uniqueCategorys = [
],
},
];
const categorys = [
export const neckCategorys = [
{
name: 'crusade',
icon: 'Ac_1.png',
@ -108,7 +108,7 @@ export const neckExtraEntry = (quality, lv) => { @@ -108,7 +108,7 @@ export const neckExtraEntry = (quality, lv) => {
};
const createBase = (quality, lv) => {
const array = quality == 'unique' ? uniqueCategorys : categorys;
const array = quality == 'unique' ? neckUniqueCategorys : neckCategorys;
const category = array[Math.floor(Math.random() * array.length)];
const entry = new Array();
category.entry.forEach((item) => {

7
src/config/equips/ring.ts

@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './ @@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './
const extraEntrys = ['atk', 'crit', 'critDmg', 'hp', 'def'];
const uniqueCategorys = [
export const ringUniqueCategorys = [
{
name: 'death',
icon: 'U_ring01.png',
@ -48,7 +48,7 @@ const uniqueCategorys = [ @@ -48,7 +48,7 @@ const uniqueCategorys = [
],
},
];
const categorys = [
export const ringCategorys = [
{
name: 'life',
icon: 'Ac_9.png',
@ -102,7 +102,7 @@ export const ringExtraEntry = (quality, lv) => { @@ -102,7 +102,7 @@ export const ringExtraEntry = (quality, lv) => {
};
const createBase = (quality, lv) => {
const array = quality == 'unique' ? uniqueCategorys : categorys;
const array = quality == 'unique' ? ringUniqueCategorys : ringCategorys;
const category = array[Math.floor(Math.random() * array.length)];
const entry = new Array();
category.entry.forEach((item) => {
@ -112,4 +112,3 @@ const createBase = (quality, lv) => { @@ -112,4 +112,3 @@ const createBase = (quality, lv) => {
});
return new EquipBase(category.name, category.icon, entry);
};

6
src/config/equips/weapon.ts

@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './ @@ -3,7 +3,7 @@ import { qualitys, entry_initor, extra_entry_num, quality_coefficient } from './
const extraEntrys = ['atk', 'crit', 'critDmg', 'hp', 'def', 'atkPercent', 'defPercent', 'hpPercent'];
const uniqueCategorys = [
export const weaponUniqueCategorys = [
{
name: 'creation',
icon: 'U_Sword01.png',
@ -87,7 +87,7 @@ const uniqueCategorys = [ @@ -87,7 +87,7 @@ const uniqueCategorys = [
],
},
];
const categorys = [
export const weaponCategorys = [
{
name: 'hellrock',
icon: 'W_Sword016.png',
@ -169,7 +169,7 @@ export const weaponExtraEntry = (quality, lv) => { @@ -169,7 +169,7 @@ export const weaponExtraEntry = (quality, lv) => {
};
const createBase = (quality, lv) => {
const array = quality == 'unique' ? uniqueCategorys : categorys;
const array = quality == 'unique' ? weaponUniqueCategorys : weaponCategorys;
const category = array[Math.floor(Math.random() * array.length)];
const entry = new Array();
category.entry.forEach((item) => {

8
src/config/i18n/zh.ts

@ -106,9 +106,9 @@ export default class Zh { @@ -106,9 +106,9 @@ export default class Zh {
neaten = '一键整理';
use = '装备';
strengthen = '强化';
stren = ['需要金币', '强化至','垫一刀', '自动强化目标等级', '自动强化', '自动强化中', '中断自动强化'];
success= '成功';
fail= '失败';
stren = ['需要金币', '强化至', '垫一刀', '自动强化目标等级', '自动强化', '自动强化中', '中断自动强化'];
success = '成功';
fail = '失败';
stDesc = [
'强化说明',
'花费金币强化装备',
@ -172,4 +172,6 @@ export default class Zh { @@ -172,4 +172,6 @@ export default class Zh {
importArchive = ['导入', '导入存档成功,继续游戏吧!', '导入存档失败'];
music = ['播放或禁音背景音乐(M)'];
illustrated = ['装备图鉴(I)'];
}

1
src/config/icons.ts

@ -8,6 +8,7 @@ export const menu_icons = { @@ -8,6 +8,7 @@ export const menu_icons = {
importGame: require('@/assets/icons/menu/icon-import.png'),
musicPlay: require('@/assets/icons/menu/music-play.png'),
musicPause: require('@/assets/icons/menu/music-pause.png'),
illustrated: require('@/assets/icons/menu/illustrated.png'),
};
export const attr_icon_urls = {

76
src/views/illustrated/equips.vue

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
<template>
<div class="title">{{ t('quality.' + quality) }}{{ t(type + '.type') }}
</div>
<div class="equips">
<div class="equip" v-for="item in categorys" :key="item.name">
<EquipIcon :equip="getShowEquip(item)" />
<div class="name">{{ t(type + '.' + item.name + '.0') }}</div>
<div class="entry" v-for="e in item.entry">{{ t(e.type + '.0') }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
import { EquipIcon } from "@/components";
import { quality_collor } from "@/config";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const color = ref('#FFF');
const props = defineProps({
type: {
type: String,
default: ''
},
quality: {
type: String,
default: ''
},
categorys: {
type: Array as () => any[],
default: [],
},
});
const getShowEquip = (category) => {
const quality = props.quality;
const equip: any = new Object();
equip.quality = { quality: quality, color: quality_collor[quality] };
equip.base = { icon: category.icon };
return equip;
}
onMounted(() => {
color.value = quality_collor[props.quality];
});
</script>
<style lang="scss" scoped>
.title {
height: 2.5rem;
font-size: 1.5rem;
color: v-bind('color');
}
.equips {
display: flex;
flex-wrap: wrap;
width: 50rem;
.equip {
align-items: center;
text-align: center;
justify-items: center;
width: 10rem;
margin-bottom: 1rem;
.name {
padding-bottom: 0.5rem;
color: v-bind('color');
}
}
}
</style>

69
src/views/illustrated/illustrated.vue

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
<template>
<Tooltip :infos="[t('illustrated.0')]" width="8rem">
<img class="menu-img" :src="menu_icons.illustrated" @click="showMenu">
</Tooltip>
<Drawer :title="t('illustrated.0')" v-model="showIllustrated">
<Tabs :tabs="tabs">
<tab v-for="item in tabs" :name="item.name">
<Equips :type="item.name" quality="unique" :categorys="uniques[item.name]" />
<Equips :type="item.name" quality="epic" :categorys="epics[item.name]" />
</tab>
</Tabs>
</Drawer>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { computed, onMounted, ref, onBeforeUnmount } from "vue";
import { useI18n } from "vue3-i18n";
import { Tooltip, Drawer, Tabs, Tab } from "@/components";
import { menu_icons, weaponCategorys, weaponUniqueCategorys, armorUniqueCategorys, armorCategorys } from "@/config";
import { neckUniqueCategorys, neckCategorys, ringUniqueCategorys, ringCategorys } from "@/config";
import Equips from "./equips.vue";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const showIllustrated = computed(() => {
return state.curMenu == 'illustrated';
});
const uniques = {
weapon: weaponUniqueCategorys,
armor: armorUniqueCategorys,
neck: neckUniqueCategorys,
ring: ringUniqueCategorys
}
const epics = {
weapon: weaponCategorys,
armor: armorCategorys,
neck: neckCategorys,
ring: ringCategorys
}
const tabs = [
{ label: t('weapon.type'), name: 'weapon' },
{ label: t('armor.type'), name: 'armor' },
{ label: t('neck.type'), name: 'neck' },
{ label: t('ring.type'), name: 'ring' }
]
const showMenu = () => {
state.curMenu = showIllustrated.value ? null : 'illustrated';
}
const keydown = (e) => {
if (e.keyCode == 73 && !e.ctrlKey) {
showMenu();
}
}
onMounted(() => {
document.addEventListener('keydown', keydown);
});
onBeforeUnmount(() => {
document.removeEventListener('keydown', keydown);
})
</script>
<style lang="scss" scoped></style>

3
src/views/illustrated/index.ts

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
import Illustrated from './illustrated.vue';
export default Illustrated;

4
src/views/menu.vue

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
<Archive />
<Dungeon />
<Music />
<Illustrated />
</div>
</template>
@ -21,6 +22,7 @@ import Reborn from "./reborn"; @@ -21,6 +22,7 @@ import Reborn from "./reborn";
import SaveGame from "./save-game.vue";
import Archive from "./archive.vue";
import Music from "./music.vue";
import Illustrated from "./illustrated";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
@ -33,7 +35,7 @@ onMounted(() => { }); @@ -33,7 +35,7 @@ onMounted(() => { });
top: 1rem;
background: rgba($color: #000000, $alpha: 0.1);
left: 0.5rem;
bottom:0.5rem;
bottom: 0.5rem;
padding: 0.1rem;
border-top-right-radius: 0.1rem;
// width:2.5rem;

Loading…
Cancel
Save