mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 12:49:25 +08:00
refactor: 移动鼠标定点查看
This commit is contained in:
parent
5b36d8977f
commit
5e4a8c1eb3
@ -3013,7 +3013,7 @@ control.prototype.removeSwitch = function (x, y, floorId, name) {
|
|||||||
control.prototype.lockControl = function () {
|
control.prototype.lockControl = function () {
|
||||||
core.status.lockControl = true;
|
core.status.lockControl = true;
|
||||||
if (!main.replayChecking) {
|
if (!main.replayChecking) {
|
||||||
mota.plugin.fixed.showFixed.value = false;
|
// mota.plugin.fixed.showFixed.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -405,16 +405,16 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
|
|||||||
break;
|
break;
|
||||||
case 67: // C:怪物临界
|
case 67: // C:怪物临界
|
||||||
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
||||||
mota.plugin.fixed.showFixed.value = false;
|
// mota.plugin.fixed.showFixed.value = false;
|
||||||
mota.ui.main.open('fixedDetail', void 0, {
|
mota.ui.main.open('fixedDetail', {
|
||||||
panel: 'critical'
|
panel: 'critical'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 69: // E:怪物属性
|
case 69: // E:怪物属性
|
||||||
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
||||||
mota.plugin.fixed.showFixed.value = false;
|
// mota.plugin.fixed.showFixed.value = false;
|
||||||
mota.ui.main.open('fixedDetail', void 0, {
|
mota.ui.main.open('fixedDetail', {
|
||||||
panel: 'special'
|
panel: 'special'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import { GameEvent, hook } from './main/game';
|
|||||||
import { fixedUi, mainUi } from './main/init/ui';
|
import { fixedUi, mainUi } from './main/init/ui';
|
||||||
import { GameStorage } from './main/storage';
|
import { GameStorage } from './main/storage';
|
||||||
import { resolvePlugin } from './plugin';
|
import { resolvePlugin } from './plugin';
|
||||||
|
import './main/init/';
|
||||||
|
|
||||||
interface AncTePlugin {
|
interface AncTePlugin {
|
||||||
pop: ReturnType<typeof import('../plugin/pop').default>;
|
pop: ReturnType<typeof import('../plugin/pop').default>;
|
||||||
|
@ -302,8 +302,8 @@ hotkey
|
|||||||
const [x, y] = flags.mouseLoc ?? [];
|
const [x, y] = flags.mouseLoc ?? [];
|
||||||
const [mx, my] = getLocFromMouseLoc(x, y);
|
const [mx, my] = getLocFromMouseLoc(x, y);
|
||||||
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
||||||
mota.plugin.fixed.showFixed.value = false;
|
// mota.plugin.fixed.showFixed.value = false;
|
||||||
mota.ui.main.open('fixedDetail', void 0, {
|
mota.ui.main.open('fixedDetail', {
|
||||||
panel: 'special'
|
panel: 'special'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -315,8 +315,8 @@ hotkey
|
|||||||
const [x, y] = flags.mouseLoc ?? [];
|
const [x, y] = flags.mouseLoc ?? [];
|
||||||
const [mx, my] = getLocFromMouseLoc(x, y);
|
const [mx, my] = getLocFromMouseLoc(x, y);
|
||||||
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
|
||||||
mota.plugin.fixed.showFixed.value = false;
|
// mota.plugin.fixed.showFixed.value = false;
|
||||||
mota.ui.main.open('fixedDetail', void 0, {
|
mota.ui.main.open('fixedDetail', {
|
||||||
panel: 'critical'
|
panel: 'critical'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ export class GameUi extends EventEmitter<GameUiEvent> {
|
|||||||
* @param vOn 监听的事件
|
* @param vOn 监听的事件
|
||||||
* @param vBind 绑定的数据
|
* @param vBind 绑定的数据
|
||||||
*/
|
*/
|
||||||
with(vOn?: UiVOn, vBind?: UiVBind): ShowableGameUi {
|
with(vBind?: UiVBind, vOn?: UiVOn): ShowableGameUi {
|
||||||
return { ui: this, vOn, vBind };
|
return { ui: this, vOn, vBind };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,15 +257,16 @@ export class UiController extends Focus<IndexedGameUi> {
|
|||||||
* @param vBind 绑定的数据
|
* @param vBind 绑定的数据
|
||||||
* @returns ui的唯一标识符
|
* @returns ui的唯一标识符
|
||||||
*/
|
*/
|
||||||
open(id: string, vOn?: UiVOn, vBind?: UiVBind) {
|
open(id: string, vBind?: UiVBind, vOn?: UiVOn) {
|
||||||
const ui = this.get(id);
|
const ui = this.get(id);
|
||||||
if (!ui) return -1;
|
if (!ui) return -1;
|
||||||
const num = this.num++;
|
const num = this.num++;
|
||||||
const sui = ui.with(vOn, {
|
const bind = {
|
||||||
num,
|
num,
|
||||||
ui,
|
ui,
|
||||||
...(vBind ?? {})
|
...(vBind ?? {})
|
||||||
});
|
};
|
||||||
|
const sui = ui.with(bind, vOn);
|
||||||
this.add({
|
this.add({
|
||||||
num,
|
num,
|
||||||
...sui
|
...sui
|
||||||
|
@ -11,9 +11,12 @@ export interface GameEvent extends EmitableEvent {
|
|||||||
export const hook = new EventEmitter<GameEvent>();
|
export const hook = new EventEmitter<GameEvent>();
|
||||||
|
|
||||||
interface ListenerEvent extends EmitableEvent {
|
interface ListenerEvent extends EmitableEvent {
|
||||||
hoverBlock: (block: Block) => void;
|
// block
|
||||||
leaveBlock: (block: Block) => void;
|
hoverBlock: (block: Block, ev: MouseEvent) => void;
|
||||||
clickBlock: (block: Block) => void;
|
leaveBlock: (block: Block, ev: MouseEvent, leaveGame: boolean) => void;
|
||||||
|
clickBlock: (block: Block, ev: MouseEvent) => void;
|
||||||
|
// mouse
|
||||||
|
mouseMove: (ev: MouseEvent) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GameListener extends EventEmitter<ListenerEvent> {
|
class GameListener extends EventEmitter<ListenerEvent> {
|
||||||
@ -24,74 +27,83 @@ class GameListener extends EventEmitter<ListenerEvent> {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
loading.once('coreInit', () => {
|
if (!!window.core) {
|
||||||
this.init();
|
this.init();
|
||||||
});
|
} else {
|
||||||
|
loading.once('coreInit', () => {
|
||||||
|
this.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
// block
|
// ----- block
|
||||||
let lastHoverX = -1;
|
let lastHoverX = -1;
|
||||||
let lastHoverY = -1;
|
let lastHoverY = -1;
|
||||||
|
|
||||||
const getBlockLoc = (px: number, py: number) => {
|
const data = core.canvas.data.canvas;
|
||||||
|
|
||||||
|
const getBlockLoc = (px: number, py: number, size: number) => {
|
||||||
return [
|
return [
|
||||||
Math.floor((px - core.bigmap.offsetX) / 32),
|
Math.floor(((px * 32) / size - core.bigmap.offsetX) / 32),
|
||||||
Math.floor((py - core.bigmap.offsetY) / 32)
|
Math.floor(((py * 32) / size - core.bigmap.offsetY) / 32)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
core.registerAction(
|
// hover & leave
|
||||||
'onmove',
|
data.addEventListener('mousemove', e => {
|
||||||
`@GameListener_${this.num}_block`,
|
if (core.status.lockControl || !core.isPlaying()) return;
|
||||||
(x, y, px, py) => {
|
this.emit('mouseMove', e);
|
||||||
if (core.status.lockControl || !core.isPlaying()) return false;
|
const {
|
||||||
const [bx, by] = getBlockLoc(px, py);
|
x: px,
|
||||||
const blocks = core.getMapBlocksObj();
|
y: py,
|
||||||
if (lastHoverX !== bx || lastHoverY !== by) {
|
size
|
||||||
const lastBlock = blocks[`${lastHoverX},${lastHoverY}`];
|
} = core.actions._getClickLoc(e.clientX, e.clientY);
|
||||||
const block = blocks[`${bx},${by}`];
|
const [bx, by] = getBlockLoc(px, py, size);
|
||||||
if (!!lastBlock) {
|
const blocks = core.getMapBlocksObj();
|
||||||
this.emit('leaveBlock', lastBlock);
|
if (lastHoverX !== bx || lastHoverY !== by) {
|
||||||
}
|
const lastBlock = blocks[`${lastHoverX},${lastHoverY}`];
|
||||||
if (!!block) {
|
const block = blocks[`${bx},${by}`];
|
||||||
this.emit('hoverBlock', block);
|
if (!!lastBlock) {
|
||||||
lastHoverX = bx;
|
this.emit('leaveBlock', lastBlock, e, false);
|
||||||
lastHoverY = by;
|
|
||||||
} else {
|
|
||||||
lastHoverX = -1;
|
|
||||||
lastHoverY = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
if (!!block) {
|
||||||
},
|
this.emit('hoverBlock', block, e);
|
||||||
50
|
lastHoverX = bx;
|
||||||
);
|
lastHoverY = by;
|
||||||
core.canvas.data.canvas.addEventListener('mouseleave', () => {
|
} else {
|
||||||
|
lastHoverX = -1;
|
||||||
|
lastHoverY = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
data.addEventListener('mouseleave', e => {
|
||||||
if (core.status.lockControl || !core.isPlaying()) return;
|
if (core.status.lockControl || !core.isPlaying()) return;
|
||||||
const blocks = core.getMapBlocksObj();
|
const blocks = core.getMapBlocksObj();
|
||||||
const lastBlock = blocks[`${lastHoverX},${lastHoverY}`];
|
const lastBlock = blocks[`${lastHoverX},${lastHoverY}`];
|
||||||
if (!!lastBlock) {
|
if (!!lastBlock) {
|
||||||
this.emit('leaveBlock', lastBlock);
|
this.emit('leaveBlock', lastBlock, e, true);
|
||||||
}
|
}
|
||||||
lastHoverX = -1;
|
lastHoverX = -1;
|
||||||
lastHoverY = -1;
|
lastHoverY = -1;
|
||||||
});
|
});
|
||||||
core.registerAction(
|
// click
|
||||||
'onup',
|
data.addEventListener('click', e => {
|
||||||
`@GameListener_${this.num}_block`,
|
if (core.status.lockControl || !core.isPlaying()) return;
|
||||||
(x, y, px, py) => {
|
const {
|
||||||
if (core.status.lockControl || !core.isPlaying()) return false;
|
x: px,
|
||||||
const [bx, by] = getBlockLoc(px, py);
|
y: py,
|
||||||
const blocks = core.getMapBlocksObj();
|
size
|
||||||
const block = blocks[`${bx},${by}`];
|
} = core.actions._getClickLoc(e.clientX, e.clientY);
|
||||||
if (!!block) {
|
const [bx, by] = getBlockLoc(px, py, size);
|
||||||
this.emit('clickBlock', block);
|
const blocks = core.getMapBlocksObj();
|
||||||
}
|
const block = blocks[`${bx},${by}`];
|
||||||
return false;
|
if (!!block) {
|
||||||
},
|
this.emit('clickBlock', block, e);
|
||||||
50
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
|
// ----- mouse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
src/core/main/init/fixed.ts
Normal file
55
src/core/main/init/fixed.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { debounce } from 'lodash-es';
|
||||||
|
import { gameListener } from '../game';
|
||||||
|
import { fixedUi } from './ui';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { sleep } from 'mutate-animate';
|
||||||
|
|
||||||
|
const close = ref(false);
|
||||||
|
|
||||||
|
let cx = 0;
|
||||||
|
let cy = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示定点查看
|
||||||
|
*/
|
||||||
|
const showFixed = debounce((block: Block) => {
|
||||||
|
const e = core.material.enemys[block.event.id as EnemyIds];
|
||||||
|
if (!e) return;
|
||||||
|
const enemy = core.status.thisMap.enemy.get(block.x, block.y);
|
||||||
|
fixedUi.open(
|
||||||
|
'fixed',
|
||||||
|
{ enemy, close, loc: [cx, cy] },
|
||||||
|
{ close: closeFixed }
|
||||||
|
);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭定点查看
|
||||||
|
*/
|
||||||
|
const closeFixed = () => {
|
||||||
|
close.value = true;
|
||||||
|
sleep(200).then(() => {
|
||||||
|
fixedUi.closeByName('fixed');
|
||||||
|
close.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let hovered: Block | null;
|
||||||
|
|
||||||
|
gameListener.on('hoverBlock', block => {
|
||||||
|
closeFixed();
|
||||||
|
hovered = block;
|
||||||
|
});
|
||||||
|
gameListener.on('leaveBlock', (_, __, leaveGame) => {
|
||||||
|
showFixed.cancel();
|
||||||
|
if (!leaveGame) closeFixed();
|
||||||
|
hovered = null;
|
||||||
|
});
|
||||||
|
gameListener.on('mouseMove', e => {
|
||||||
|
cx = e.clientX;
|
||||||
|
cy = e.clientY;
|
||||||
|
showFixed.cancel();
|
||||||
|
if (hovered) {
|
||||||
|
showFixed(hovered);
|
||||||
|
}
|
||||||
|
});
|
1
src/core/main/init/index.ts
Normal file
1
src/core/main/init/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
import './fixed';
|
@ -8,7 +8,6 @@ import mark from '@/plugin/mark';
|
|||||||
import chapter from '@/plugin/ui/chapter';
|
import chapter from '@/plugin/ui/chapter';
|
||||||
import fly from '@/plugin/ui/fly';
|
import fly from '@/plugin/ui/fly';
|
||||||
import chase from '@/plugin/chase/chase';
|
import chase from '@/plugin/chase/chase';
|
||||||
import fixed from '@/plugin/ui/fixed';
|
|
||||||
import webglUtils from '@/plugin/webgl/utils';
|
import webglUtils from '@/plugin/webgl/utils';
|
||||||
import shadow from '@/plugin/shadow/shadow';
|
import shadow from '@/plugin/shadow/shadow';
|
||||||
import gameShadow from '@/plugin/shadow/gameShadow';
|
import gameShadow from '@/plugin/shadow/gameShadow';
|
||||||
@ -33,7 +32,6 @@ export function resolvePlugin() {
|
|||||||
['chapter', chapter()],
|
['chapter', chapter()],
|
||||||
['fly', fly()],
|
['fly', fly()],
|
||||||
['chase', chase()],
|
['chase', chase()],
|
||||||
['fixed', fixed()],
|
|
||||||
['webglUtils', webglUtils()],
|
['webglUtils', webglUtils()],
|
||||||
['shadow', shadow()],
|
['shadow', shadow()],
|
||||||
['gameShadow', gameShadow()],
|
['gameShadow', gameShadow()],
|
||||||
|
@ -74,6 +74,10 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
|||||||
this.extract();
|
this.extract();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get(x: number, y: number) {
|
||||||
|
return this.list.find(v => v.x === x && v.y === y);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析本地图的怪物信息
|
* 解析本地图的怪物信息
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ export {};
|
|||||||
|
|
||||||
function openItemShop(itemShopId) {
|
function openItemShop(itemShopId) {
|
||||||
if (!core.isReplaying()) {
|
if (!core.isReplaying()) {
|
||||||
mota.ui.main.open('shop', void 0, {
|
mota.ui.main.open('shop', {
|
||||||
shopId: itemShopId
|
shopId: itemShopId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,46 +5,46 @@ import { ToShowEnemy, detailInfo } from './book';
|
|||||||
import { DamageEnemy } from '../game/enemy/damage';
|
import { DamageEnemy } from '../game/enemy/damage';
|
||||||
import { isMobile } from '../use';
|
import { isMobile } from '../use';
|
||||||
|
|
||||||
export const showFixed = ref(false);
|
// export const showFixed = ref(false);
|
||||||
|
|
||||||
let lastId: EnemyIds;
|
// let lastId: EnemyIds;
|
||||||
|
|
||||||
const show = debounce((ev: MouseEvent) => {
|
// const show = debounce((ev: MouseEvent) => {
|
||||||
if (!window.flags) return;
|
// if (!window.flags) return;
|
||||||
if (!flags.mouseLoc) return;
|
// if (!flags.mouseLoc) return;
|
||||||
flags.clientLoc = [ev.clientX, ev.clientY];
|
// flags.clientLoc = [ev.clientX, ev.clientY];
|
||||||
const [mx, my] = getLocFromMouseLoc(...flags.mouseLoc);
|
// const [mx, my] = getLocFromMouseLoc(...flags.mouseLoc);
|
||||||
|
|
||||||
const e = core.status.thisMap.enemy.list.find(v => {
|
// const e = core.status.thisMap.enemy.list.find(v => {
|
||||||
return v.x === mx && v.y === my;
|
// return v.x === mx && v.y === my;
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (!e) return;
|
// if (!e) return;
|
||||||
|
|
||||||
lastId = e.id;
|
// lastId = e.id;
|
||||||
const detail = getDetailedEnemy(e);
|
// const detail = getDetailedEnemy(e);
|
||||||
detailInfo.enemy = detail;
|
// detailInfo.enemy = detail;
|
||||||
showFixed.value = true;
|
// showFixed.value = true;
|
||||||
}, 200);
|
// }, 200);
|
||||||
|
|
||||||
export default function init() {
|
// export default function init() {
|
||||||
const data = core.canvas.data.canvas;
|
// const data = core.canvas.data.canvas;
|
||||||
data.addEventListener('mousemove', ev => {
|
// data.addEventListener('mousemove', ev => {
|
||||||
if (!core.isPlaying() || core.status.lockControl) return;
|
// if (!core.isPlaying() || core.status.lockControl) return;
|
||||||
const [mx, my] = getLocFromMouseLoc(...flags.mouseLoc);
|
// const [mx, my] = getLocFromMouseLoc(...flags.mouseLoc);
|
||||||
const e = core.getBlockId(mx, my);
|
// const e = core.getBlockId(mx, my);
|
||||||
if (e !== lastId) showFixed.value = false;
|
// if (e !== lastId) showFixed.value = false;
|
||||||
if (!e) return;
|
// if (!e) return;
|
||||||
show(ev);
|
// show(ev);
|
||||||
});
|
// });
|
||||||
data.addEventListener('mousedown', ev => {
|
// data.addEventListener('mousedown', ev => {
|
||||||
showFixed.value = false;
|
// showFixed.value = false;
|
||||||
});
|
// });
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
showFixed
|
// showFixed
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function getLocFromMouseLoc(x: number, y: number): LocArr {
|
export function getLocFromMouseLoc(x: number, y: number): LocArr {
|
||||||
const mx = Math.round(x + core.bigmap.offsetX / 32);
|
const mx = Math.round(x + core.bigmap.offsetX / 32);
|
||||||
|
9
src/types/action.d.ts
vendored
9
src/types/action.d.ts
vendored
@ -136,6 +136,15 @@ interface Actions extends VoidedActionFuncs {
|
|||||||
_getNextFlyFloor(delta: number, index: number): number;
|
_getNextFlyFloor(delta: number, index: number): number;
|
||||||
|
|
||||||
_clickGameInfo_openComments();
|
_clickGameInfo_openComments();
|
||||||
|
|
||||||
|
_getClickLoc(
|
||||||
|
x: number,
|
||||||
|
y: number
|
||||||
|
): {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
size: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const actions: new () => Actions;
|
declare const actions: new () => Actions;
|
||||||
|
3
src/types/plugin.d.ts
vendored
3
src/types/plugin.d.ts
vendored
@ -177,9 +177,6 @@ interface PluginUis {
|
|||||||
/** 是否展示标记的怪物 */
|
/** 是否展示标记的怪物 */
|
||||||
readonly showMarkedEnemy: Ref<boolean>;
|
readonly showMarkedEnemy: Ref<boolean>;
|
||||||
|
|
||||||
/** 是否展示移动鼠标显示怪物信息的盒子 */
|
|
||||||
readonly showFixed: Ref<boolean>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示章节
|
* 显示章节
|
||||||
* @param chapter 显示的文字
|
* @param chapter 显示的文字
|
||||||
|
145
src/ui/fixed.vue
145
src/ui/fixed.vue
@ -1,63 +1,94 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="fixed">
|
<div id="fixed">
|
||||||
<Transition>
|
<Box
|
||||||
<Box
|
v-model:height="height"
|
||||||
v-if="showFixed"
|
v-model:left="left"
|
||||||
v-model:height="height"
|
v-model:top="top"
|
||||||
v-model:left="left"
|
v-model:width="width"
|
||||||
v-model:top="top"
|
>
|
||||||
v-model:width="width"
|
<div id="enemy-fixed">
|
||||||
>
|
<span id="enemy-name">{{ enemy.enemy.name }}</span>
|
||||||
<div id="enemy-fixed">
|
<div id="enemy-special">
|
||||||
<span id="enemy-name">{{ enemy.enemy.enemy.name }}</span>
|
<span
|
||||||
<div id="enemy-special">
|
v-for="(text, i) of special"
|
||||||
<span
|
:style="{ color: text[1] }"
|
||||||
v-for="(text, i) of enemy.showSpecial"
|
>{{ text[0] }}</span
|
||||||
:style="{ color: text[2] }"
|
>
|
||||||
>{{ text[0] }}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="enemy-attr" v-for="(a, i) of toShowAttrs">
|
|
||||||
<span class="attr-name" :style="{ color: a[2] }">{{
|
|
||||||
a[1]
|
|
||||||
}}</span>
|
|
||||||
<span class="attr-value" :style="{ color: a[2] }">{{
|
|
||||||
format(a[0])
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
<div class="enemy-attr" v-for="(a, i) of detail">
|
||||||
</Transition>
|
<span class="attr-name" :style="{ color: a[2] }">{{
|
||||||
|
a[1]
|
||||||
|
}}</span>
|
||||||
|
<span class="attr-value" :style="{ color: a[2] }">{{
|
||||||
|
format(a[0])
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ComputedRef, computed, onMounted, onUpdated, ref, watch } from 'vue';
|
import { onMounted, onUpdated, ref, watch } from 'vue';
|
||||||
import Box from '../components/box.vue';
|
import Box from '../components/box.vue';
|
||||||
import { showFixed } from '../plugin/ui/fixed';
|
import { GameUi } from '@/core/main/custom/ui';
|
||||||
import { ToShowEnemy, detailInfo } from '../plugin/ui/book';
|
import type { DamageEnemy } from '@/plugin/game/enemy/damage';
|
||||||
|
import { nextFrame } from '@/plugin/utils';
|
||||||
|
|
||||||
watch(showFixed, n => {
|
const props = defineProps<{
|
||||||
if (n) calHeight();
|
num: number;
|
||||||
|
ui: GameUi;
|
||||||
|
enemy: DamageEnemy;
|
||||||
|
close: Ref<boolean>;
|
||||||
|
loc: [x: number, y: number];
|
||||||
|
}>();
|
||||||
|
const emits = defineEmits<{
|
||||||
|
(e: 'close'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
watch(props.close, n => {
|
||||||
|
if (n) {
|
||||||
|
fixed.style.opacity = '0';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let main: HTMLDivElement;
|
let main: HTMLDivElement;
|
||||||
|
let fixed: HTMLDivElement;
|
||||||
|
|
||||||
const format = core.formatBigNumber;
|
const format = core.formatBigNumber;
|
||||||
const enemy = ref(detailInfo.enemy!);
|
const enemy = props.enemy;
|
||||||
|
const detail = ((): [number, string, string][] => {
|
||||||
|
const info = enemy.info;
|
||||||
|
const data = enemy.calCritical()[0];
|
||||||
|
const ratio = core.status.thisMap?.ratio ?? 1;
|
||||||
|
return [
|
||||||
|
[info.hp, '生命', 'lightgreen'],
|
||||||
|
[info.atk, '攻击', 'lightcoral'],
|
||||||
|
[info.def, '防御', 'lightblue'],
|
||||||
|
[enemy.enemy.money, '金币', 'lightyellow'],
|
||||||
|
[enemy.enemy.exp, '经验', 'lawgreen'],
|
||||||
|
[data?.atkDelta ?? 0, '临界', 'lightsalmon'],
|
||||||
|
[data?.delta ?? 0, '临界减伤', 'lightpink'],
|
||||||
|
[enemy.calDefDamage(ratio).delta, `${ratio}防`, 'cyan']
|
||||||
|
];
|
||||||
|
})();
|
||||||
|
const special = (() => {
|
||||||
|
const s = enemy.info.special;
|
||||||
|
|
||||||
const toShowAttrs: ComputedRef<[number | string, string, string][]> = computed(
|
const fromFunc = (
|
||||||
() => [
|
func: string | ((enemy: Enemy) => string),
|
||||||
[enemy.value.enemy.info.hp, '生命', 'lightgreen'],
|
enemy: Enemy
|
||||||
[enemy.value.enemy.info.atk, '攻击', 'lightcoral'],
|
) => {
|
||||||
[enemy.value.enemy.info.def, '防御', 'lightblue'],
|
return typeof func === 'string' ? func : func(enemy);
|
||||||
[enemy.value.enemy.enemy.money, '金币', 'lightyellow'],
|
};
|
||||||
[enemy.value.enemy.enemy.exp, '经验', 'lawgreen'],
|
|
||||||
[enemy.value.critical, '临界', 'lightsalmon'],
|
const show = s.slice(0, 2).map(v => {
|
||||||
[enemy.value.criticalDam, '临界减伤', 'lightpink'],
|
const s = core.plugin.special[v];
|
||||||
[enemy.value.defDam, `${core.status.thisMap?.ratio ?? 1}防`, 'cyan']
|
return [fromFunc(s.name, enemy.enemy), s.color];
|
||||||
]
|
});
|
||||||
);
|
if (s.length > 2) show.push(['...', 'white']);
|
||||||
|
return show;
|
||||||
|
})();
|
||||||
|
|
||||||
const left = ref(0);
|
const left = ref(0);
|
||||||
const top = ref(0);
|
const top = ref(0);
|
||||||
@ -67,19 +98,15 @@ let vh = window.innerHeight;
|
|||||||
let vw = window.innerWidth;
|
let vw = window.innerWidth;
|
||||||
|
|
||||||
async function calHeight() {
|
async function calHeight() {
|
||||||
enemy.value = detailInfo.enemy!;
|
|
||||||
vh = window.innerHeight;
|
vh = window.innerHeight;
|
||||||
vw = window.innerWidth;
|
vw = window.innerWidth;
|
||||||
width.value = vh * 0.28;
|
width.value = vh * 0.28;
|
||||||
await new Promise(res => requestAnimationFrame(res));
|
await new Promise(res => requestAnimationFrame(res));
|
||||||
if (mota.ui.main.hasName('fixedDetail')) {
|
|
||||||
showFixed.value = false;
|
|
||||||
}
|
|
||||||
updateMain();
|
updateMain();
|
||||||
if (!main) return;
|
if (!main) return;
|
||||||
const style = getComputedStyle(main);
|
const style = getComputedStyle(main);
|
||||||
const h = parseFloat(style.height);
|
const h = parseFloat(style.height);
|
||||||
const [cx, cy] = flags.clientLoc;
|
const [cx, cy] = props.loc;
|
||||||
if (cy + h + 10 > vh - 10) top.value = vh - h - 10;
|
if (cy + h + 10 > vh - 10) top.value = vh - h - 10;
|
||||||
else top.value = cy + 10;
|
else top.value = cy + 10;
|
||||||
if (cx + width.value + 10 > vw - 10) left.value = vw - width.value - 10;
|
if (cx + width.value + 10 > vw - 10) left.value = vw - width.value - 10;
|
||||||
@ -89,11 +116,13 @@ async function calHeight() {
|
|||||||
|
|
||||||
function updateMain() {
|
function updateMain() {
|
||||||
main = document.getElementById('enemy-fixed') as HTMLDivElement;
|
main = document.getElementById('enemy-fixed') as HTMLDivElement;
|
||||||
|
fixed = document.getElementById('fixed') as HTMLDivElement;
|
||||||
if (main) {
|
if (main) {
|
||||||
main.addEventListener('mouseleave', () => {
|
main.addEventListener('mouseleave', () => emits('close'));
|
||||||
showFixed.value = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
nextFrame(() => {
|
||||||
|
fixed.style.opacity = '1';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdated(calHeight);
|
onUpdated(calHeight);
|
||||||
@ -108,16 +137,8 @@ onMounted(() => {
|
|||||||
#fixed {
|
#fixed {
|
||||||
font-family: 'normal';
|
font-family: 'normal';
|
||||||
font-size: 2.5vh;
|
font-size: 2.5vh;
|
||||||
}
|
|
||||||
|
|
||||||
.v-enter-active,
|
|
||||||
.v-leave-active {
|
|
||||||
transition: opacity 0.2s linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v-enter-from,
|
|
||||||
.v-leave-to {
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
#enemy-fixed {
|
#enemy-fixed {
|
||||||
|
Loading…
Reference in New Issue
Block a user