mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-10-09 04:11:46 +08:00
Compare commits
3 Commits
81e96e31f0
...
d135328858
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d135328858 | ||
82d58756b7 | |||
e666b85ba3 |
@ -1,5 +1,5 @@
|
|||||||
import { gameKey } from '@motajs/system-action';
|
import { gameKey } from '@motajs/system-action';
|
||||||
import { MAIN_WIDTH, MAIN_HEIGHT } from './shared';
|
import { MAIN_WIDTH, MAIN_HEIGHT, POP_BOX_WIDTH, CENTER_LOC } from './shared';
|
||||||
import {
|
import {
|
||||||
saveSave,
|
saveSave,
|
||||||
mainUIController,
|
mainUIController,
|
||||||
@ -9,6 +9,7 @@ import {
|
|||||||
ReplaySettingsUI,
|
ReplaySettingsUI,
|
||||||
openViewMap
|
openViewMap
|
||||||
} from './ui';
|
} from './ui';
|
||||||
|
import { ElementLocator } from '@motajs/render-core';
|
||||||
|
|
||||||
export function createAction() {
|
export function createAction() {
|
||||||
gameKey
|
gameKey
|
||||||
@ -22,11 +23,13 @@ export function createAction() {
|
|||||||
saveLoad(mainUIController, [0, 0, MAIN_WIDTH, MAIN_HEIGHT]);
|
saveLoad(mainUIController, [0, 0, MAIN_WIDTH, MAIN_HEIGHT]);
|
||||||
})
|
})
|
||||||
.realize('menu', () => {
|
.realize('menu', () => {
|
||||||
openSettings(mainUIController, [420, 240, 240, 400, 0.5, 0.5]);
|
const loc = CENTER_LOC.slice() as ElementLocator;
|
||||||
|
loc[2] = POP_BOX_WIDTH;
|
||||||
|
openSettings(mainUIController, loc);
|
||||||
})
|
})
|
||||||
.realize('replay', () => {
|
.realize('replay', () => {
|
||||||
mainUIController.open(ReplaySettingsUI, {
|
mainUIController.open(ReplaySettingsUI, {
|
||||||
loc: [420, 240, void 0, void 0, 0.5, 0.5]
|
loc: CENTER_LOC
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.realize('viewMap', () => {
|
.realize('viewMap', () => {
|
||||||
|
@ -33,6 +33,8 @@ export interface ConfirmBoxProps extends DefaultProps, TextContentProps {
|
|||||||
color?: CanvasStyle;
|
color?: CanvasStyle;
|
||||||
/** 对话框边框颜色,当未设置 winskin 时生效 */
|
/** 对话框边框颜色,当未设置 winskin 时生效 */
|
||||||
border?: CanvasStyle;
|
border?: CanvasStyle;
|
||||||
|
/** 按键作用域,如果需要同作用域按键,那么需要传入 */
|
||||||
|
scope?: symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConfirmBoxEmits = {
|
export type ConfirmBoxEmits = {
|
||||||
@ -53,7 +55,8 @@ const confirmBoxProps = {
|
|||||||
'winskin',
|
'winskin',
|
||||||
'defaultYes',
|
'defaultYes',
|
||||||
'color',
|
'color',
|
||||||
'border'
|
'border',
|
||||||
|
'scope'
|
||||||
],
|
],
|
||||||
emits: ['no', 'yes']
|
emits: ['no', 'yes']
|
||||||
} satisfies SetupComponentOptions<
|
} satisfies SetupComponentOptions<
|
||||||
@ -143,7 +146,7 @@ export const ConfirmBox = defineComponent<
|
|||||||
noSize.value = [width, height];
|
noSize.value = [width, height];
|
||||||
};
|
};
|
||||||
|
|
||||||
const [key] = useKey();
|
const [key] = useKey(false, props.scope);
|
||||||
key.realize('confirm', () => {
|
key.realize('confirm', () => {
|
||||||
if (selected.value) emit('yes');
|
if (selected.value) emit('yes');
|
||||||
else emit('no');
|
else emit('no');
|
||||||
@ -242,6 +245,8 @@ export interface ChoicesProps extends DefaultProps, TextContentProps {
|
|||||||
interval?: number;
|
interval?: number;
|
||||||
/** 默认选中的选项索引 */
|
/** 默认选中的选项索引 */
|
||||||
selected?: number;
|
selected?: number;
|
||||||
|
/** 按键作用域,如果需要同作用域按键,那么需要传入,例如系统设置 UI */
|
||||||
|
scope?: symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ChoicesEmits = {
|
export type ChoicesEmits = {
|
||||||
@ -265,7 +270,8 @@ const choicesProps = {
|
|||||||
'titleFill',
|
'titleFill',
|
||||||
'pad',
|
'pad',
|
||||||
'interval',
|
'interval',
|
||||||
'selected'
|
'selected',
|
||||||
|
'scope'
|
||||||
],
|
],
|
||||||
emits: ['choose']
|
emits: ['choose']
|
||||||
} satisfies SetupComponentOptions<
|
} satisfies SetupComponentOptions<
|
||||||
@ -464,7 +470,7 @@ export const Choices = defineComponent<
|
|||||||
selected.value = 0;
|
selected.value = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const [key] = useKey();
|
const [key] = useKey(false, props.scope);
|
||||||
key.realize('moveUp', () => {
|
key.realize('moveUp', () => {
|
||||||
if (selected.value === 0) {
|
if (selected.value === 0) {
|
||||||
if (pageCom.value?.now() !== 0) {
|
if (pageCom.value?.now() !== 0) {
|
||||||
@ -505,27 +511,25 @@ export const Choices = defineComponent<
|
|||||||
color={props.color ?? '#333'}
|
color={props.color ?? '#333'}
|
||||||
border={props.border}
|
border={props.border}
|
||||||
/>
|
/>
|
||||||
{hasTitle.value && (
|
<text
|
||||||
<text
|
hidden={!hasTitle.value}
|
||||||
loc={titleLoc.value}
|
loc={titleLoc.value}
|
||||||
text={props.title}
|
text={props.title}
|
||||||
font={props.titleFont ?? new Font(void 0, 18)}
|
font={props.titleFont ?? new Font(void 0, 18)}
|
||||||
fillStyle={props.titleFill ?? 'gold'}
|
fillStyle={props.titleFill ?? 'gold'}
|
||||||
zIndex={5}
|
zIndex={5}
|
||||||
onSetText={updateTitleHeight}
|
onSetText={updateTitleHeight}
|
||||||
/>
|
/>
|
||||||
)}
|
<TextContent
|
||||||
{hasText.value && (
|
{...attrs}
|
||||||
<TextContent
|
hidden={!hasText.value}
|
||||||
{...attrs}
|
text={props.text}
|
||||||
text={props.text}
|
loc={contentLoc.value}
|
||||||
loc={contentLoc.value}
|
width={contentWidth.value}
|
||||||
width={contentWidth.value}
|
zIndex={5}
|
||||||
zIndex={5}
|
autoHeight
|
||||||
autoHeight
|
onUpdateHeight={updateContentHeight}
|
||||||
onUpdateHeight={updateContentHeight}
|
/>
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Page
|
<Page
|
||||||
ref={pageCom}
|
ref={pageCom}
|
||||||
loc={choiceLoc.value}
|
loc={choiceLoc.value}
|
||||||
|
@ -5,6 +5,14 @@ import { computed, defineComponent, onMounted, ref, watch } from 'vue';
|
|||||||
import { Scroll, ScrollExpose } from './scroll';
|
import { Scroll, ScrollExpose } from './scroll';
|
||||||
import { Font } from '@motajs/render-style';
|
import { Font } from '@motajs/render-style';
|
||||||
import { MotaOffscreenCanvas2D } from '@motajs/render-core';
|
import { MotaOffscreenCanvas2D } from '@motajs/render-core';
|
||||||
|
import {
|
||||||
|
HALF_STATUS_WIDTH,
|
||||||
|
STATUS_BAR_HEIGHT,
|
||||||
|
STATUS_BAR_WIDTH
|
||||||
|
} from '../shared';
|
||||||
|
|
||||||
|
const SCROLL_HEIGHT = STATUS_BAR_HEIGHT - 280;
|
||||||
|
const HALF_HEIGHT = SCROLL_HEIGHT / 2;
|
||||||
|
|
||||||
export interface FloorSelectorProps extends DefaultProps {
|
export interface FloorSelectorProps extends DefaultProps {
|
||||||
floors: FloorIds[];
|
floors: FloorIds[];
|
||||||
@ -67,7 +75,7 @@ export const FloorSelector = defineComponent<
|
|||||||
|
|
||||||
const getGradient = (ctx: CanvasRenderingContext2D) => {
|
const getGradient = (ctx: CanvasRenderingContext2D) => {
|
||||||
if (gradient) return gradient;
|
if (gradient) return gradient;
|
||||||
gradient = ctx.createLinearGradient(0, 0, 0, 200);
|
gradient = ctx.createLinearGradient(0, 0, 0, SCROLL_HEIGHT);
|
||||||
gradient.addColorStop(0, 'rgba(255,255,255,0)');
|
gradient.addColorStop(0, 'rgba(255,255,255,0)');
|
||||||
gradient.addColorStop(0.2, 'rgba(255,255,255,1)');
|
gradient.addColorStop(0.2, 'rgba(255,255,255,1)');
|
||||||
gradient.addColorStop(0.8, 'rgba(255,255,255,1)');
|
gradient.addColorStop(0.8, 'rgba(255,255,255,1)');
|
||||||
@ -112,12 +120,24 @@ export const FloorSelector = defineComponent<
|
|||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<container>
|
<container>
|
||||||
<text text={floorName.value} loc={[90, 24]} anc={[0.5, 0.5]} />
|
<text
|
||||||
<g-line line={[48, 40, 132, 40]} lineWidth={1} />
|
text={floorName.value}
|
||||||
<g-line line={[48, 440, 132, 440]} lineWidth={1} />
|
loc={[HALF_STATUS_WIDTH, 24]}
|
||||||
|
anc={[0.5, 0.5]}
|
||||||
|
/>
|
||||||
|
<g-line line={[48, 40, STATUS_BAR_WIDTH - 48, 40]} lineWidth={1} />
|
||||||
|
<g-line
|
||||||
|
line={[
|
||||||
|
48,
|
||||||
|
STATUS_BAR_HEIGHT - 40,
|
||||||
|
STATUS_BAR_WIDTH - 48,
|
||||||
|
STATUS_BAR_HEIGHT - 40
|
||||||
|
]}
|
||||||
|
lineWidth={1}
|
||||||
|
/>
|
||||||
<text
|
<text
|
||||||
text="退出"
|
text="退出"
|
||||||
loc={[90, 456]}
|
loc={[90, STATUS_BAR_HEIGHT - 24]}
|
||||||
anc={[0.5, 0.5]}
|
anc={[0.5, 0.5]}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={close}
|
onClick={close}
|
||||||
@ -138,25 +158,25 @@ export const FloorSelector = defineComponent<
|
|||||||
/>
|
/>
|
||||||
<text
|
<text
|
||||||
text="「 下移一层 」"
|
text="「 下移一层 」"
|
||||||
loc={[90, 370]}
|
loc={[90, STATUS_BAR_HEIGHT - 110]}
|
||||||
anc={[0.5, 0.5]}
|
anc={[0.5, 0.5]}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={() => changeFloor(-1)}
|
onClick={() => changeFloor(-1)}
|
||||||
/>
|
/>
|
||||||
<text
|
<text
|
||||||
text="「 下移十层 」"
|
text="「 下移十层 」"
|
||||||
loc={[90, 410]}
|
loc={[90, STATUS_BAR_HEIGHT - 70]}
|
||||||
anc={[0.5, 0.5]}
|
anc={[0.5, 0.5]}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={() => changeFloor(-10)}
|
onClick={() => changeFloor(-10)}
|
||||||
/>
|
/>
|
||||||
<container loc={[0, 140, 144, 200]}>
|
<container loc={[0, 140, 144, SCROLL_HEIGHT]}>
|
||||||
<Scroll
|
<Scroll
|
||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
loc={[0, 0, 144, 200]}
|
loc={[0, 0, 144, SCROLL_HEIGHT]}
|
||||||
noscroll
|
noscroll
|
||||||
zIndex={10}
|
zIndex={10}
|
||||||
padEnd={88}
|
padEnd={HALF_HEIGHT - 12}
|
||||||
>
|
>
|
||||||
{floors.value.map((v, i, a) => {
|
{floors.value.map((v, i, a) => {
|
||||||
const floor = core.floors[v];
|
const floor = core.floors[v];
|
||||||
@ -168,7 +188,7 @@ export const FloorSelector = defineComponent<
|
|||||||
return (
|
return (
|
||||||
<container
|
<container
|
||||||
nocache
|
nocache
|
||||||
loc={[0, i * 24 + 88, 144, 24]}
|
loc={[0, i * 24 + HALF_HEIGHT - 12, 144, 24]}
|
||||||
key={v}
|
key={v}
|
||||||
>
|
>
|
||||||
<text
|
<text
|
||||||
@ -195,14 +215,14 @@ export const FloorSelector = defineComponent<
|
|||||||
})}
|
})}
|
||||||
</Scroll>
|
</Scroll>
|
||||||
<g-line
|
<g-line
|
||||||
line={[130, 0, 130, 200]}
|
line={[130, 0, 130, SCROLL_HEIGHT]}
|
||||||
zIndex={5}
|
zIndex={5}
|
||||||
lineWidth={1}
|
lineWidth={1}
|
||||||
strokeStyle="#aaa"
|
strokeStyle="#aaa"
|
||||||
/>
|
/>
|
||||||
<sprite
|
<sprite
|
||||||
zIndex={20}
|
zIndex={20}
|
||||||
loc={[0, 0, 144, 200]}
|
loc={[0, 0, 144, SCROLL_HEIGHT]}
|
||||||
nocache
|
nocache
|
||||||
noevent
|
noevent
|
||||||
render={renderMask}
|
render={renderMask}
|
||||||
|
@ -118,6 +118,16 @@ export const Page = defineComponent<
|
|||||||
const height = computed(() => props.loc[3] ?? 200);
|
const height = computed(() => props.loc[3] ?? 200);
|
||||||
const round = computed(() => font.value.size / 4);
|
const round = computed(() => font.value.size / 4);
|
||||||
const nowPageFont = computed(() => Font.clone(font.value, { weight: 700 }));
|
const nowPageFont = computed(() => Font.clone(font.value, { weight: 700 }));
|
||||||
|
/** 页码的横向间距 */
|
||||||
|
const interval = computed(() => {
|
||||||
|
const size = font.value.size * 1.5;
|
||||||
|
const max = size * 9;
|
||||||
|
if (width.value > max) {
|
||||||
|
return size;
|
||||||
|
} else {
|
||||||
|
return (width.value - size * 5) / 4;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 左右箭头的颜色
|
// 左右箭头的颜色
|
||||||
const leftColor = computed(() => (isFirst.value ? '#666' : '#ddd'));
|
const leftColor = computed(() => (isFirst.value ? '#666' : '#ddd'));
|
||||||
@ -135,11 +145,12 @@ export const Page = defineComponent<
|
|||||||
pageLoc.value = [0, height.value - pageH, width.value, pageH];
|
pageLoc.value = [0, height.value - pageH, width.value, pageH];
|
||||||
const center = width.value / 2;
|
const center = width.value / 2;
|
||||||
const size = font.value.size * 1.5;
|
const size = font.value.size * 1.5;
|
||||||
|
const int = size + interval.value;
|
||||||
nowPageLoc.value = [center, 0, size, size, 0.5, 0];
|
nowPageLoc.value = [center, 0, size, size, 0.5, 0];
|
||||||
leftPageLoc.value = [center - size * 1.5, 0, size, size, 0.5, 0];
|
leftPageLoc.value = [center - int, 0, size, size, 0.5, 0];
|
||||||
leftLoc.value = [center - size * 3, 0, size, size, 0.5, 0];
|
leftLoc.value = [center - int * 2, 0, size, size, 0.5, 0];
|
||||||
rightPageLoc.value = [center + size * 1.5, 0, size, size, 0.5, 0];
|
rightPageLoc.value = [center + int, 0, size, size, 0.5, 0];
|
||||||
rightLoc.value = [center + size * 3, 0, size, size, 0.5, 0];
|
rightLoc.value = [center + int * 2, 0, size, size, 0.5, 0];
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateArrowPath = () => {
|
const updateArrowPath = () => {
|
||||||
|
@ -361,6 +361,8 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>(
|
|||||||
|
|
||||||
//#region 事件监听
|
//#region 事件监听
|
||||||
|
|
||||||
|
// todo: 滑动操作时的滚动惯性
|
||||||
|
|
||||||
const customPropagate = <T extends ActionType>(
|
const customPropagate = <T extends ActionType>(
|
||||||
type: T,
|
type: T,
|
||||||
progress: EventProgress,
|
progress: EventProgress,
|
||||||
|
@ -130,7 +130,7 @@ export const TextContent = defineComponent<
|
|||||||
let needUpdate = false;
|
let needUpdate = false;
|
||||||
|
|
||||||
const retype = () => {
|
const retype = () => {
|
||||||
if (needUpdate) return;
|
if (needUpdate || props.hidden) return;
|
||||||
needUpdate = true;
|
needUpdate = true;
|
||||||
if (!spriteElement.value) {
|
if (!spriteElement.value) {
|
||||||
needUpdate = false;
|
needUpdate = false;
|
||||||
|
@ -13,6 +13,12 @@ import { RenderableData, texture } from './cache';
|
|||||||
import { BlockCacher, CanvasCacheItem, ICanvasCacheItem } from './block';
|
import { BlockCacher, CanvasCacheItem, ICanvasCacheItem } from './block';
|
||||||
import { IAnimateFrame, renderEmits } from './frame';
|
import { IAnimateFrame, renderEmits } from './frame';
|
||||||
import { EventEmitter } from 'eventemitter3';
|
import { EventEmitter } from 'eventemitter3';
|
||||||
|
import {
|
||||||
|
MAP_BLOCK_HEIGHT,
|
||||||
|
MAP_BLOCK_WIDTH,
|
||||||
|
MAP_HEIGHT,
|
||||||
|
MAP_WIDTH
|
||||||
|
} from '../shared';
|
||||||
|
|
||||||
export interface ILayerGroupRenderExtends {
|
export interface ILayerGroupRenderExtends {
|
||||||
/** 拓展的唯一标识符 */
|
/** 拓展的唯一标识符 */
|
||||||
@ -104,7 +110,7 @@ export class LayerGroup
|
|||||||
// static list: Set<LayerGroup> = new Set();
|
// static list: Set<LayerGroup> = new Set();
|
||||||
|
|
||||||
cellSize: number = 32;
|
cellSize: number = 32;
|
||||||
blockSize: number = core._WIDTH_;
|
blockSize: number = MAP_BLOCK_WIDTH;
|
||||||
|
|
||||||
/** 当前楼层 */
|
/** 当前楼层 */
|
||||||
floorId?: FloorIds;
|
floorId?: FloorIds;
|
||||||
@ -126,7 +132,7 @@ export class LayerGroup
|
|||||||
|
|
||||||
this.setHD(true);
|
this.setHD(true);
|
||||||
this.setAntiAliasing(false);
|
this.setAntiAliasing(false);
|
||||||
this.size(core._PX_, core._PY_);
|
this.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
|
|
||||||
this.on('afterRender', () => {
|
this.on('afterRender', () => {
|
||||||
this.releaseNeedRender();
|
this.releaseNeedRender();
|
||||||
@ -378,8 +384,8 @@ export function calNeedRenderOf(
|
|||||||
cell: number,
|
cell: number,
|
||||||
block: BlockCacher<any>
|
block: BlockCacher<any>
|
||||||
): Set<number> {
|
): Set<number> {
|
||||||
const w = core._WIDTH_ * cell;
|
const w = MAP_BLOCK_WIDTH * cell;
|
||||||
const h = core._HEIGHT_ * cell;
|
const h = MAP_BLOCK_HEIGHT * cell;
|
||||||
const size = block.blockSize;
|
const size = block.blockSize;
|
||||||
const width = block.blockData.width;
|
const width = block.blockData.width;
|
||||||
|
|
||||||
@ -604,7 +610,7 @@ export class Layer extends Container<ELayerEvent> {
|
|||||||
block: BlockCacher<ICanvasCacheItem> = new BlockCacher(
|
block: BlockCacher<ICanvasCacheItem> = new BlockCacher(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
core._WIDTH_,
|
MAP_BLOCK_WIDTH,
|
||||||
4
|
4
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -625,20 +631,20 @@ export class Layer extends Container<ELayerEvent> {
|
|||||||
|
|
||||||
// this.setHD(false);
|
// this.setHD(false);
|
||||||
this.setAntiAliasing(false);
|
this.setAntiAliasing(false);
|
||||||
this.size(core._PX_, core._PY_);
|
this.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
|
|
||||||
this.staticMap.setHD(false);
|
this.staticMap.setHD(false);
|
||||||
this.staticMap.setAntiAliasing(false);
|
this.staticMap.setAntiAliasing(false);
|
||||||
this.staticMap.size(core._PX_, core._PY_);
|
this.staticMap.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
this.movingMap.setHD(false);
|
this.movingMap.setHD(false);
|
||||||
this.movingMap.setAntiAliasing(false);
|
this.movingMap.setAntiAliasing(false);
|
||||||
this.movingMap.size(core._PX_, core._PY_);
|
this.movingMap.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
this.backMap.setHD(false);
|
this.backMap.setHD(false);
|
||||||
this.backMap.setAntiAliasing(false);
|
this.backMap.setAntiAliasing(false);
|
||||||
this.backMap.size(core._PX_, core._PY_);
|
this.backMap.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
this.main.setAntiAliasing(false);
|
this.main.setAntiAliasing(false);
|
||||||
this.main.setHD(false);
|
this.main.setHD(false);
|
||||||
this.main.size(core._PX_, core._PY_);
|
this.main.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
|
|
||||||
this.appendChild(this.main);
|
this.appendChild(this.main);
|
||||||
this.main.setRenderFn((canvas, transform) => {
|
this.main.setRenderFn((canvas, transform) => {
|
||||||
@ -789,7 +795,7 @@ export class Layer extends Container<ELayerEvent> {
|
|||||||
const [sx, sy, w, h] = data.render[i];
|
const [sx, sy, w, h] = data.render[i];
|
||||||
canvas.setHD(false);
|
canvas.setHD(false);
|
||||||
canvas.setAntiAliasing(false);
|
canvas.setAntiAliasing(false);
|
||||||
canvas.size(core._PX_, core._PY_);
|
canvas.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
temp.size(w, h);
|
temp.size(w, h);
|
||||||
|
|
||||||
const img = data.autotile ? data.image[0b11111111] : data.image;
|
const img = data.autotile ? data.image[0b11111111] : data.image;
|
||||||
@ -1204,7 +1210,7 @@ export class Layer extends Container<ELayerEvent> {
|
|||||||
const temp = this.requireCanvas(true, false);
|
const temp = this.requireCanvas(true, false);
|
||||||
temp.setAntiAliasing(false);
|
temp.setAntiAliasing(false);
|
||||||
temp.setHD(false);
|
temp.setHD(false);
|
||||||
temp.size(core._PX_, core._PY_);
|
temp.size(MAP_WIDTH, MAP_HEIGHT);
|
||||||
|
|
||||||
// 先画到临时画布,用于缓存
|
// 先画到临时画布,用于缓存
|
||||||
for (let nx = sx; nx < ex; nx++) {
|
for (let nx = sx; nx < ex; nx++) {
|
||||||
@ -1261,7 +1267,7 @@ export class Layer extends Container<ELayerEvent> {
|
|||||||
const [a, b, , c, d, , e, f] = mat;
|
const [a, b, , c, d, , e, f] = mat;
|
||||||
ctx.setTransform(a, b, c, d, e, f);
|
ctx.setTransform(a, b, c, d, e, f);
|
||||||
const max1 = 1 / Math.min(a, b, c, d) ** 2;
|
const max1 = 1 / Math.min(a, b, c, d) ** 2;
|
||||||
const max2 = Math.max(core._PX_, core._PY_) * 2;
|
const max2 = Math.max(MAP_WIDTH, MAP_HEIGHT) * 2;
|
||||||
const r = (max1 * max2) ** 2;
|
const r = (max1 * max2) ** 2;
|
||||||
|
|
||||||
this.movingRenderable.forEach(v => {
|
this.movingRenderable.forEach(v => {
|
||||||
|
@ -1,21 +1,99 @@
|
|||||||
// 地图格子宽高,此处仅影响画面,不影响游戏内逻辑,游戏内逻辑地图大小请在 core.js 中修改
|
import { ElementLocator } from '@motajs/render-core';
|
||||||
export const MAP_BLOCK_WIDTH = 15;
|
|
||||||
export const MAP_BLOCK_HEIGHT = 15;
|
|
||||||
|
|
||||||
// 地图像素宽高
|
// 本文件为 UI 配置文件,你可以修改下面的每个常量来控制 UI 的显示参数,每个常量都有注释说明
|
||||||
export const MAP_WIDTH = 32 * MAP_BLOCK_WIDTH;
|
|
||||||
export const MAP_HEIGHT = 32 * MAP_BLOCK_HEIGHT;
|
|
||||||
|
|
||||||
// 状态栏像素宽高
|
//#region 地图
|
||||||
|
|
||||||
|
/** 每个格子的宽高 */
|
||||||
|
export const CELL_SIZE = 32;
|
||||||
|
/** 地图格子宽度,此处仅影响画面,不影响游戏内逻辑,游戏内逻辑地图大小请在 core.js 中修改 */
|
||||||
|
export const MAP_BLOCK_WIDTH = 13;
|
||||||
|
/** 地图格子高度,此处仅影响画面,不影响游戏内逻辑,游戏内逻辑地图大小请在 core.js 中修改 */
|
||||||
|
export const MAP_BLOCK_HEIGHT = 13;
|
||||||
|
/** 地图像素宽度 */
|
||||||
|
export const MAP_WIDTH = CELL_SIZE * MAP_BLOCK_WIDTH;
|
||||||
|
/** 地图像素高度 */
|
||||||
|
export const MAP_HEIGHT = CELL_SIZE * MAP_BLOCK_HEIGHT;
|
||||||
|
|
||||||
|
//#region 状态栏
|
||||||
|
|
||||||
|
/** 状态栏像素宽度 */
|
||||||
export const STATUS_BAR_WIDTH = 180;
|
export const STATUS_BAR_WIDTH = 180;
|
||||||
|
/** 状态栏像素高度 */
|
||||||
export const STATUS_BAR_HEIGHT = 32 * MAP_BLOCK_HEIGHT;
|
export const STATUS_BAR_HEIGHT = 32 * MAP_BLOCK_HEIGHT;
|
||||||
// 右侧状态栏的横坐标
|
/** 右侧状态栏的横坐标 */
|
||||||
export const RIGHT_STATUS_POS = STATUS_BAR_WIDTH + MAP_WIDTH;
|
export const RIGHT_STATUS_POS = STATUS_BAR_WIDTH + MAP_WIDTH;
|
||||||
|
/** 是否启用右侧状态栏 */
|
||||||
// 是否启用右侧状态栏
|
|
||||||
export const ENABLE_RIGHT_STATUS_BAR = true;
|
export const ENABLE_RIGHT_STATUS_BAR = true;
|
||||||
|
/** 状态栏数量,启用右侧状态栏为两个,不启用为一个 */
|
||||||
export const STATUS_BAR_COUNT = ENABLE_RIGHT_STATUS_BAR ? 2 : 1;
|
export const STATUS_BAR_COUNT = ENABLE_RIGHT_STATUS_BAR ? 2 : 1;
|
||||||
|
/** 状态栏宽度的一半 */
|
||||||
|
export const HALF_STATUS_WIDTH = STATUS_BAR_WIDTH / 2;
|
||||||
|
|
||||||
// 游戏画面像素宽高,宽=地图宽度+状态栏宽度*状态栏数量
|
//#region 游戏画面
|
||||||
|
|
||||||
|
/** 游戏画面像素宽度,宽=地图宽度+状态栏宽度*状态栏数量 */
|
||||||
export const MAIN_WIDTH = MAP_WIDTH + STATUS_BAR_WIDTH * STATUS_BAR_COUNT;
|
export const MAIN_WIDTH = MAP_WIDTH + STATUS_BAR_WIDTH * STATUS_BAR_COUNT;
|
||||||
|
/** 游戏画面像素高度 */
|
||||||
export const MAIN_HEIGHT = MAP_HEIGHT;
|
export const MAIN_HEIGHT = MAP_HEIGHT;
|
||||||
|
/** 游戏画面宽度的一半 */
|
||||||
|
export const HALF_WIDTH = MAIN_WIDTH / 2;
|
||||||
|
/** 游戏画面高度的一半 */
|
||||||
|
export const HALF_HEIGHT = MAIN_HEIGHT / 2;
|
||||||
|
/** 全屏显示的 loc */
|
||||||
|
export const FULL_LOC: ElementLocator = [0, 0, MAIN_WIDTH, MAIN_HEIGHT];
|
||||||
|
/** 居中显示的 loc */
|
||||||
|
export const CENTER_LOC: ElementLocator = [
|
||||||
|
HALF_WIDTH,
|
||||||
|
HALF_HEIGHT,
|
||||||
|
void 0,
|
||||||
|
void 0,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
];
|
||||||
|
|
||||||
|
//#region 通用配置
|
||||||
|
|
||||||
|
/** 弹框的宽度,使用在内置 UI 与组件中,包括确认框、选择框、等待框等 */
|
||||||
|
export const POP_BOX_WIDTH = MAP_WIDTH / 2;
|
||||||
|
|
||||||
|
//#region 存档界面
|
||||||
|
|
||||||
|
/** 存档缩略图尺寸 */
|
||||||
|
export const SAVE_ITEM_SIZE = 150;
|
||||||
|
/** 单个存档上方显示第几号存档的高度 */
|
||||||
|
export const SAVE_ITEM_TOP = 24;
|
||||||
|
/** 单个存档下方显示这个存档信息的高度 */
|
||||||
|
export const SAVE_ITEM_DOWN = 16;
|
||||||
|
/** 单个存档高度,包括存档下方的信息 */
|
||||||
|
export const SAVE_ITEM_HEIGHT = SAVE_ITEM_SIZE + SAVE_ITEM_TOP + SAVE_ITEM_DOWN;
|
||||||
|
/** 存档间距 */
|
||||||
|
export const SAVE_INTERVAL = 30;
|
||||||
|
/** 存档下巴高度,即下方显示页码和返回按钮的高度 */
|
||||||
|
export const SAVE_DOWN_PAD = 30;
|
||||||
|
/** 存档页码数,调高并不会影响性能,但是如果玩家存档太多的话会导致存档体积很大 */
|
||||||
|
export const SAVE_PAGES = 1000;
|
||||||
|
|
||||||
|
//#region 标题界面
|
||||||
|
|
||||||
|
/** 标题文字宽度 */
|
||||||
|
export const TITLE_WIDTH = 640;
|
||||||
|
/** 标题文字高度 */
|
||||||
|
export const TITLE_HEIGHT = 100;
|
||||||
|
/** 标题文字宽度的一半 */
|
||||||
|
export const HALF_TITLE_WIDTH = TITLE_WIDTH / 2;
|
||||||
|
/** 标题文字高度的一半 */
|
||||||
|
export const HALF_TITLE_HEIGHT = TITLE_HEIGHT / 2;
|
||||||
|
/** 标题文字中心横坐标 */
|
||||||
|
export const TITLE_X = HALF_WIDTH;
|
||||||
|
/** 标题文字中心纵坐标 */
|
||||||
|
export const TITLE_Y = 120;
|
||||||
|
|
||||||
|
/** 标题界面按钮宽度,如果文字被裁剪可以考虑扩大此值 */
|
||||||
|
export const BUTTONS_WIDTH = 200;
|
||||||
|
/** 标题界面按钮高度,如果文字被裁剪可以考虑扩大此值 */
|
||||||
|
export const BUTTONS_HEIGHT = 160;
|
||||||
|
/** 标题界面按钮左上角横坐标 */
|
||||||
|
export const BUTTONS_X = 50;
|
||||||
|
/** 标题界面按钮左上角纵坐标 */
|
||||||
|
export const BUTTONS_Y = MAIN_HEIGHT - BUTTONS_HEIGHT;
|
||||||
|
@ -16,7 +16,19 @@ import {
|
|||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { getConfirm, Page, PageExpose, Thumbnail } from '../components';
|
import { getConfirm, Page, PageExpose, Thumbnail } from '../components';
|
||||||
import { useKey } from '../use';
|
import { useKey } from '../use';
|
||||||
import { MAP_WIDTH } from '../shared';
|
import {
|
||||||
|
HALF_HEIGHT,
|
||||||
|
HALF_WIDTH,
|
||||||
|
MAP_WIDTH,
|
||||||
|
POP_BOX_WIDTH,
|
||||||
|
SAVE_DOWN_PAD,
|
||||||
|
SAVE_INTERVAL,
|
||||||
|
SAVE_ITEM_DOWN,
|
||||||
|
SAVE_ITEM_HEIGHT,
|
||||||
|
SAVE_ITEM_SIZE,
|
||||||
|
SAVE_ITEM_TOP,
|
||||||
|
SAVE_PAGES
|
||||||
|
} from '../shared';
|
||||||
import { getSave, SaveData, adjustGrid, IGridLayoutData } from '../utils';
|
import { getSave, SaveData, adjustGrid, IGridLayoutData } from '../utils';
|
||||||
|
|
||||||
export const enum SaveMode {
|
export const enum SaveMode {
|
||||||
@ -61,10 +73,11 @@ export const SaveItem = defineComponent<SaveItemProps>(props => {
|
|||||||
const statusFont = new Font('normal', 14);
|
const statusFont = new Font('normal', 14);
|
||||||
|
|
||||||
const w = computed(() => props.loc[2] ?? 200);
|
const w = computed(() => props.loc[2] ?? 200);
|
||||||
|
const h = computed(() => props.loc[3] ?? 200);
|
||||||
const lineWidth = computed(() => (props.selected ? 4 : 2));
|
const lineWidth = computed(() => (props.selected ? 4 : 2));
|
||||||
const imgLoc = computed<ElementLocator>(() => {
|
const imgLoc = computed<ElementLocator>(() => {
|
||||||
const size = w.value - 4;
|
const size = w.value - 4;
|
||||||
return [2, 24, size, size];
|
return [2, SAVE_ITEM_TOP, size, size];
|
||||||
});
|
});
|
||||||
|
|
||||||
const name = computed(() => {
|
const name = computed(() => {
|
||||||
@ -102,7 +115,7 @@ export const SaveItem = defineComponent<SaveItemProps>(props => {
|
|||||||
<text
|
<text
|
||||||
text={name.value}
|
text={name.value}
|
||||||
font={font}
|
font={font}
|
||||||
loc={[w.value / 2, 20]}
|
loc={[w.value / 2, SAVE_ITEM_TOP - 4]}
|
||||||
anc={[0.5, 1]}
|
anc={[0.5, 1]}
|
||||||
/>
|
/>
|
||||||
<g-rect
|
<g-rect
|
||||||
@ -130,7 +143,7 @@ export const SaveItem = defineComponent<SaveItemProps>(props => {
|
|||||||
text={statusText.value}
|
text={statusText.value}
|
||||||
fillStyle="yellow"
|
fillStyle="yellow"
|
||||||
font={statusFont}
|
font={statusFont}
|
||||||
loc={[w.value / 2, w.value + 28]}
|
loc={[w.value / 2, h.value - SAVE_ITEM_DOWN + 2]}
|
||||||
anc={[0.5, 0]}
|
anc={[0.5, 0]}
|
||||||
/>
|
/>
|
||||||
</container>
|
</container>
|
||||||
@ -139,12 +152,8 @@ export const SaveItem = defineComponent<SaveItemProps>(props => {
|
|||||||
|
|
||||||
export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||||
(props, { emit }) => {
|
(props, { emit }) => {
|
||||||
const itemSize = 150;
|
const font = Font.defaults({ size: 18 });
|
||||||
const itemHeight = itemSize + 40;
|
const pageFont = Font.defaults({ size: 14 });
|
||||||
const interval = 30;
|
|
||||||
|
|
||||||
const font = new Font('normal', 18);
|
|
||||||
const pageFont = new Font('normal', 14);
|
|
||||||
|
|
||||||
/** 当前页上被选中的存档的posIndex */
|
/** 当前页上被选中的存档的posIndex */
|
||||||
const selected = ref(0);
|
const selected = ref(0);
|
||||||
@ -160,16 +169,16 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
const grid = computed<IGridLayoutData>(() =>
|
const grid = computed<IGridLayoutData>(() =>
|
||||||
adjustGrid(
|
adjustGrid(
|
||||||
width.value,
|
width.value,
|
||||||
height.value - 30,
|
height.value - SAVE_DOWN_PAD,
|
||||||
itemSize,
|
SAVE_ITEM_SIZE,
|
||||||
itemHeight,
|
SAVE_ITEM_HEIGHT,
|
||||||
interval
|
SAVE_INTERVAL
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentLoc = computed<ElementLocator>(() => {
|
const contentLoc = computed<ElementLocator>(() => {
|
||||||
const cx = width.value / 2;
|
const cx = width.value / 2;
|
||||||
const cy = (height.value - 30) / 2;
|
const cy = (height.value - SAVE_DOWN_PAD) / 2;
|
||||||
return [cx, cy, grid.value.width, grid.value.height, 0.5, 0.5];
|
return [cx, cy, grid.value.width, grid.value.height, 0.5, 0.5];
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -244,8 +253,8 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
`确认要删除存档 ${index + 1}?`,
|
`确认要删除存档 ${index + 1}?`,
|
||||||
[420, 240, void 0, void 0, 0.5, 0.5],
|
[HALF_WIDTH, HALF_HEIGHT, void 0, void 0, 0.5, 0.5],
|
||||||
240,
|
POP_BOX_WIDTH,
|
||||||
{ winskin: 'winskin2.png' }
|
{ winskin: 'winskin2.png' }
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
@ -370,6 +379,9 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
//#region 事件监听
|
//#region 事件监听
|
||||||
|
|
||||||
|
// todo: 按住快速切换页码
|
||||||
|
|
||||||
const wheel = (ev: IWheelEvent) => {
|
const wheel = (ev: IWheelEvent) => {
|
||||||
const delta = Math.sign(ev.wheelY);
|
const delta = Math.sign(ev.wheelY);
|
||||||
if (ev.ctrlKey) {
|
if (ev.ctrlKey) {
|
||||||
@ -384,7 +396,7 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
<Page
|
<Page
|
||||||
ref={pageRef}
|
ref={pageRef}
|
||||||
loc={[0, 0, width.value, height.value - 10]}
|
loc={[0, 0, width.value, height.value - 10]}
|
||||||
pages={1000}
|
pages={SAVE_PAGES}
|
||||||
font={pageFont}
|
font={pageFont}
|
||||||
v-model:page={now.value}
|
v-model:page={now.value}
|
||||||
onWheel={wheel}
|
onWheel={wheel}
|
||||||
|
@ -24,6 +24,8 @@ import { openStatistics } from './statistics';
|
|||||||
import { saveWithExist } from './save';
|
import { saveWithExist } from './save';
|
||||||
import { compressToBase64 } from 'lz-string';
|
import { compressToBase64 } from 'lz-string';
|
||||||
import { ViewMapUI } from './viewmap';
|
import { ViewMapUI } from './viewmap';
|
||||||
|
import { CENTER_LOC, FULL_LOC, MAIN_HEIGHT, POP_BOX_WIDTH } from '../shared';
|
||||||
|
import { useKey } from '../use';
|
||||||
|
|
||||||
export interface MainSettingsProps
|
export interface MainSettingsProps
|
||||||
extends Partial<ChoicesProps>,
|
extends Partial<ChoicesProps>,
|
||||||
@ -61,6 +63,9 @@ export const MainSettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
[MainChoice.Back, '返回游戏']
|
[MainChoice.Back, '返回游戏']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const [key, scope] = useKey();
|
||||||
|
key.realize('exit', () => props.controller.close(props.instance));
|
||||||
|
|
||||||
const choose = async (key: ChoiceKey) => {
|
const choose = async (key: ChoiceKey) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case MainChoice.SystemSetting: {
|
case MainChoice.SystemSetting: {
|
||||||
@ -79,7 +84,9 @@ export const MainSettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MainChoice.ViewMap: {
|
case MainChoice.ViewMap: {
|
||||||
props.controller.open(ViewMapUI, { loc: [0, 0, 840, 840] });
|
props.controller.open(ViewMapUI, {
|
||||||
|
loc: FULL_LOC
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MainChoice.Replay: {
|
case MainChoice.Replay: {
|
||||||
@ -98,8 +105,8 @@ export const MainSettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'确认要返回标题吗?',
|
'确认要返回标题吗?',
|
||||||
[420, 240, void 0, void 0, 0.5, 0.5],
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
props.controller.closeAll();
|
props.controller.closeAll();
|
||||||
@ -118,10 +125,11 @@ export const MainSettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
<Choices
|
<Choices
|
||||||
loc={props.loc}
|
loc={props.loc}
|
||||||
choices={choices}
|
choices={choices}
|
||||||
width={240}
|
width={POP_BOX_WIDTH}
|
||||||
onChoose={choose}
|
onChoose={choose}
|
||||||
maxHeight={400}
|
maxHeight={MAIN_HEIGHT - 64}
|
||||||
interval={8}
|
interval={8}
|
||||||
|
scope={scope}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, mainSettingsProps);
|
}, mainSettingsProps);
|
||||||
@ -147,6 +155,9 @@ export const ReplaySettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
[ReplayChoice.Back, '返回游戏']
|
[ReplayChoice.Back, '返回游戏']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const [key, scope] = useKey();
|
||||||
|
key.realize('exit', () => props.controller.close(props.instance));
|
||||||
|
|
||||||
const choose = async (key: ChoiceKey) => {
|
const choose = async (key: ChoiceKey) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case ReplayChoice.Start: {
|
case ReplayChoice.Start: {
|
||||||
@ -158,10 +169,7 @@ export const ReplaySettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ReplayChoice.StartFromSave: {
|
case ReplayChoice.StartFromSave: {
|
||||||
const index = await saveWithExist(
|
const index = await saveWithExist(props.controller, FULL_LOC);
|
||||||
props.controller,
|
|
||||||
[0, 0, 840, 480]
|
|
||||||
);
|
|
||||||
if (index === -2) break;
|
if (index === -2) break;
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
core.doSL('autoSave', 'replayLoad');
|
core.doSL('autoSave', 'replayLoad');
|
||||||
@ -172,10 +180,7 @@ export const ReplaySettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ReplayChoice.ResumeReplay: {
|
case ReplayChoice.ResumeReplay: {
|
||||||
const index = await saveWithExist(
|
const index = await saveWithExist(props.controller, FULL_LOC);
|
||||||
props.controller,
|
|
||||||
[0, 0, 840, 480]
|
|
||||||
);
|
|
||||||
if (index === -2) break;
|
if (index === -2) break;
|
||||||
const name = index === -1 ? 'autoSave' : index + 1;
|
const name = index === -1 ? 'autoSave' : index + 1;
|
||||||
const success = core.doSL(name, 'replayRemain');
|
const success = core.doSL(name, 'replayRemain');
|
||||||
@ -185,14 +190,11 @@ export const ReplaySettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
}
|
}
|
||||||
await getConfirm(
|
await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'[步骤2]请选择第二个存档。\n\r[yellow]该存档必须是前一个存档的后续。\r\n将尝试播放到此存档。',
|
'[步骤2]请选择第二个存档。\n\\r[yellow]该存档必须是前一个存档的后续。\\r\n将尝试播放到此存档。',
|
||||||
[420, 240, void 0, void 0, 0.5, 0.5],
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
|
||||||
const index2 = await saveWithExist(
|
|
||||||
props.controller,
|
|
||||||
[0, 0, 840, 480]
|
|
||||||
);
|
);
|
||||||
|
const index2 = await saveWithExist(props.controller, FULL_LOC);
|
||||||
if (index2 === -2) break;
|
if (index2 === -2) break;
|
||||||
const name2 = index2 === -1 ? 'autoSave' : index2 + 1;
|
const name2 = index2 === -1 ? 'autoSave' : index2 + 1;
|
||||||
core.doSL(name2, 'replayRemain');
|
core.doSL(name2, 'replayRemain');
|
||||||
@ -200,10 +202,7 @@ export const ReplaySettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ReplayChoice.ReplayRest: {
|
case ReplayChoice.ReplayRest: {
|
||||||
const index = await saveWithExist(
|
const index = await saveWithExist(props.controller, FULL_LOC);
|
||||||
props.controller,
|
|
||||||
[0, 0, 840, 480]
|
|
||||||
);
|
|
||||||
if (index === -2) break;
|
if (index === -2) break;
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
core.doSL('autoSave', 'replaySince');
|
core.doSL('autoSave', 'replaySince');
|
||||||
@ -243,9 +242,10 @@ export const ReplaySettings = defineComponent<MainSettingsProps>(props => {
|
|||||||
<Choices
|
<Choices
|
||||||
loc={props.loc}
|
loc={props.loc}
|
||||||
choices={choice}
|
choices={choice}
|
||||||
width={240}
|
width={POP_BOX_WIDTH}
|
||||||
onChoose={choose}
|
onChoose={choose}
|
||||||
interval={8}
|
interval={8}
|
||||||
|
scope={scope}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, mainSettingsProps);
|
}, mainSettingsProps);
|
||||||
@ -269,6 +269,9 @@ export const GameInfo = defineComponent<MainSettingsProps>(props => {
|
|||||||
[GameInfoChoice.Back, '返回主菜单']
|
[GameInfoChoice.Back, '返回主菜单']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const [key, scope] = useKey();
|
||||||
|
key.realize('exit', () => props.controller.close(props.instance));
|
||||||
|
|
||||||
const choose = async (key: ChoiceKey) => {
|
const choose = async (key: ChoiceKey) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case GameInfoChoice.Statistics: {
|
case GameInfoChoice.Statistics: {
|
||||||
@ -281,8 +284,8 @@ export const GameInfo = defineComponent<MainSettingsProps>(props => {
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'即将离开本游戏,跳转至工程页面,确认跳转?',
|
'即将离开本游戏,跳转至工程页面,确认跳转?',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
window.location.href = 'editor-mobile.html';
|
window.location.href = 'editor-mobile.html';
|
||||||
@ -299,8 +302,8 @@ export const GameInfo = defineComponent<MainSettingsProps>(props => {
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'即将离开本游戏,跳转至评论页面,确认跳转?',
|
'即将离开本游戏,跳转至评论页面,确认跳转?',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
window.location.href = href;
|
window.location.href = href;
|
||||||
@ -330,9 +333,10 @@ export const GameInfo = defineComponent<MainSettingsProps>(props => {
|
|||||||
<Choices
|
<Choices
|
||||||
loc={props.loc}
|
loc={props.loc}
|
||||||
choices={choices}
|
choices={choices}
|
||||||
width={240}
|
width={POP_BOX_WIDTH}
|
||||||
onChoose={choose}
|
onChoose={choose}
|
||||||
interval={8}
|
interval={8}
|
||||||
|
scope={scope}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, mainSettingsProps);
|
}, mainSettingsProps);
|
||||||
@ -360,6 +364,9 @@ export const SyncSave = defineComponent<MainSettingsProps>(props => {
|
|||||||
[SyncSaveChoice.Back, '返回上一级']
|
[SyncSaveChoice.Back, '返回上一级']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const [key, scope] = useKey();
|
||||||
|
key.realize('exit', () => props.controller.close(props.instance));
|
||||||
|
|
||||||
const choose = async (key: ChoiceKey) => {
|
const choose = async (key: ChoiceKey) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case SyncSaveChoice.ToServer: {
|
case SyncSaveChoice.ToServer: {
|
||||||
@ -370,8 +377,8 @@ export const SyncSave = defineComponent<MainSettingsProps>(props => {
|
|||||||
const replay = await getInput(
|
const replay = await getInput(
|
||||||
props.controller,
|
props.controller,
|
||||||
'请输入存档编号+密码',
|
'请输入存档编号+密码',
|
||||||
[240, 240, void 0, void 0, 0.5, 0.5],
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
await syncFromServer(props.controller, replay);
|
await syncFromServer(props.controller, replay);
|
||||||
break;
|
break;
|
||||||
@ -398,10 +405,11 @@ export const SyncSave = defineComponent<MainSettingsProps>(props => {
|
|||||||
return () => (
|
return () => (
|
||||||
<Choices
|
<Choices
|
||||||
loc={props.loc}
|
loc={props.loc}
|
||||||
width={240}
|
width={POP_BOX_WIDTH}
|
||||||
choices={choices}
|
choices={choices}
|
||||||
onChoose={choose}
|
onChoose={choose}
|
||||||
interval={8}
|
interval={8}
|
||||||
|
scope={scope}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, mainSettingsProps);
|
}, mainSettingsProps);
|
||||||
@ -413,6 +421,9 @@ export const SyncSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
[SyncSaveChoice.Back, '返回上一级']
|
[SyncSaveChoice.Back, '返回上一级']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const [key, scope] = useKey();
|
||||||
|
key.realize('exit', () => props.controller.close(props.instance));
|
||||||
|
|
||||||
const choose = async (key: ChoiceKey) => {
|
const choose = async (key: ChoiceKey) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case SyncSaveChoice.AllSaves: {
|
case SyncSaveChoice.AllSaves: {
|
||||||
@ -420,8 +431,8 @@ export const SyncSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'你确定要同步全部存档么?这可能在存档较多的时候比较慢。',
|
'你确定要同步全部存档么?这可能在存档较多的时候比较慢。',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
core.syncSave('all');
|
core.syncSave('all');
|
||||||
@ -433,8 +444,8 @@ export const SyncSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'确定要同步当前存档吗?',
|
'确定要同步当前存档吗?',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
core.syncSave();
|
core.syncSave();
|
||||||
@ -451,10 +462,11 @@ export const SyncSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
return () => (
|
return () => (
|
||||||
<Choices
|
<Choices
|
||||||
loc={props.loc}
|
loc={props.loc}
|
||||||
width={240}
|
width={POP_BOX_WIDTH}
|
||||||
choices={choices}
|
choices={choices}
|
||||||
onChoose={choose}
|
onChoose={choose}
|
||||||
interval={8}
|
interval={8}
|
||||||
|
scope={scope}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, mainSettingsProps);
|
}, mainSettingsProps);
|
||||||
@ -466,20 +478,23 @@ export const DownloadSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
[SyncSaveChoice.Back, '返回上一级']
|
[SyncSaveChoice.Back, '返回上一级']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const [key, scope] = useKey();
|
||||||
|
key.realize('exit', () => props.controller.close(props.instance));
|
||||||
|
|
||||||
const choose = async (key: ChoiceKey) => {
|
const choose = async (key: ChoiceKey) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case SyncSaveChoice.AllSaves: {
|
case SyncSaveChoice.AllSaves: {
|
||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'确认要下载所有存档吗?',
|
'确认要下载所有存档吗?',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
const data = await waitbox(
|
const data = await waitbox(
|
||||||
props.controller,
|
props.controller,
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240,
|
POP_BOX_WIDTH,
|
||||||
getAllSavesData(),
|
getAllSavesData(),
|
||||||
{ text: '请等待处理完毕' }
|
{ text: '请等待处理完毕' }
|
||||||
);
|
);
|
||||||
@ -496,8 +511,8 @@ export const DownloadSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'确认要下载当前存档吗?',
|
'确认要下载当前存档吗?',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
const data = await getSaveData(core.saves.saveIndex);
|
const data = await getSaveData(core.saves.saveIndex);
|
||||||
@ -520,10 +535,11 @@ export const DownloadSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
return () => (
|
return () => (
|
||||||
<Choices
|
<Choices
|
||||||
loc={props.loc}
|
loc={props.loc}
|
||||||
width={240}
|
width={POP_BOX_WIDTH}
|
||||||
choices={choices}
|
choices={choices}
|
||||||
onChoose={choose}
|
onChoose={choose}
|
||||||
interval={8}
|
interval={8}
|
||||||
|
scope={scope}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, mainSettingsProps);
|
}, mainSettingsProps);
|
||||||
@ -535,20 +551,23 @@ export const ClearSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
[SyncSaveChoice.Back, '返回上一级']
|
[SyncSaveChoice.Back, '返回上一级']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const [key, scope] = useKey();
|
||||||
|
key.realize('exit', () => props.controller.close(props.instance));
|
||||||
|
|
||||||
const choose = async (key: ChoiceKey) => {
|
const choose = async (key: ChoiceKey) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case SyncSaveChoice.AllSaves: {
|
case SyncSaveChoice.AllSaves: {
|
||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'你确定要清除【全部游戏】的所有本地存档?此行为不可逆!!!',
|
'你确定要清除【全部游戏】的所有本地存档?此行为不可逆!!!',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
await waitbox(
|
await waitbox(
|
||||||
props.controller,
|
props.controller,
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240,
|
POP_BOX_WIDTH,
|
||||||
new Promise<void>(res => {
|
new Promise<void>(res => {
|
||||||
core.clearLocalForage(() => {
|
core.clearLocalForage(() => {
|
||||||
core.saves.ids = {};
|
core.saves.ids = {};
|
||||||
@ -571,8 +590,8 @@ export const ClearSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
await getConfirm(
|
await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'所有塔的存档已经全部清空',
|
'所有塔的存档已经全部清空',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -581,14 +600,14 @@ export const ClearSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
const confirm = await getConfirm(
|
const confirm = await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'你确定要清除【当前游戏】的所有本地存档?此行为不可逆!!!',
|
'你确定要清除【当前游戏】的所有本地存档?此行为不可逆!!!',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
await waitbox(
|
await waitbox(
|
||||||
props.controller,
|
props.controller,
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240,
|
POP_BOX_WIDTH,
|
||||||
new Promise<void>(res => {
|
new Promise<void>(res => {
|
||||||
Object.keys(core.saves.ids).forEach(function (v) {
|
Object.keys(core.saves.ids).forEach(function (v) {
|
||||||
core.removeLocalForage('save' + v);
|
core.removeLocalForage('save' + v);
|
||||||
@ -613,8 +632,8 @@ export const ClearSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
await getConfirm(
|
await getConfirm(
|
||||||
props.controller,
|
props.controller,
|
||||||
'当前塔的存档已被清空',
|
'当前塔的存档已被清空',
|
||||||
props.loc,
|
CENTER_LOC,
|
||||||
240
|
POP_BOX_WIDTH
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -633,6 +652,7 @@ export const ClearSaveSelect = defineComponent<MainSettingsProps>(props => {
|
|||||||
choices={choices}
|
choices={choices}
|
||||||
onChoose={choose}
|
onChoose={choose}
|
||||||
interval={8}
|
interval={8}
|
||||||
|
scope={scope}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, mainSettingsProps);
|
}, mainSettingsProps);
|
||||||
|
@ -91,9 +91,9 @@ export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>(
|
|||||||
return num.toString().padStart(2, '0');
|
return num.toString().padStart(2, '0');
|
||||||
};
|
};
|
||||||
|
|
||||||
const font1 = new Font('normal', 18);
|
const font1 = Font.defaults({ size: 18 });
|
||||||
const font2 = new Font('normal', 18, 'px', 700);
|
const font2 = Font.defaults({ size: 18, weight: 700 });
|
||||||
const font3 = new Font('normal', 14, 'px', 700);
|
const font3 = Font.defaults({ size: 14, weight: 700 });
|
||||||
|
|
||||||
const iconLoc = (n: number): ElementLocator => {
|
const iconLoc = (n: number): ElementLocator => {
|
||||||
return [16, 76 + 44 * n, 32, 32];
|
return [16, 76 + 44 * n, 32, 32];
|
||||||
|
@ -5,7 +5,22 @@ import {
|
|||||||
UIComponentProps
|
UIComponentProps
|
||||||
} from '@motajs/system-ui';
|
} from '@motajs/system-ui';
|
||||||
import { defineComponent, nextTick, onMounted, ref } from 'vue';
|
import { defineComponent, nextTick, onMounted, ref } from 'vue';
|
||||||
import { MAIN_HEIGHT, MAIN_WIDTH } from '../shared';
|
import {
|
||||||
|
BUTTONS_HEIGHT,
|
||||||
|
BUTTONS_WIDTH,
|
||||||
|
BUTTONS_X,
|
||||||
|
BUTTONS_Y,
|
||||||
|
HALF_HEIGHT,
|
||||||
|
HALF_TITLE_HEIGHT,
|
||||||
|
HALF_TITLE_WIDTH,
|
||||||
|
HALF_WIDTH,
|
||||||
|
MAIN_HEIGHT,
|
||||||
|
MAIN_WIDTH,
|
||||||
|
TITLE_HEIGHT,
|
||||||
|
TITLE_WIDTH,
|
||||||
|
TITLE_X,
|
||||||
|
TITLE_Y
|
||||||
|
} from '../shared';
|
||||||
import {
|
import {
|
||||||
ElementLocator,
|
ElementLocator,
|
||||||
IActionEvent,
|
IActionEvent,
|
||||||
@ -147,8 +162,8 @@ export const GameTitle = defineComponent<GameTitleProps>(props => {
|
|||||||
|
|
||||||
let cursorScale = 1;
|
let cursorScale = 1;
|
||||||
|
|
||||||
const titleFont = new Font('normal', 72).string();
|
const titleFont = Font.defaults({ size: 72 });
|
||||||
const buttonFont = new Font('normal', 24, 'px', 600);
|
const buttonFont = Font.defaults({ size: 24, weight: 600 });
|
||||||
|
|
||||||
//#region 按钮功能
|
//#region 按钮功能
|
||||||
|
|
||||||
@ -388,7 +403,7 @@ export const GameTitle = defineComponent<GameTitleProps>(props => {
|
|||||||
}
|
}
|
||||||
ctx.textAlign = 'center';
|
ctx.textAlign = 'center';
|
||||||
ctx.textBaseline = 'middle';
|
ctx.textBaseline = 'middle';
|
||||||
ctx.font = titleFont;
|
ctx.font = titleFont.string();
|
||||||
ctx.fillStyle = titleGradient!;
|
ctx.fillStyle = titleGradient!;
|
||||||
ctx.filter = `
|
ctx.filter = `
|
||||||
drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.5))
|
drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.5))
|
||||||
@ -396,7 +411,7 @@ export const GameTitle = defineComponent<GameTitleProps>(props => {
|
|||||||
drop-shadow(12px 12px 4px rgba(0, 0, 0, 0.4))
|
drop-shadow(12px 12px 4px rgba(0, 0, 0, 0.4))
|
||||||
blur(1px)
|
blur(1px)
|
||||||
`;
|
`;
|
||||||
ctx.fillText(core.firstData.title, 320, 50);
|
ctx.fillText(core.firstData.title, HALF_TITLE_WIDTH, HALF_TITLE_HEIGHT);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderCursor = (canvas: MotaOffscreenCanvas2D) => {
|
const renderCursor = (canvas: MotaOffscreenCanvas2D) => {
|
||||||
@ -420,15 +435,15 @@ export const GameTitle = defineComponent<GameTitleProps>(props => {
|
|||||||
>
|
>
|
||||||
<image
|
<image
|
||||||
image={bg}
|
image={bg}
|
||||||
loc={[MAIN_WIDTH / 2, MAIN_HEIGHT / 2, width, height]}
|
loc={[HALF_WIDTH, HALF_HEIGHT, width, height]}
|
||||||
anc={[0.5, 0.5]}
|
anc={[0.5, 0.5]}
|
||||||
|
filter="brightness(120%)contrast(110%)"
|
||||||
zIndex={0}
|
zIndex={0}
|
||||||
/>
|
/>
|
||||||
<shader
|
<shader
|
||||||
ref={imageShader}
|
ref={imageShader}
|
||||||
zIndex={5}
|
zIndex={5}
|
||||||
loc={[0, 0, MAIN_WIDTH, MAIN_HEIGHT]}
|
loc={[0, 0, MAIN_WIDTH, MAIN_HEIGHT]}
|
||||||
filter="brightness(120%)contrast(110%)"
|
|
||||||
/>
|
/>
|
||||||
<sprite
|
<sprite
|
||||||
ref={maskSprite}
|
ref={maskSprite}
|
||||||
@ -441,17 +456,16 @@ export const GameTitle = defineComponent<GameTitleProps>(props => {
|
|||||||
<sprite
|
<sprite
|
||||||
ref={titleSprite}
|
ref={titleSprite}
|
||||||
render={renderTitle}
|
render={renderTitle}
|
||||||
loc={[MAIN_WIDTH / 2, 120, 640, 100, 0.5, 0.5]}
|
loc={[TITLE_X, TITLE_Y, TITLE_WIDTH, TITLE_HEIGHT, 0.5, 0.5]}
|
||||||
zIndex={10}
|
zIndex={10}
|
||||||
/>
|
/>
|
||||||
<container
|
<container
|
||||||
zIndex={15}
|
zIndex={15}
|
||||||
loc={[50, MAIN_HEIGHT, 200, 160]}
|
loc={[BUTTONS_X, BUTTONS_Y, BUTTONS_WIDTH, BUTTONS_HEIGHT]}
|
||||||
anc={[0, 1]}
|
|
||||||
>
|
>
|
||||||
<container
|
<container
|
||||||
hidden={selectHard.value}
|
hidden={selectHard.value}
|
||||||
loc={[0, 0, 200, 160]}
|
loc={[0, 0, BUTTONS_WIDTH, BUTTONS_HEIGHT]}
|
||||||
alpha={buttonsAlpha.ref.value}
|
alpha={buttonsAlpha.ref.value}
|
||||||
>
|
>
|
||||||
{buttons.map((v, i) => {
|
{buttons.map((v, i) => {
|
||||||
@ -475,7 +489,7 @@ export const GameTitle = defineComponent<GameTitleProps>(props => {
|
|||||||
</container>
|
</container>
|
||||||
<container
|
<container
|
||||||
hidden={!selectHard.value}
|
hidden={!selectHard.value}
|
||||||
loc={[0, 0, 200, 160]}
|
loc={[0, 0, BUTTONS_WIDTH, BUTTONS_HEIGHT]}
|
||||||
alpha={buttonsAlpha.ref.value}
|
alpha={buttonsAlpha.ref.value}
|
||||||
>
|
>
|
||||||
{hard.map((v, i) => {
|
{hard.map((v, i) => {
|
||||||
@ -528,16 +542,15 @@ export const GameTitle = defineComponent<GameTitleProps>(props => {
|
|||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!soundOpened.value && (
|
<g-line
|
||||||
<g-line
|
line={[5, 35, 35, 5]}
|
||||||
line={[5, 35, 35, 5]}
|
strokeStyle="gray"
|
||||||
strokeStyle="gray"
|
lineWidth={3}
|
||||||
lineWidth={3}
|
lineCap="round"
|
||||||
lineCap="round"
|
zIndex={5}
|
||||||
noevent
|
noevent
|
||||||
zIndex={5}
|
hidden={soundOpened.value}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</container>
|
</container>
|
||||||
</container>
|
</container>
|
||||||
);
|
);
|
||||||
|
@ -23,7 +23,7 @@ import { generateBinary } from '@motajs/legacy-common';
|
|||||||
import { SetupComponentOptions } from '@motajs/system-ui';
|
import { SetupComponentOptions } from '@motajs/system-ui';
|
||||||
import { saveSave, saveLoad } from './save';
|
import { saveSave, saveLoad } from './save';
|
||||||
import { mainUIController } from './controller';
|
import { mainUIController } from './controller';
|
||||||
import { MAIN_WIDTH, MAIN_HEIGHT } from '../shared';
|
import { MAIN_HEIGHT, FULL_LOC, POP_BOX_WIDTH, CENTER_LOC } from '../shared';
|
||||||
import { openSettings } from './settings';
|
import { openSettings } from './settings';
|
||||||
import { openViewMap } from './viewmap';
|
import { openViewMap } from './viewmap';
|
||||||
|
|
||||||
@ -90,10 +90,10 @@ export const PlayingToolbar = defineComponent<
|
|||||||
const tool = () => core.openToolbox(true);
|
const tool = () => core.openToolbox(true);
|
||||||
const fly = () => core.useFly(true);
|
const fly = () => core.useFly(true);
|
||||||
const save = () => {
|
const save = () => {
|
||||||
saveSave(mainUIController, [0, 0, MAIN_WIDTH, MAIN_HEIGHT]);
|
saveSave(mainUIController, FULL_LOC);
|
||||||
};
|
};
|
||||||
const load = () => {
|
const load = () => {
|
||||||
saveLoad(mainUIController, [0, 0, MAIN_WIDTH, MAIN_HEIGHT]);
|
saveLoad(mainUIController, FULL_LOC);
|
||||||
};
|
};
|
||||||
const equip = () => core.openEquipbox(true);
|
const equip = () => core.openEquipbox(true);
|
||||||
const shop = () => core.openQuickShop(true);
|
const shop = () => core.openQuickShop(true);
|
||||||
@ -111,12 +111,15 @@ export const PlayingToolbar = defineComponent<
|
|||||||
const redo = () => core.doSL('autoSave', 'reload');
|
const redo = () => core.doSL('autoSave', 'reload');
|
||||||
const numpad = () => emit('numpad');
|
const numpad = () => emit('numpad');
|
||||||
const view = () => {
|
const view = () => {
|
||||||
openViewMap(mainUIController, [0, 0, MAIN_WIDTH, MAIN_HEIGHT]);
|
openViewMap(mainUIController, FULL_LOC);
|
||||||
};
|
};
|
||||||
const danmaku = () => requestAnimationFrame(openDanmakuPoster);
|
const danmaku = () => requestAnimationFrame(openDanmakuPoster);
|
||||||
const replay = () => core.ui._drawReplay();
|
const replay = () => core.ui._drawReplay();
|
||||||
const settings = () => {
|
const settings = () => {
|
||||||
openSettings(mainUIController, [420, 240, 240, 400, 0.5, 0.5]);
|
const loc = CENTER_LOC.slice() as ElementLocator;
|
||||||
|
loc[2] = POP_BOX_WIDTH;
|
||||||
|
loc[3] = MAIN_HEIGHT - 72;
|
||||||
|
openSettings(mainUIController, loc);
|
||||||
};
|
};
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
@ -166,7 +169,7 @@ export const ReplayingToolbar = defineComponent<ReplayingProps>(props => {
|
|||||||
|
|
||||||
const bookIcon = core.statusBar.icons.book;
|
const bookIcon = core.statusBar.icons.book;
|
||||||
const saveIcon = core.statusBar.icons.save;
|
const saveIcon = core.statusBar.icons.save;
|
||||||
const font1 = new Font('normal', 16);
|
const font1 = Font.defaults({ size: 16 });
|
||||||
const font2 = new Font('Verdana', 12);
|
const font2 = new Font('Verdana', 12);
|
||||||
|
|
||||||
const speedText = computed(() => `${status.speed}速`);
|
const speedText = computed(() => `${status.speed}速`);
|
||||||
@ -183,7 +186,7 @@ export const ReplayingToolbar = defineComponent<ReplayingProps>(props => {
|
|||||||
const speedUp = () => core.speedUpReplay();
|
const speedUp = () => core.speedUpReplay();
|
||||||
const book = () => core.openBook(true);
|
const book = () => core.openBook(true);
|
||||||
const save = () => {
|
const save = () => {
|
||||||
saveSave(mainUIController, [0, 0, MAIN_WIDTH, MAIN_HEIGHT]);
|
saveSave(mainUIController, FULL_LOC);
|
||||||
};
|
};
|
||||||
const view = () => {
|
const view = () => {
|
||||||
if (core.isPlaying() && !core.isMoving() && !core.status.lockControl) {
|
if (core.isPlaying() && !core.isMoving() && !core.status.lockControl) {
|
||||||
|
@ -38,6 +38,17 @@ import { clamp, mean } from 'lodash-es';
|
|||||||
import { calculateStatisticsOne, StatisticsDataOneFloor } from './statistics';
|
import { calculateStatisticsOne, StatisticsDataOneFloor } from './statistics';
|
||||||
import { Tip, TipExpose } from '../components';
|
import { Tip, TipExpose } from '../components';
|
||||||
import { useKey } from '../use';
|
import { useKey } from '../use';
|
||||||
|
import {
|
||||||
|
ENABLE_RIGHT_STATUS_BAR,
|
||||||
|
FULL_LOC,
|
||||||
|
HALF_WIDTH,
|
||||||
|
MAIN_HEIGHT,
|
||||||
|
MAP_HEIGHT,
|
||||||
|
MAP_WIDTH,
|
||||||
|
RIGHT_STATUS_POS,
|
||||||
|
STATUS_BAR_HEIGHT,
|
||||||
|
STATUS_BAR_WIDTH
|
||||||
|
} from '../shared';
|
||||||
|
|
||||||
export interface ViewMapProps extends UIComponentProps, BaseProps {
|
export interface ViewMapProps extends UIComponentProps, BaseProps {
|
||||||
loc: ElementLocator;
|
loc: ElementLocator;
|
||||||
@ -335,12 +346,18 @@ export const ViewMap = defineComponent<ViewMapProps>(props => {
|
|||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<container loc={props.loc} nocache>
|
<container loc={props.loc} nocache>
|
||||||
<g-rect fillStyle="black" fill loc={[0, 0, 840, 480]} />
|
<g-rect fillStyle="black" fill loc={FULL_LOC} />
|
||||||
<g-rect stroke zIndex={100} loc={[0, 0, 840, 480]} noevent />
|
<g-rect stroke zIndex={100} loc={FULL_LOC} noevent />
|
||||||
<g-line line={[180, 0, 180, 480]} lineWidth={1} />
|
<g-line
|
||||||
<g-line line={[180 + 480, 0, 180 + 480, 480]} lineWidth={1} />
|
line={[STATUS_BAR_WIDTH, 0, STATUS_BAR_WIDTH, MAIN_HEIGHT]}
|
||||||
|
lineWidth={1}
|
||||||
|
/>
|
||||||
|
<g-line
|
||||||
|
line={[RIGHT_STATUS_POS, 0, RIGHT_STATUS_POS, MAIN_HEIGHT]}
|
||||||
|
lineWidth={1}
|
||||||
|
/>
|
||||||
<FloorSelector
|
<FloorSelector
|
||||||
loc={[0, 0, 180, 480]}
|
loc={[0, 0, STATUS_BAR_WIDTH, MAIN_HEIGHT]}
|
||||||
floors={viewableFloor}
|
floors={viewableFloor}
|
||||||
v-model:now={now.value}
|
v-model:now={now.value}
|
||||||
onClose={close}
|
onClose={close}
|
||||||
@ -348,7 +365,7 @@ export const ViewMap = defineComponent<ViewMapProps>(props => {
|
|||||||
<layer-group
|
<layer-group
|
||||||
ref={group}
|
ref={group}
|
||||||
ex={layerGroupExtends}
|
ex={layerGroupExtends}
|
||||||
loc={[180, 0, 480, 480]}
|
loc={[STATUS_BAR_WIDTH, 0, MAP_WIDTH, MAP_HEIGHT]}
|
||||||
onDown={downMap}
|
onDown={downMap}
|
||||||
onMove={moveMap}
|
onMove={moveMap}
|
||||||
onUp={upMap}
|
onUp={upMap}
|
||||||
@ -365,12 +382,12 @@ export const ViewMap = defineComponent<ViewMapProps>(props => {
|
|||||||
<Tip
|
<Tip
|
||||||
ref={tip}
|
ref={tip}
|
||||||
zIndex={40}
|
zIndex={40}
|
||||||
loc={[188, 8, 200, 32]}
|
loc={[STATUS_BAR_WIDTH + 8, 8, 200, 32]}
|
||||||
pad={[12, 6]}
|
pad={[12, 6]}
|
||||||
corner={16}
|
corner={16}
|
||||||
/>
|
/>
|
||||||
<sprite
|
<sprite
|
||||||
loc={[180, 0, 480, 64]}
|
loc={[STATUS_BAR_WIDTH, 0, MAP_WIDTH, 64]}
|
||||||
render={renderTop}
|
render={renderTop}
|
||||||
alpha={topAlpha.value}
|
alpha={topAlpha.value}
|
||||||
zIndex={10}
|
zIndex={10}
|
||||||
@ -380,7 +397,7 @@ export const ViewMap = defineComponent<ViewMapProps>(props => {
|
|||||||
onClick={() => changeFloor(1)}
|
onClick={() => changeFloor(1)}
|
||||||
/>
|
/>
|
||||||
<sprite
|
<sprite
|
||||||
loc={[180, 416, 480, 64]}
|
loc={[STATUS_BAR_WIDTH, MAP_HEIGHT - 64, MAP_WIDTH, 64]}
|
||||||
render={renderBottom}
|
render={renderBottom}
|
||||||
alpha={bottomAlpha.value}
|
alpha={bottomAlpha.value}
|
||||||
zIndex={10}
|
zIndex={10}
|
||||||
@ -391,19 +408,22 @@ export const ViewMap = defineComponent<ViewMapProps>(props => {
|
|||||||
/>
|
/>
|
||||||
<text
|
<text
|
||||||
text="上移地图"
|
text="上移地图"
|
||||||
loc={[420, 24]}
|
loc={[HALF_WIDTH, 24]}
|
||||||
anc={[0.5, 0.5]}
|
anc={[0.5, 0.5]}
|
||||||
zIndex={20}
|
zIndex={20}
|
||||||
noevent
|
noevent
|
||||||
/>
|
/>
|
||||||
<text
|
<text
|
||||||
text="下移地图"
|
text="下移地图"
|
||||||
loc={[420, 456]}
|
loc={[HALF_WIDTH, MAP_HEIGHT - 24]}
|
||||||
anc={[0.5, 0.5]}
|
anc={[0.5, 0.5]}
|
||||||
zIndex={20}
|
zIndex={20}
|
||||||
noevent
|
noevent
|
||||||
/>
|
/>
|
||||||
<container loc={[660, 0, 180, 480]}>
|
<container
|
||||||
|
loc={[RIGHT_STATUS_POS, 0, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT]}
|
||||||
|
hidden={!ENABLE_RIGHT_STATUS_BAR}
|
||||||
|
>
|
||||||
<text
|
<text
|
||||||
text="鼠标 / 单指拖动地图"
|
text="鼠标 / 单指拖动地图"
|
||||||
font={rightFont}
|
font={rightFont}
|
||||||
|
@ -73,17 +73,22 @@ type KeyUsing = [Hotkey, symbol];
|
|||||||
/**
|
/**
|
||||||
* 在组件中定义按键操作
|
* 在组件中定义按键操作
|
||||||
* @param noScope 是否不创建新作用域
|
* @param noScope 是否不创建新作用域
|
||||||
|
* @param scope 指定作用域,如果 `noScope` 为 `true`,则此项无效
|
||||||
*/
|
*/
|
||||||
export function useKey(noScope: boolean = false): KeyUsing {
|
export function useKey(noScope: boolean = false, scope?: symbol): KeyUsing {
|
||||||
if (noScope) {
|
if (noScope) {
|
||||||
return [gameKey, gameKey.scope];
|
return [gameKey, gameKey.scope];
|
||||||
} else {
|
} else {
|
||||||
const sym = Symbol();
|
const sym = scope ?? Symbol();
|
||||||
gameKey.use(sym);
|
if (sym === gameKey.scope) {
|
||||||
onUnmounted(() => {
|
return [gameKey, gameKey.scope];
|
||||||
gameKey.dispose();
|
} else {
|
||||||
});
|
gameKey.use(sym);
|
||||||
return [gameKey, sym];
|
onUnmounted(() => {
|
||||||
|
gameKey.dispose();
|
||||||
|
});
|
||||||
|
return [gameKey, sym];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +34,8 @@ export function deleteWith<T>(arr: T[], ele: T): T[] {
|
|||||||
|
|
||||||
export function spliceBy<T>(arr: T[], from: T): T[] {
|
export function spliceBy<T>(arr: T[], from: T): T[] {
|
||||||
const index = arr.indexOf(from);
|
const index = arr.indexOf(from);
|
||||||
if (index === -1) return arr;
|
if (index === -1) return [];
|
||||||
arr.splice(index);
|
return arr.splice(index);
|
||||||
return arr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,8 +160,18 @@ export class Font implements IFontConfig {
|
|||||||
/**
|
/**
|
||||||
* 获取默认字体
|
* 获取默认字体
|
||||||
*/
|
*/
|
||||||
static defaults() {
|
static defaults(config?: Partial<IFontConfig>) {
|
||||||
return new Font();
|
if (!config) {
|
||||||
|
return new Font();
|
||||||
|
} else {
|
||||||
|
return new Font(
|
||||||
|
config.family,
|
||||||
|
config.size,
|
||||||
|
config.sizeUnit,
|
||||||
|
config.weight,
|
||||||
|
config.italic
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,7 +179,8 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
* @param symbol 当前作用域的symbol
|
* @param symbol 当前作用域的symbol
|
||||||
*/
|
*/
|
||||||
use(symbol: symbol): void {
|
use(symbol: symbol): void {
|
||||||
spliceBy(this.scopeStack, symbol);
|
if (symbol === this.scope) return;
|
||||||
|
this.dispose(symbol);
|
||||||
this.scopeStack.push(symbol);
|
this.scopeStack.push(symbol);
|
||||||
this.scope = symbol;
|
this.scope = symbol;
|
||||||
this.conditionMap.set(symbol, () => true);
|
this.conditionMap.set(symbol, () => true);
|
||||||
@ -190,10 +191,12 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
* @param symbol 要释放的作用域的symbol
|
* @param symbol 要释放的作用域的symbol
|
||||||
*/
|
*/
|
||||||
dispose(symbol: symbol = this.scopeStack.at(-1) ?? Symbol()): void {
|
dispose(symbol: symbol = this.scopeStack.at(-1) ?? Symbol()): void {
|
||||||
for (const key of Object.values(this.data)) {
|
const disposed = spliceBy(this.scopeStack, symbol);
|
||||||
key.emits.delete(symbol);
|
disposed.forEach(v => {
|
||||||
}
|
for (const key of Object.values(this.data)) {
|
||||||
spliceBy(this.scopeStack, symbol);
|
key.emits.delete(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
this.scope = this.scopeStack.at(-1) ?? Symbol();
|
this.scope = this.scopeStack.at(-1) ?? Symbol();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user