一个全随机的刷装备小游戏
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
5.4 KiB

2 weeks ago
<template>
<div v-if="dungeon" class="battle">
<div class="player">
<img class="player-icon" :src="dungeon_icon.player">
2 weeks ago
</div>
<div class="monster" v-for="(v, k) in dungeon.monsters" :key="k"
:style="{ left: (95 / dungeon.monsters.length) * (k + 1) + '%' }">
<img :src="dungeon_icon[v.type]">
</div>
<div class="progress-bar"></div>
<button @click="stopDungeon" class="button">{{ t('stopDungeon.0') }}</button>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { computed, nextTick, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
import { dungeon_icon, player_move_time, player_battle_time } from "@/config";
import { randonBootyEquip, callBattleResult } from "@/tool";
2 weeks ago
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const battle = computed(() => {
return state.battle;
})
const props = defineProps({
dungeon: {
type: Object,
}
})
const startDungeon = () => {
const dungeon = props.dungeon;
if (!dungeon) {
return;
}
dispatch('play_music', 'battle');
playerMove(0, 0);
const msg = t('startDungeon') + 'lv' + dungeon.lv + '_' + t('difficulty.' + dungeon.difficulty);
commit("set_sys_info", { msg: msg, type: 'warning' });
}
defineExpose({ startDungeon })
const stopDungeon = () => {
for (let i = 0; i < 5; i++) {
clearTimeout(battle.value.timeOut);
}
battle.value.battleShow = false;
dispatch('play_music', 'backgound');
commit("set_sys_info", { msg: t('stopDungeon.1'), type: 'warning' });
}
const exploreDungeon = (monsterIdx) => {
let idx2 = monsterIdx || 0;
const dungeon = props.dungeon;
if (!dungeon) {
return;
}
const monster = dungeon.monsters[idx2];
battleWithMonster(monster).then(rsp => {
idx2++;
if (idx2 < dungeon.monsters.length) {
playerMove(idx2);
} else {
commit("set_sys_info", { msg: t('dungeonSuccess'), type: 'battle' });
if (dungeon.lv > state.playerAttribute.lv) {
commit('set_player_lv', dungeon.lv)
commit('set_sys_info', { msg: t('upgrade'), type: 'win' })
}
if (dungeon.difficulty != 1) {
dungeon.setDifficulty(1);
battle.value.battleShow = false;
dispatch('play_music', 'backgound');
} else {
playerMove(0, 0);
}
}
})
}
const playerMove = (monsterIdx?, playerIdx?) => {
let idx2 = playerIdx || 0;
const max = 20;
const lenght = 95 / props.dungeon?.monsters.length;
const left = monsterIdx * lenght + lenght / (max + 1) * idx2;
battle.value.left = + left + '%';
const position = Math.floor(left % 4) * 32;
battle.value.imgLeft = -1 * position + 'px';
battle.value.clip = 'rect(96px, ' + (position + 32) + 'px, 144px, ' + position + 'px)'
2 weeks ago
if (idx2 > max) {
exploreDungeon(monsterIdx);
} else {
idx2++;
const moveTime = Math.round(player_move_time * 100 / (100 + state.rebornAttribute.moveSpeed) / max);
battle.value.timeOut = setTimeout(() => {
playerMove(monsterIdx, idx2);
}, moveTime);
}
}
const battleWithMonster = (monster) => {
return new Promise((resolve, reject) => {
const player = state.playerAttribute.attribute;
const battleTime = Math.round(player_battle_time * 100 / (100 + state.rebornAttribute.battleSpeed))
const getMsg = (i18nName, takeDmg) => {
return t(i18nName).replace('${lv}', monster.lv).replace('${name}', t('difficulty.' + props.dungeon?.difficulty) + t(monster.type)).replace('${dmg}', takeDmg + '');
2 weeks ago
};
commit("set_sys_info", { msg: getMsg('battle', 0), type: 'battle' });
2 weeks ago
battle.value.timeOut = setTimeout(() => {
const result = callBattleResult(player, monster);
2 weeks ago
nextTick(() => {
commit('add_player_curhp', -1 * result.takeDmg);
2 weeks ago
})
if (result.win) {
commit("set_sys_info", { msg: getMsg('killMonster', result.takeDmg), type: 'battle', bouts: result.bouts });
2 weeks ago
//随机获取装备战利品
const equips = randonBootyEquip(monster);
commit('add_bootys', { equips: equips, coins: monster.coins });
resolve(true);
} else {
commit("set_sys_info", { msg: getMsg('beKilled', result.takeDmg), type: 'warning', bouts: result.bouts });
2 weeks ago
battle.value.battleShow = false;
dispatch('play_music', 'backgound');
}
}, battleTime);
});
}
onMounted(() => { });
</script>
<style lang="scss" scoped>
.battle {
width: 100%;
2 weeks ago
.player {
overflow: hidden;
2 weeks ago
position: absolute;
z-index: 2;
top: 1.2rem;
height: 48px;
width: 32px;
left: v-bind('state.battle.left');
.player-icon {
top: -96px;
left: v-bind('state.battle.imgLeft');
position: absolute;
clip: v-bind('state.battle.clip');
}
2 weeks ago
}
.monster {
position: absolute;
top: 2rem;
}
.progress-bar {
position: absolute;
top: 5rem;
left: 0.7rem;
right: 0.7rem;
border: 1px solid #fff;
}
.button {
position: absolute;
top: 6rem;
right: 1.2rem;
}
}
</style>