mirror of
https://github.com/unanmed/HumanBreak.git
synced 2026-11-02 17:44:31 +08:00
键盘操作
This commit is contained in:
1 parent
6034d959e0
commit
b38e334753
8 files changed
+1035
-43
No files matched your search
+98
-8
@@ -16,7 +16,13 @@
|
||||
v-model:drag="drag"
|
||||
>
|
||||
<div v-for="(e, i) of enemy" class="enemy">
|
||||
<EnemyOne :enemy="e" @select="select(e, i)"></EnemyOne>
|
||||
<EnemyOne
|
||||
:selected="i === selected"
|
||||
:enemy="e"
|
||||
:key="i"
|
||||
@select="select(e, i)"
|
||||
@hover="selected = i"
|
||||
></EnemyOne>
|
||||
<a-divider
|
||||
dashed
|
||||
style="width: 100%; border-color: #ddd4"
|
||||
@@ -30,12 +36,13 @@
|
||||
<script setup lang="tsx">
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { sleep } from 'mutate-animate';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import EnemyOne from '../components/enemyOne.vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { getDamageColor } from '../plugin/utils';
|
||||
import { getDamageColor, keycode } from '../plugin/utils';
|
||||
import BookDetail from './bookDetail.vue';
|
||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||
import { KeyCode } from '../plugin/keyCodes';
|
||||
|
||||
const floorId = core.floorIds[core.status.event?.ui] ?? core.status.floorId;
|
||||
const enemy = core.getCurrentEnemys(floorId);
|
||||
@@ -43,6 +50,7 @@ const enemy = core.getCurrentEnemys(floorId);
|
||||
const scroll = ref(0);
|
||||
const drag = ref(false);
|
||||
const detail = ref(false);
|
||||
const selected = ref(0);
|
||||
|
||||
// 解析
|
||||
enemy.forEach(v => {
|
||||
@@ -60,11 +68,6 @@ enemy.forEach(v => {
|
||||
v.damageColor = getDamageColor(v.damage);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const div = document.getElementById('book') as HTMLDivElement;
|
||||
div.style.opacity = '1';
|
||||
});
|
||||
|
||||
/**
|
||||
* 选择怪物,展示详细信息
|
||||
* @param enemy 选择的怪物
|
||||
@@ -80,6 +83,9 @@ function select(enemy: Enemy & DetailedEnemy, index: number) {
|
||||
hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏怪物手册
|
||||
*/
|
||||
async function hide() {
|
||||
const div = document.getElementById('book') as HTMLDivElement;
|
||||
div.style.opacity = '0';
|
||||
@@ -87,12 +93,18 @@ async function hide() {
|
||||
div.style.display = 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭详细信息
|
||||
*/
|
||||
async function closeDetail() {
|
||||
show();
|
||||
await sleep(600);
|
||||
detail.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示怪物手册
|
||||
*/
|
||||
async function show() {
|
||||
const div = document.getElementById('book') as HTMLDivElement;
|
||||
div.style.display = 'flex';
|
||||
@@ -100,10 +112,88 @@ async function show() {
|
||||
div.style.opacity = '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出怪物手册
|
||||
*/
|
||||
function exit() {
|
||||
core.closePanel();
|
||||
core.plugin.bookOpened.value = false;
|
||||
}
|
||||
|
||||
function checkScroll() {
|
||||
const h = window.innerHeight;
|
||||
const y = selected.value * h * 0.2 - scroll.value;
|
||||
if (y < 0) {
|
||||
scroll.value += y - 20;
|
||||
}
|
||||
if (y > h * 0.655) {
|
||||
scroll.value += y - h * 0.655 + 20;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 键盘松开时
|
||||
*/
|
||||
function keyup(e: KeyboardEvent) {
|
||||
const c = keycode(e.keyCode);
|
||||
if (c === KeyCode.KeyX || c === KeyCode.Escape) {
|
||||
exit();
|
||||
}
|
||||
if (c === KeyCode.Enter && !detail.value) {
|
||||
select(enemy[selected.value], selected.value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 键盘按下时
|
||||
*/
|
||||
function keydown(e: KeyboardEvent) {
|
||||
const c = keycode(e.keyCode);
|
||||
if (!detail.value) {
|
||||
if (c === KeyCode.DownArrow) {
|
||||
if (selected.value < enemy.length - 1) {
|
||||
selected.value++;
|
||||
}
|
||||
checkScroll();
|
||||
}
|
||||
if (c === KeyCode.UpArrow) {
|
||||
if (selected.value > 0) {
|
||||
selected.value--;
|
||||
}
|
||||
checkScroll();
|
||||
}
|
||||
// 一次移动5个怪物
|
||||
if (c === KeyCode.LeftArrow || c === KeyCode.PageUp) {
|
||||
if (selected.value <= 4) {
|
||||
selected.value = 0;
|
||||
} else {
|
||||
selected.value -= 5;
|
||||
}
|
||||
checkScroll();
|
||||
}
|
||||
if (c === KeyCode.RightArrow || c === KeyCode.PageDown) {
|
||||
if (selected.value >= enemy.length - 5) {
|
||||
selected.value = enemy.length - 1;
|
||||
} else {
|
||||
selected.value += 5;
|
||||
}
|
||||
checkScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const div = document.getElementById('book') as HTMLDivElement;
|
||||
div.style.opacity = '1';
|
||||
await sleep(600);
|
||||
document.addEventListener('keyup', keyup);
|
||||
document.addEventListener('keydown', keydown);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keyup', keyup);
|
||||
document.removeEventListener('keydown', keydown);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
+31
-9
@@ -45,17 +45,21 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import EnemyOne from '../components/enemyOne.vue';
|
||||
import { useDrag } from '../plugin/use';
|
||||
import EnemySpecial from '../panel/enemySpecial.vue';
|
||||
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||
import EnemyCritical from '../panel/enemyCritical.vue';
|
||||
import { KeyCode } from '../plugin/keyCodes';
|
||||
import { keycode } from '../plugin/utils';
|
||||
|
||||
const enemy = core.plugin.bookDetailEnemy;
|
||||
const top = ref(core.plugin.bookDetailPos);
|
||||
const panel = ref('special');
|
||||
|
||||
let detail: HTMLDivElement;
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'close'): void;
|
||||
}>();
|
||||
@@ -65,18 +69,30 @@ function changePanel(e: MouseEvent, to: string) {
|
||||
panel.value = to;
|
||||
}
|
||||
|
||||
function close() {
|
||||
top.value = core.plugin.bookDetailPos;
|
||||
detail.style.opacity = '0';
|
||||
emits('close');
|
||||
}
|
||||
|
||||
function key(e: KeyboardEvent) {
|
||||
if (keycode(e.keyCode) === KeyCode.Enter) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
top.value = 0;
|
||||
const div = document.getElementById('detail') as HTMLDivElement;
|
||||
div.style.opacity = '1';
|
||||
detail = document.getElementById('detail') as HTMLDivElement;
|
||||
detail.style.opacity = '1';
|
||||
|
||||
const style = getComputedStyle(div);
|
||||
const style = getComputedStyle(detail);
|
||||
|
||||
let moved = false;
|
||||
let pos = [0, 0];
|
||||
|
||||
useDrag(
|
||||
div,
|
||||
detail,
|
||||
(x, y) => {
|
||||
if ((x - pos[0]) ** 2 + (y - pos[1]) ** 2 >= 100) moved = true;
|
||||
},
|
||||
@@ -85,14 +101,18 @@ onMounted(() => {
|
||||
if (y > (parseFloat(style.height) * 4) / 5) moved = true;
|
||||
},
|
||||
() => {
|
||||
if (moved === false) {
|
||||
top.value = core.plugin.bookDetailPos;
|
||||
div.style.opacity = '0';
|
||||
emits('close');
|
||||
if (moved === false && panel.value !== 'critical') {
|
||||
close();
|
||||
}
|
||||
moved = false;
|
||||
}
|
||||
);
|
||||
|
||||
document.addEventListener('keyup', key);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keyup', key);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -118,6 +138,7 @@ onMounted(() => {
|
||||
width: 72%;
|
||||
height: 90%;
|
||||
transition: all 0.6s ease;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#detail-more {
|
||||
@@ -171,6 +192,7 @@ onMounted(() => {
|
||||
|
||||
#detail-more {
|
||||
font-size: 4vw;
|
||||
bottom: 5%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user