重构设置模块

This commit is contained in:
unanmed 2023-08-05 12:12:02 +08:00
parent b7f0d6f4d8
commit 4d4aeed3cd
14 changed files with 603 additions and 227 deletions

2
components.d.ts vendored
View File

@ -7,7 +7,9 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AButton: typeof import('ant-design-vue/es')['Button']
ADivider: typeof import('ant-design-vue/es')['Divider']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AProgress: typeof import('ant-design-vue/es')['Progress']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']

View File

@ -415,10 +415,7 @@ main.prototype.loadAsync = async function (mode, callback) {
// 自动放缩最大化
let auto = core.getLocalStorage('autoScale');
if (auto == null) {
core.setLocalStorage('autoScale', true);
auto = true;
}
if (auto && !core.domStyle.isVertical) {
try {
core.plugin.utils.maxGameScale();

View File

@ -51,11 +51,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
else core.showStatusBar();
if (main.mode === 'play' && !main.replayChecking) {
ancTe.plugin.fly.splitArea();
ancTe.plugin.setting.resetFlagSettings();
ancTe.game.hook.emit('reset');
} else {
flags.autoSkill ??= true;
flags.itemDetail ??= true;
flags.autoLocate ??= true;
}
},
win: function (reason, norank, noexit) {

View File

@ -18,7 +18,6 @@ import { uiStack } from './plugin/uiController';
display: flex;
justify-content: center;
overflow: hidden;
font-size: 16px;
}
@media screen and (max-width: 600px) {

View File

@ -1,7 +1,9 @@
import { BgmController } from './audio/bgm';
import { SoundController } from './audio/sound';
import { EventEmitter } from './common/eventEmitter';
import { loading, readyAllResource } from './loader/load';
import { ResourceStore, ResourceType } from './loader/resource';
import { GameEvent } from './main/game';
import { resolvePlugin } from './plugin';
interface AncTePlugin {
@ -38,6 +40,9 @@ export interface AncTe {
zipResource: ResourceStore<'zip'>;
bgm: BgmController;
plugin: AncTePlugin;
game: {
hook: EventEmitter<GameEvent>;
};
}
function ready() {

9
src/core/main/game.ts Normal file
View File

@ -0,0 +1,9 @@
import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
export interface GameEvent extends EmitableEvent {
reset: () => void;
}
export const hook = new EventEmitter<GameEvent>();
ancTe.game.hook = hook;

View File

@ -1,12 +1,17 @@
import { reactive } from 'vue';
import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
import { transition } from '../../plugin/uiController';
import { loading } from '../loader/load';
import { hook } from './game';
type MotaSettingType = boolean | number | MotaSetting;
interface MotaSettingItem<T extends MotaSettingType = MotaSettingType> {
export interface MotaSettingItem<T extends MotaSettingType = MotaSettingType> {
name: string;
key: string;
value: T;
defaults?: boolean | number;
step?: number;
step?: [number, number, number];
display?: (value: T) => string;
special?: string;
}
@ -19,8 +24,28 @@ interface SettingEvent extends EmitableEvent {
) => void;
}
class MotaSetting extends EventEmitter<SettingEvent> {
private list: Record<string, MotaSettingItem> = {};
export type SettingText = {
[key: string]: string[] | SettingText;
};
export interface SettingDisplayInfo {
item: MotaSettingItem | null;
list: Record<string, MotaSettingItem>;
text: string[];
}
export class MotaSetting extends EventEmitter<SettingEvent> {
readonly list: Record<string, MotaSettingItem> = {};
/**
*
* @param setting
*/
reset(setting: Record<string, boolean | number>) {
for (const [key, value] of Object.entries(setting)) {
this.setValue(key, value);
}
}
/**
*
@ -36,7 +61,12 @@ class MotaSetting extends EventEmitter<SettingEvent> {
* @param key
* @param value
*/
register(key: string, name: string, value: number, step?: number): this;
register(
key: string,
name: string,
value: number,
step?: [number, number, number]
): this;
/**
*
* @param key
@ -47,11 +77,12 @@ class MotaSetting extends EventEmitter<SettingEvent> {
key: string,
name: string,
value: MotaSettingType,
step: number = 1
step: [number, number, number] = [0, 100, 1]
) {
const setting: MotaSettingItem = {
name,
value
value,
key
};
if (!(value instanceof MotaSetting)) setting.defaults = value;
if (typeof value === 'number') setting.step = step;
@ -83,7 +114,7 @@ class MotaSetting extends EventEmitter<SettingEvent> {
}
const old = setting.value as boolean | number;
setting.value = value;
this.emit('valueChange', key, old, value);
this.emit('valueChange', key, value, old);
}
/**
@ -112,13 +143,14 @@ class MotaSetting extends EventEmitter<SettingEvent> {
setDisplayFunc(key: string, func: (value: MotaSettingType) => string) {
const setting = this.getSettingBy(key.split('.'));
setting.display = func;
return this;
}
private getSettingBy(list: string[]) {
let now: MotaSetting = this;
for (let i = 0; i < list.length - 1; i++) {
const item = now.list[list[i]];
const item = now.list[list[i]].value;
if (!(item instanceof MotaSetting)) {
throw new Error(
`Cannot get setting. The parent isn't a MotaSetting instance.` +
@ -132,8 +164,203 @@ class MotaSetting extends EventEmitter<SettingEvent> {
}
}
interface SettingDisplayerEvent extends EmitableEvent {
update: (stack: string[], display: SettingDisplayInfo[]) => void;
}
export class SettingDisplayer extends EventEmitter<SettingDisplayerEvent> {
setting: MotaSetting;
textInfo: SettingText;
/** 选项选中栈 */
selectStack: string[] = [];
displayInfo: SettingDisplayInfo[] = reactive([]);
constructor(setting: MotaSetting, textInfo: SettingText) {
super();
this.setting = setting;
this.textInfo = textInfo;
this.update();
}
/**
*
* @param key
*/
add(key: string) {
this.selectStack.push(...key.split('.'));
this.update();
}
/**
*
* @param index
*/
cut(index: number, noUpdate: boolean = false) {
this.selectStack.splice(index, Infinity);
if (!noUpdate) this.update();
}
update() {
const list = this.selectStack;
let now = this.setting;
let nowText: string[] | SettingText = this.textInfo;
this.displayInfo = [];
for (let i = 0; i < list.length - 1; i++) {
const item = now.list[list[i]].value;
if (!(item instanceof MotaSetting)) {
throw new Error(
`Cannot get setting. The parent isn't a MotaSetting instance.` +
`Key: '${list.join('.')}'. Reading: '${list[i + 1]}'`
);
}
this.displayInfo.push({
item: now.list[list[i]],
text: [],
list: now.list
});
now = item;
if (nowText && !(nowText instanceof Array))
nowText = nowText[list[i]];
}
if (nowText && !(nowText instanceof Array))
nowText = nowText[list.at(-1)!];
const last = now.list[list.at(-1)!];
if (last) {
this.displayInfo.push({
item: last,
text: nowText instanceof Array ? nowText : ['请选择设置'],
list: now.list
});
if (last.value instanceof MotaSetting) {
this.displayInfo.push({
item: null,
text: ['请选择设置'],
list: (last.value as MotaSetting).list
});
}
} else {
this.displayInfo.push({
item: null,
text: ['请选择设置'],
list: this.setting.list
});
}
this.emit('update', this.selectStack, this.displayInfo);
}
}
export const mainSetting = new MotaSetting();
// ----- 监听设置修改
mainSetting.on('valueChange', (key, n, o) => {
const [root, setting] = key.split('.');
if (root === 'screen') {
handleScreenSetting(setting, n, o);
} else if (root === 'action') {
handleActionSetting(setting, n, o);
} else if (root === 'utils') {
handleUtilsSetting(setting, n, o);
}
});
export async function triggerFullscreen(full: boolean) {
const { maxGameScale } = core.plugin.utils;
if (!!document.fullscreenElement && !full) {
await document.exitFullscreen();
requestAnimationFrame(() => {
maxGameScale(1);
});
}
if (full && !document.fullscreenElement) {
await document.body.requestFullscreen();
requestAnimationFrame(() => {
maxGameScale();
});
}
}
const root = document.getElementById('root') as HTMLDivElement;
const root2 = document.getElementById('root2') as HTMLDivElement;
function handleScreenSetting<T extends number | boolean>(
key: string,
n: T,
o: T
) {
if (n === o) return;
if (key === 'fullscreen') {
// 全屏
triggerFullscreen(n as boolean);
} else if (key === 'halo') {
// 光环
core.setLocalStorage('showHalo', n);
} else if (key === 'frag') {
// 打怪特效
core.setLocalStorage('frag', n);
} else if (key === 'itemDetail') {
// 宝石血瓶显伤
core.setLocalStorage('itemDetail', n);
} else if (key === 'transition') {
// 界面动画
core.setLocalStorage('transition', n);
transition.value = n as boolean;
} else if (key === 'antiAlias') {
// 抗锯齿
core.setLocalStorage('antiAlias', n);
for (const canvas of core.dom.gameCanvas) {
if (core.domStyle.hdCanvas.includes(canvas.id)) continue;
if (n) {
canvas.classList.remove('no-anti-aliasing');
} else {
canvas.classList.add('no-anti-aliasing');
}
}
} else if (key === 'autoScale') {
// 自动放缩
core.setLocalStorage('autoScale', n);
} else if (key === 'fontSize') {
// 字体大小
core.setLocalStorage('fontSize', n);
root.style.fontSize = root2.style.fontSize = `${n}px`;
}
}
function handleActionSetting<T extends number | boolean>(
key: string,
n: T,
o: T
) {
if (n === o) return;
if (key === 'autoSkill') {
// 自动切换技能
flags.autoSkill = n;
}
if (key === 'fixed') {
// 定点查看
core.setLocalStorage('fixed', n);
}
}
function handleUtilsSetting<T extends number | boolean>(
key: string,
n: T,
o: T
) {
if (n === o) return;
if (key === 'betterLoad') {
// 加载优化
core.setLocalStorage('betterLoad', n);
}
}
// ----- 游戏的所有设置项
mainSetting
.register(
@ -147,7 +374,7 @@ mainSetting
.register('transition', '界面动画', false)
.register('antiAlias', '抗锯齿', false)
.register('autoScale', '自动放缩', true)
.register('fontSize', '字体大小', 16, 1)
.register('fontSize', '字体大小', 16, [8, 28, 1])
)
.register(
'action',
@ -157,9 +384,31 @@ mainSetting
.register('fixed', '定点查看', true)
.register('hotkey', '快捷键', false)
.markSpecial('hotkey', 'hotkey')
.setDisplayFunc('hotkey', () => '')
)
.register(
'utils',
'功能设置',
new MotaSetting().register('betterLoad', '优化加载', true)
);
loading.once('coreInit', () => {
mainSetting.reset({
'screen.fullscreen': false,
'screen.halo': !!core.getLocalStorage('showHalo', true),
'screen.frag': !!core.getLocalStorage('frag', true),
'screen.itemDetail': !!core.getLocalStorage('itemDetail', true),
'screen.transition': !!core.getLocalStorage('transition', false),
'screen.antiAlias': !!core.getLocalStorage('antiAlias', false),
'screen.autoScale': !!core.getLocalStorage('autoScale', true),
'screen.fontSize': core.getLocalStorage('fontSize', 16),
'action.fixed': !!core.getLocalStorage('fixed', true),
'utils.betterLoad': !!core.getLocalStorage('betterLoad', true)
});
});
hook.once('reset', () => {
mainSetting.reset({
'action.autoSkill': flags.autoSkill ?? true
});
});

View File

@ -1,32 +1,20 @@
{
"fullscreen": {
"text": "全屏游戏",
"desc": [
"screen": {
"fullscreen": [
"是否全屏进行游戏全屏后按ESC退出全屏不能开启系统设置菜单请按下方的按钮打开。",
"进入或退出全屏后请存读档一下,以解决一部分绘制问题。"
]
},
"transition": {
"text": "界面动画",
"desc": [
],
"halo": ["开启后,会在地图上显示范围光环。"],
"frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"],
"itemDetail": ["是否在地图上显示宝石血瓶装备等增加的属性值"],
"transition": [
"是否展示当一个ui界面如怪物手册等的打开与关闭时的动画。当此项开启时",
"所有界面被打开或关闭时都会展示动画,否则会直接展示出来"
]
},
"itemDetail": {
"text": "宝石血瓶显伤",
"desc": ["是否在地图上显示宝石血瓶装备等增加的属性值"]
},
"autoSkill": {
"text": "自动切换技能",
"desc": [
"开启后,打怪物的时候会自动选择伤害最低的技能。同时显伤也会显示此状态下的伤害,",
"临界也会考虑技能在内"
]
},
"autoScale": {
"text": "自动放缩",
"desc": [
],
"antiAlias": [
"是否开启抗锯齿。开启后,画面会变得不那么锐利,观感更加舒适;关闭后,可以更好地展现出像素感,同时部分像素错误也不会出现。"
],
"autoScale": [
"开启后,每次进入游戏时会自动缩放游戏画面至合适值。该项只对电脑端有效。",
"<br>",
"<br>",
@ -35,46 +23,26 @@
"1. 首先尝试缩放至最大缩放比例",
"<br>",
"2. 如果缩放后游戏画面高度高于页面高度的95%,那么缩小一个缩放比例,否则保持最大比例"
]
],
"fontSize": ["在各种 ui 界面中显示的文字大小,范围为 8 - 28"]
},
"showHalo": {
"text": "展示范围光环",
"desc": ["开启后,会在地图上显示范围光环。"]
},
"useFixed": {
"text": "移动鼠标显示怪物信息",
"desc": [
"action": {
"autoSkill": [
"开启后,打怪物的时候会自动选择伤害最低的技能。同时显伤也会显示此状态下的伤害,",
"临界也会考虑技能在内"
],
"fixed": [
"开启后,当鼠标移动到怪物上时,会以盒子的形式展示该点的怪物信息。手机端此功能无效。",
"<br>",
"<br>",
"注当鼠标移动到怪物上时经过200毫秒才会显示信息防止误操作。"
]
],
"hotkey": ["设置游戏中会用到的一些快捷键"]
},
"autoLocate": {
"text": "自动勇士定位",
"desc": [
"此项会在进入第二章后会起作用。开启后,当勇士处于不同位置打同一个怪物伤害不同时,在地图上使用绿色箭头标出伤害最低的位置,",
"其余方向,伤害越高,箭头颜色越红,同时在自动寻路中选择可以到达的伤害最低的位置。",
"utils": {
"betterLoad": [
"<span style=\"color: yellow; font-weight: 700\">试验性功能</span>",
"<br>",
"<br>",
"注:如果出现明显卡顿现象可以考虑关闭本设置或自动切换技能设置。"
]
},
"antiAliasing": {
"text": "抗锯齿",
"desc": [
"是否开启抗锯齿。开启后,画面会变得不那么锐利,观感更加舒适;关闭后,可以更好地展现出像素感,同时部分像素错误也不会出现。"
]
},
"showStudied": {
"text": "展示已学习技能",
"desc": [
"开启后,会在画面内以类似状态栏的盒子的形式显示当前已学习的怪物技能。"
]
},
"betterLoad": {
"text": "优化加载",
"desc": [
"开启后游戏将对加载进行优化,缩短进入游戏时的加载时长,而在游戏中对资源进行部分性按需加载,从而对加载进行优化。",
"该设置不会影响你的正常游戏,但如果网络环境较差,可能会导致楼层转换时间明显变长。",
"<br>",

View File

@ -169,7 +169,7 @@ core.events.afterBattle = function (
else core.clearContinueAutomaticRoute();
// 打怪特效
if (has(x) && has(y)) {
if (core.getLocalStorage('frag') && has(x) && has(y)) {
const frame = core.status.globalAnimateStatus % 2;
const canvas = document.createElement('canvas');
canvas.width = 32;

View File

@ -31,7 +31,7 @@ core.control.updateDamage = function (floorId = core.status.floorId, ctx) {
// 获取宝石信息 并绘制
function getItemDetail(floorId: FloorIds, onMap: boolean) {
if (!core.getFlag('itemDetail')) return;
if (!core.getLocalStorage('itemDetail')) return;
floorId ??= core.status.thisMap.floorId;
let diff: Record<string | symbol, number | undefined> = {};
const before = core.status.hero;

View File

@ -21,8 +21,16 @@ export let isMobile = matchMedia('(max-width: 600px)').matches;
window.addEventListener('resize', () => {
requestAnimationFrame(() => {
isMobile = matchMedia('(max-width: 600px)').matches;
checkMobile();
});
});
checkMobile();
function checkMobile() {
if (isMobile) {
alert('手机端建议使用自带的浏览器进行游玩,并在进入游戏后开启全屏游玩');
}
}
/**
*

View File

@ -12,6 +12,11 @@
transition: all 0.6s linear;
opacity: 0;
background-color: #000d;
font-size: 16px;
}
#root2 {
font-size: 16px;
}
.antdv-message {

View File

@ -1,171 +1,307 @@
<template>
<Column :width="60" :height="60" @close="exit"
><template #left
><div id="setting-list">
<div class="setting-main">
<div id="tools">
<span class="button-text" @click="exit"
><left-outlined /> 返回游戏</span
>
</div>
<div class="setting-container">
<div class="setting-select">
<TransitionGroup name="list">
<div
v-for="(info, i) of display"
:key="i"
class="setting-display"
>
<Scroll class="setting-scroll">
<div class="setting-list">
<div
v-for="item of info.list"
class="setting-item selectable"
:selected="item === info.item"
@click="click(item.key, i, item)"
>
<span>{{ item.name }}</span>
<span
class="selectable"
:selected="selected === 'fullscreen'"
@click="click('fullscreen')"
>全屏游戏:&nbsp;&nbsp;&nbsp;{{
fullscreen ? 'ON' : 'OFF'
}}</span
:selected="item === info.item"
class="setting-cascade"
v-if="isCascade(item)"
>
<RightOutlined />
</span>
<span v-else class="setting-value">
{{ getItemValue(item) }}
</span>
</div>
</div>
</Scroll>
<a-divider
class="display-divider"
type="vertical"
dashed
></a-divider>
</div>
</TransitionGroup>
</div>
<div class="setting-info">
<div
class="info-text"
v-html="splitText(display.at(-1)?.text ?? ['请选择设置'])"
></div>
<a-divider class="info-divider" dashed></a-divider>
<div class="info-editor" v-if="!!selectedItem">
<div v-if="!!selectedItem.special"></div>
<div
class="editor-number"
v-else-if="typeof selectedItem.value === 'number'"
>
<span>修改设置</span>
<a-input-number
class="number-input"
size="large"
:min="selectedItem.step?.[0] ?? 0"
:max="selectedItem.step?.[1] ?? 100"
:step="selectedItem.step?.[2] ?? 1"
:keyboard="true"
:value="selectedItem.value"
@change="changeValue"
></a-input-number>
</div>
<div
class="editor-boolean"
v-else-if="typeof selectedItem.value === 'boolean'"
>
<span
class="selectable"
:selected="selected === 'transition'"
@click="click('transition')"
>界面动画:&nbsp;&nbsp;&nbsp;{{
transition ? 'ON' : 'OFF'
>当前{{
selectedItem.value ? '开启' : '关闭'
}}</span
>
<span
class="selectable"
:selected="selected === 'itemDetail'"
@click="click('itemDetail')"
>宝石血瓶显伤:&nbsp;&nbsp;&nbsp;{{
itemDetail ? 'ON' : 'OFF'
}}</span
<a-button
class="boolean-button"
type="primary"
size="large"
@click="changeValue(!selectedItem.value)"
>
<span
class="selectable"
:selected="selected === 'autoSkill'"
@click="click('autoSkill')"
>自动切换技能:&nbsp;&nbsp;&nbsp;{{
autoSkill ? 'ON' : 'OFF'
}}</span
>
<span
class="selectable"
:selected="selected === 'autoScale'"
@click="click('autoScale')"
>自动放缩:&nbsp;&nbsp;&nbsp;{{
autoScale ? 'ON' : 'OFF'
}}</span
>
<span
class="selectable"
:selected="selected === 'showHalo'"
@click="click('showHalo')"
>展示范围光环:&nbsp;&nbsp;&nbsp;{{
showHalo ? 'ON' : 'OFF'
}}</span
>
<span
class="selectable"
:selected="selected === 'useFixed'"
@click="click('useFixed')"
>移动鼠标显示怪物信息:&nbsp;&nbsp;&nbsp;{{
useFixed ? 'ON' : 'OFF'
}}</span
>
<!-- <span
class="selectable"
:selected="selected === 'autoLocate'"
@click="click('autoLocate')"
>勇士自动定位:&nbsp;&nbsp;&nbsp;{{
autoLocate ? 'ON' : 'OFF'
}}</span
> -->
<span
class="selectable"
:selected="selected === 'antiAliasing'"
@click="click('antiAliasing')"
>抗锯齿:&nbsp;&nbsp;&nbsp;{{
antiAliasing ? 'ON' : 'OFF'
}}</span
>
<!-- <span
class="selectable"
:selected="selected === 'showStudied'"
v-if="core.plugin.skillTree.getSkillLevel(11) > 0"
@click="click('showStudied')"
>展示已学习技能:&nbsp;&nbsp;&nbsp;{{
showStudied ? 'ON' : 'OFF'
}}</span
> -->
</div></template
>
<template #right><span v-html="descText"></span></template
></Column>
{{ selectedItem.value ? '关闭' : '开启' }}设置
</a-button>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { computed, shallowRef } from 'vue';
import {
transition,
itemDetail,
autoSkill,
autoScale,
showStudied,
showHalo,
useFixed,
autoLocate,
antiAliasing,
fullscreen,
triggerFullscreen
} from '../plugin/settings';
import settingInfo from '../data/settings.json';
import { has, splitText } from '../plugin/utils';
import Column from '../components/colomn.vue';
mainSetting,
MotaSetting,
MotaSettingItem,
SettingDisplayer,
SettingDisplayInfo,
SettingText
} from '../core/main/setting';
import settingText from '../data/settings.json';
import { RightOutlined, LeftOutlined } from '@ant-design/icons-vue';
import { splitText } from '../plugin/utils';
import Scroll from '../components/scroll.vue';
import { settingsOpened } from '../plugin/uiController';
type Settings = typeof settingInfo;
const props = defineProps<{
info?: MotaSetting;
text?: SettingText;
}>();
const core = window.core;
const setting = props.info ?? mainSetting;
const text = props.text ?? (settingText as SettingText);
const display = shallowRef<SettingDisplayInfo[]>([]);
const selectedItem = computed(() => display.value.at(-1)?.item);
const selected = ref<keyof Settings>('fullscreen');
fullscreen.value = !!document.fullscreenElement;
const descText = computed(() => {
return splitText(settingInfo[selected.value].desc);
const displayer = new SettingDisplayer(setting, text);
displayer.on('update', (stack, dis) => {
display.value = dis;
});
display.value = displayer.displayInfo;
const settings: Record<keyof Settings, Ref<boolean>> = {
transition,
itemDetail,
autoSkill,
autoScale,
showHalo,
showStudied,
useFixed,
autoLocate,
antiAliasing,
fullscreen,
betterLoad: ref(false)
};
const ignore: (keyof Settings)[] = ['fullscreen'];
function exit() {
ancTe.plugin.ui.settingsOpened.value = false;
function getItemValue(item: MotaSettingItem) {
if (item.value instanceof MotaSetting) {
return '';
} else {
if (item.display) {
return item.display(item.value);
} else {
if (typeof item.value === 'number') {
return item.value.toString();
} else {
return item.value ? 'ON' : 'OFF';
}
}
}
}
function click(id: keyof Settings) {
if (selected.value !== id) {
selected.value = id;
return;
function isCascade(item: MotaSettingItem) {
return item.value instanceof MotaSetting;
}
function click(key: string, index: number, item: MotaSettingItem) {
if (item.value instanceof MotaSetting) {
if (index === display.value.length - 1) {
displayer.add(key);
} else {
if (displayer.selectStack.includes(key)) {
displayer.cut(index);
} else {
displayer.cut(index, true);
displayer.add(key);
}
if (!ignore.includes(id)) {
settings[id].value = !settings[id].value;
if (id === 'autoSkill') {
core.status.route.push(`set:autoSkill:${settings.autoSkill.value}`);
}
} else {
if (id === 'fullscreen') {
triggerFullscreen();
displayer.cut(index, true);
displayer.add(key);
}
}
function changeValue(value: number | boolean) {
setting.setValue(displayer.selectStack.join('.'), value);
displayer.update();
}
function exit() {
settingsOpened.value = false;
}
</script>
<style lang="less" scoped>
#setting-list {
#tools {
width: 100%;
font-family: 'normal';
font-size: 3.2vh;
height: 5vh;
position: fixed;
left: 10vw;
top: 10vh;
}
.setting-main {
user-select: none;
display: flex;
flex-direction: column;
justify-content: center;
font-family: normal;
font-size: 150%;
.setting-container {
height: 60%;
display: flex;
flex-direction: row;
}
}
.setting-select {
display: flex;
flex-direction: row;
transition: all 0.5s ease;
}
.list-move,
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(-50px);
}
.list-leave-active {
position: absolute;
pointer-events: none;
}
.setting-display {
display: flex;
flex-direction: row;
height: 100%;
.setting-list {
display: flex;
flex-direction: column;
}
.display-divider {
border-color: #fff4;
height: auto;
}
.setting-item {
width: 100%;
padding: 1% 3% 1% 3%;
padding: 2%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.setting-cascade {
font-size: 75%;
margin-right: 40px;
transition: all 0.5s ease;
}
.setting-cascade[selected='true'] {
font-size: 90%;
margin-right: 10px;
color: cyan;
}
.setting-value {
margin-right: 10px;
color: rgb(242, 255, 101);
}
}
.setting-scroll {
width: 300px;
height: 100%;
}
.setting-info {
width: 400px;
.info-divider {
border-color: #fff4;
margin: 2% 0;
}
.editor-boolean {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
padding: 0 10% 0 5%;
.boolean-button {
font-size: 75%;
}
}
.info-text {
font-size: 85%;
min-height: 30%;
}
.editor-number {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
padding: 0 10% 0 5%;
.number-input {
font-size: 80%;
width: 40%;
}
}
}
</style>

View File

@ -68,7 +68,7 @@ import { Matrix4 } from '../plugin/webgl/matrix';
import { doByInterval, keycode } from '../plugin/utils';
import { KeyCode } from '../plugin/keyCodes';
import { achievementOpened } from '../plugin/uiController';
import { triggerFullscreen } from '../plugin/settings';
import { triggerFullscreen } from '../core/main/setting';
import { loading } from '../core/loader/load';
let startdiv: HTMLDivElement;
@ -203,7 +203,7 @@ function bgm() {
async function setFullscreen() {
const index = toshow.length - toshow.indexOf(selected.value) - 1;
await triggerFullscreen();
await triggerFullscreen(!fullscreen.value);
requestAnimationFrame(() => {
fullscreen.value = !!document.fullscreenElement;
setCursor(buttons[index], index);