Browse Source

更新(详情见description)

1.调整战斗逻辑,战斗伤害不再使用用期望值,每回合伤害独立计算,击败怪物的回合怪物将不造成伤害
2.新增战斗过程查看
master
许孟阳 2 weeks ago
parent
commit
ab23228b6b
  1. BIN
      src/assets/icons/tips.png
  2. 43
      src/components/tooltip.vue
  3. 2
      src/config/i18n/zh.ts
  4. 32
      src/tool/caller.ts
  5. 23
      src/views/dungeon/battle.vue
  6. 51
      src/views/message/bouts.vue
  7. 20
      src/views/message/sys-info.vue
  8. 11
      src/views/version/update-log.vue

BIN
src/assets/icons/tips.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

43
src/components/tooltip.vue

@ -4,6 +4,7 @@
<slot></slot> <slot></slot>
</div> </div>
<div class="c-tooltip-tip" :class="placement" v-if="tipsShow" :style='tipsStyle'> <div class="c-tooltip-tip" :class="placement" v-if="tipsShow" :style='tipsStyle'>
<img v-if="showIcon" src="/img/tips.png" class="tip-icons"></img>
<p v-for="info in infos" class="info">* {{ info }}</p> <p v-for="info in infos" class="info">* {{ info }}</p>
<slot name="tip"></slot> <slot name="tip"></slot>
</div> </div>
@ -18,7 +19,9 @@ import { useI18n } from "vue3-i18n";
const { t } = useI18n(); const { t } = useI18n();
const { state, commit, dispatch } = useStore(); const { state, commit, dispatch } = useStore();
const tipsShow = ref(false); const tipsShow = ref(false);
const tipsStyle = ref({}); const tipsStyle = ref({
transform: ''
});
const prop = defineProps({ const prop = defineProps({
placement: { placement: {
@ -31,16 +34,25 @@ const prop = defineProps({
width: { width: {
type: String, type: String,
default: '16rem' default: '16rem'
},
showIcon: {
type: Boolean,
default: true
},
x: {
type: String,
default: null
} }
}) })
const showTips = (e) => { const showTips = (e) => {
const x = e.pageX, y = e.pageY, maxH = window.innerHeight, maxW = window.innerWidth; const x = e.pageX, y = e.pageY, maxH = window.innerHeight, maxW = window.innerWidth;
const xt = x < 100 ? '15%' : y < maxH - 100 ? '0%' : '-40%'; let xt = x < 100 ? '15%' : y < maxH - 100 ? '0%' : '-40%';
const yt = y < maxH - 200 ? '100%' : '-50%'; if (prop.x) {
tipsStyle.value = { xt = prop.x;
transform: 'translate(' + xt + ', ' + yt + ')'
} }
const yt = y < maxH / 2 ? '100%' : '-50%';
tipsStyle.value.transform = 'translate(' + xt + ', ' + yt + ')';
tipsShow.value = true tipsShow.value = true
} }
const closeTips = () => { const closeTips = () => {
@ -66,28 +78,27 @@ onMounted(() => { });
border-radius: 4px; border-radius: 4px;
padding: 1.2rem; padding: 1.2rem;
background: #111111; background: #111111;
padding-top: 3.6rem; // padding-top: 3.6rem;
font-size: 0.86rem; font-size: 0.86rem;
font-weight: normal; font-weight: normal;
z-index: 9999; z-index: 9999;
box-shadow: 0 0 3px 3px rgba($color: #000000, $alpha: 1.0); box-shadow: 0 0 3px 3px rgba($color: #000000, $alpha: 1.0);
.info { .tip-icons {
font-weight: normal; // position: absolute;
margin-top: 0.4rem; margin-left: 50%;
}
&::after {
position: absolute;
top: 0.4rem;
left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
display: flex; display: flex;
width: 3.2rem; width: 3.2rem;
height: 3.2rem; height: 3.2rem;
background-image: url(@/assets/icons/tips.png);
background-size: cover; background-size: cover;
} }
.info {
font-weight: normal;
margin-top: 0.4rem;
}
} }
.top { .top {

2
src/config/i18n/zh.ts

@ -2,6 +2,7 @@ export default class Zh {
title = '挂机放置游戏'; title = '挂机放置游戏';
welcome = ['欢迎你勇士,点击地图上的副本开始战斗。', '界面左上角菜单可以打开世界副本地图。']; welcome = ['欢迎你勇士,点击地图上的副本开始战斗。', '界面左上角菜单可以打开世界副本地图。'];
sys = '系统';
loadEmpty = '未读取到存档!'; loadEmpty = '未读取到存档!';
loadError = '存档坏了!'; loadError = '存档坏了!';
@ -146,6 +147,7 @@ export default class Zh {
eliteMonster = '无尽模式精英怪'; eliteMonster = '无尽模式精英怪';
startDungeon = '你已进入'; startDungeon = '你已进入';
battle = '你遭遇了(lv${lv}${name}),正在战斗中...'; battle = '你遭遇了(lv${lv}${name}),正在战斗中...';
bouts = ['点击查看战斗过程', '回合', '触发了暴击', '你造成了${dmg}点伤害', '受到${dmg}点伤害', '战斗结束', '你获胜', '你战败'];
killMonster = '你击杀了(lv${lv}${name}),共受到了${dmg}点伤害'; killMonster = '你击杀了(lv${lv}${name}),共受到了${dmg}点伤害';
beKilled = '你被(lv${lv}${name})击败,共受到了${dmg}点伤害'; beKilled = '你被(lv${lv}${name})击败,共受到了${dmg}点伤害';
getCoins = '获得金币:'; getCoins = '获得金币:';

32
src/tool/caller.ts

@ -63,9 +63,9 @@ export const callPlayerAttribute = (playerAttribute: any, rA: any) => {
critdmg = attribute.critDmg / 100; critdmg = attribute.critDmg / 100;
attribute.dps = Math.ceil((1 - crit + crit * critdmg) * atk); attribute.dps = Math.ceil((1 - crit + crit * critdmg) * atk);
//计算减伤比例 //计算减伤比例
// attribute.def = 500; // attribute.def = 500;
attribute.reducPercent = (0.5 * attribute.def) / (35 + 0.55 * attribute.def) + (0.09 * attribute.def) / (attribute.def + 200); attribute.reducPercent = (0.5 * attribute.def) / (35 + 0.55 * attribute.def) + (0.09 * attribute.def) / (attribute.def + 200);
// attribute.reducPercent = (0.5 * attribute.def) / (200 + 0.502 * attribute.def); // attribute.reducPercent = (0.5 * attribute.def) / (200 + 0.502 * attribute.def);
return attribute; return attribute;
}; };
@ -127,3 +127,31 @@ export const getPointsOfReborn = (playerAttribute) => {
return Math.round(points * 1.2); return Math.round(points * 1.2);
}; };
export const callBattleResult = (player, monster) => {
const tmp = player.curHp,
crit = player.crit / 100,
critdmg = player.critDmg / 100,
atk = player.atk;
let monsterDmg = Math.ceil(monster.atk * (1 - player.reducPercent) - player.bloc);
monsterDmg < 1 && (monsterDmg = 1);
let curHp = player.curHp,
mHp = monster.hp;
const bouts: any = [];
while (true) {
const bout: any = {};
bouts.push(bout);
if (Math.random() < crit) {
bout.crit = true;
bout.dmg = Math.ceil(atk * critdmg);
} else {
bout.dmg = atk;
}
mHp -= bout.dmg;
if (mHp < 0) break;
bout.takeDmg = monsterDmg;
curHp -= monsterDmg;
if (curHp < 0) break;
}
return { win: curHp > 0, bouts: bouts, takeDmg: tmp - curHp };
};

23
src/views/dungeon/battle.vue

@ -16,7 +16,7 @@ import { useStore } from "vuex";
import { computed, nextTick, onMounted, ref } from "vue"; import { computed, nextTick, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n"; import { useI18n } from "vue3-i18n";
import { dungeon_icon, player_move_time, player_battle_time } from "@/config"; import { dungeon_icon, player_move_time, player_battle_time } from "@/config";
import { randonBootyEquip } from "@/tool"; import { randonBootyEquip, callBattleResult } from "@/tool";
const { t } = useI18n(); const { t } = useI18n();
const { state, commit, dispatch } = useStore(); const { state, commit, dispatch } = useStore();
@ -103,30 +103,31 @@ const playerMove = (monsterIdx?, playerIdx?) => {
const battleWithMonster = (monster) => { const battleWithMonster = (monster) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const player = state.playerAttribute.attribute; const player = state.playerAttribute.attribute;
let monsterDmg = Math.ceil(monster.atk * (1 - player.reducPercent) - player.bloc); const result = callBattleResult(player, monster);
monsterDmg < 1 && (monsterDmg = 1); // let monsterDmg = Math.ceil(monster.atk * (1 - player.reducPercent) - player.bloc);
// monsterDmg < 1 && (monsterDmg = 1);
const playerDeadTime = Math.ceil(player.curHp / monsterDmg); // const playerDeadTime = Math.ceil(player.curHp / monsterDmg);
const monsterDeadTime = Math.ceil(monster.hp / player.dps); // const monsterDeadTime = Math.ceil(monster.hp / player.dps);
const takeDmg = monsterDeadTime * monsterDmg; // const takeDmg = monsterDeadTime * monsterDmg;
const battleTime = Math.round(player_battle_time * 100 / (100 + state.rebornAttribute.battleSpeed)) const battleTime = Math.round(player_battle_time * 100 / (100 + state.rebornAttribute.battleSpeed))
const getMsg = (i18nName) => { const getMsg = (i18nName) => {
return t(i18nName).replace('${lv}', monster.lv).replace('${name}', t('difficulty.' + props.dungeon?.difficulty) + t(monster.type)).replace('${dmg}', takeDmg + ''); return t(i18nName).replace('${lv}', monster.lv).replace('${name}', t('difficulty.' + props.dungeon?.difficulty) + t(monster.type)).replace('${dmg}', result.takeDmg + '');
}; };
commit("set_sys_info", { msg: getMsg('battle'), type: 'battle' }); commit("set_sys_info", { msg: getMsg('battle'), type: 'battle' });
battle.value.timeOut = setTimeout(() => { battle.value.timeOut = setTimeout(() => {
nextTick(() => { nextTick(() => {
commit('add_player_curhp', -1 * takeDmg); commit('add_player_curhp', -1 * result.takeDmg);
}) })
if (monsterDeadTime < playerDeadTime) { if (result.win) {
commit("set_sys_info", { msg: getMsg('killMonster'), type: 'battle' }); commit("set_sys_info", { msg: getMsg('killMonster'), type: 'battle', bouts: result.bouts });
// //
const equips = randonBootyEquip(monster); const equips = randonBootyEquip(monster);
commit('add_bootys', { equips: equips, coins: monster.coins }); commit('add_bootys', { equips: equips, coins: monster.coins });
resolve(true); resolve(true);
} else { } else {
commit("set_sys_info", { msg: getMsg('beKilled'), type: 'warning' }); commit("set_sys_info", { msg: getMsg('beKilled'), type: 'warning', bouts: result.bouts });
battle.value.battleShow = false; battle.value.battleShow = false;
dispatch('play_music', 'backgound'); dispatch('play_music', 'backgound');
} }

51
src/views/message/bouts.vue

@ -0,0 +1,51 @@
<template>
<div class="bouts">
<div v-for="bout, idx in bouts" class="bout">
<span class="seq">{{ t('bouts.1') + (idx + 1) }}:</span>
<span class="crit" v-if="bout.crit">{{ t('bouts.2') }},</span>
<span class="dmg">{{ t('bouts.3').replace('${dmg}', bout.dmg) }},</span>
<span class="take-dmg" v-if="bout.takeDmg">{{ t('bouts.4').replace('${dmg}', bout.takeDmg) }}</span>
<span v-if="idx == bouts.length - 1">
{{ t('bouts.5') }}{{ bout.takeDmg ? t('bouts.7') : t('bouts.6') }}
</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
defineProps({
bouts: {
type: Array as () => any[],
default: []
}
})
onMounted(() => { });
</script>
<style lang="scss" scoped>
.bout {
text-align: left;
.seq {
font-size: 1.1rem;
}
.crit {
color: red;
}
.dmg {
color: #2fe20f;
}
.take-dmg {
color: #de8618;
}
}
</style>

20
src/views/message/sys-info.vue

@ -1,9 +1,17 @@
<template> <template>
<div class='sysInfo' ref="sysInfo"> <div class='sysInfo' ref="sysInfo">
<div :class="['info', v.type]" v-for="(v, k) in state.sysInfo" :key="k"> <div :class="['info', v.type]" v-for="(v, k) in state.sysInfo" :key="k">
<span>系统</span> <span>{{ t('sys') }}</span>
<i class="time" v-if="v.time">({{ v.time }})</i> <i class="time" v-if="v.time">({{ v.time }})</i>
<span class="msg">{{ v.msg }}</span> <span class="msg">{{ v.msg }}</span>
<div style="float: inline-end;" v-if="v.bouts">
<Tooltip :show-icon="false" width="25rem" x="-50%">
<a class="bouts-link">{{ t('bouts.0') }}</a>
<template #tip>
<Bouts :bouts="v.bouts"></Bouts>
</template>
</Tooltip>
</div>
<span v-if="v.equips" v-for="(o, p) in v.equips" :key="p"> <span v-if="v.equips" v-for="(o, p) in v.equips" :key="p">
<a :style="{ color: o.quality.color }" @mouseleave="commit('close_equip_tip')" <a :style="{ color: o.quality.color }" @mouseleave="commit('close_equip_tip')"
@mouseover="commit('show_equip_tip', { equip: o, compare: true, e: $event })"> @mouseover="commit('show_equip_tip', { equip: o, compare: true, e: $event })">
@ -13,6 +21,9 @@
</span> </span>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -20,6 +31,8 @@ import { useStore } from "vuex";
import { watch, nextTick, onMounted, ref } from "vue"; import { watch, nextTick, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n"; import { useI18n } from "vue3-i18n";
import { qualitys } from "@/config"; import { qualitys } from "@/config";
import { Tooltip } from "@/components";
import Bouts from "./bouts.vue";
const { t } = useI18n(); const { t } = useI18n();
const { state, commit, dispatch } = useStore(); const { state, commit, dispatch } = useStore();
@ -75,4 +88,9 @@ a {
.booty>.msg { .booty>.msg {
color: #2fe20f; color: #2fe20f;
} }
.bouts-link {
color: aqua;
padding-left: 0.3rem;
}
</style> </style>

11
src/views/version/update-log.vue

@ -31,7 +31,16 @@ const { state, commit, dispatch } = useStore();
const curVersion = '测试版'; const curVersion = '测试版';
const updateLogs: any = [{ const updateLogs: any = [{
date: '2025-04-22', version: '测试版', desc: '新增装备图鉴', date: '2025-04-23', version: '测试版',
adjust: [
'调整战斗逻辑,战斗伤害不再使用用期望值,每回合伤害独立计算,击败怪物的回合怪物将不造成伤害',
'新增战斗过程查看'
],
tuning: [
'修复菜单tip突变不显示BUG'
]
}, {
date: '2025-04-22', version: '测试版',
adjust: [ adjust: [
'新增版本信息和更新日志', '新增版本信息和更新日志',
], ],

Loading…
Cancel
Save