mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-05-02 04:13:24 +08:00
refactor: 新状态栏
This commit is contained in:
parent
6ba0b4a762
commit
2e3c368354
@ -3149,8 +3149,8 @@ control.prototype.resize = function () {
|
|||||||
core.domStyle.scale = target - 0.25;
|
core.domStyle.scale = target - 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pw = core._PX_ * core.domStyle.scale;
|
const pw = (480 + 180) * core.domStyle.scale;
|
||||||
const ph = core._PY_ * core.domStyle.scale;
|
const ph = 480 * core.domStyle.scale;
|
||||||
core.dom.gameDraw.style.width = `${pw}px`;
|
core.dom.gameDraw.style.width = `${pw}px`;
|
||||||
core.dom.gameDraw.style.height = `${ph}px`;
|
core.dom.gameDraw.style.height = `${ph}px`;
|
||||||
|
|
||||||
|
@ -895,6 +895,18 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
* @param expected 期望类型
|
* @param expected 期望类型
|
||||||
* @param key 键名
|
* @param key 键名
|
||||||
*/
|
*/
|
||||||
|
protected assertType(value: any, expected: string, key: string): boolean;
|
||||||
|
/**
|
||||||
|
* 判断一个prop是否是期望类型
|
||||||
|
* @param value 实际值
|
||||||
|
* @param expected 期望类型
|
||||||
|
* @param key 键名
|
||||||
|
*/
|
||||||
|
protected assertType<T>(
|
||||||
|
value: any,
|
||||||
|
expected: new (...params: any[]) => T,
|
||||||
|
key: string
|
||||||
|
): value is T;
|
||||||
protected assertType(
|
protected assertType(
|
||||||
value: any,
|
value: any,
|
||||||
expected: string | (new (...params: any[]) => any),
|
expected: string | (new (...params: any[]) => any),
|
||||||
@ -1030,6 +1042,27 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
this.setComposite(nextValue);
|
this.setComposite(nextValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case 'loc': {
|
||||||
|
if (!this.assertType(nextValue, Array, key)) return;
|
||||||
|
if (!isNil(nextValue[0]) && !isNil(nextValue[1])) {
|
||||||
|
this.pos(nextValue[0] as number, nextValue[1] as number);
|
||||||
|
}
|
||||||
|
if (!isNil(nextValue[2]) && !isNil(nextValue[3])) {
|
||||||
|
this.size(nextValue[2] as number, nextValue[3] as number);
|
||||||
|
}
|
||||||
|
if (!isNil(nextValue[4]) && !isNil(nextValue[5])) {
|
||||||
|
this.setAnchor(
|
||||||
|
nextValue[4] as number,
|
||||||
|
nextValue[5] as number
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'anc': {
|
||||||
|
if (!this.assertType(nextValue, Array, key)) return;
|
||||||
|
this.setAnchor(nextValue[0] as number, nextValue[1] as number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const ev = this.parseEvent(key);
|
const ev = this.parseEvent(key);
|
||||||
if (ev) {
|
if (ev) {
|
||||||
|
@ -62,7 +62,6 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
|||||||
this.target = new MotaOffscreenCanvas2D(true, canvas);
|
this.target = new MotaOffscreenCanvas2D(true, canvas);
|
||||||
this.size(core._PX_, core._PY_);
|
this.size(core._PX_, core._PY_);
|
||||||
this.target.withGameScale(true);
|
this.target.withGameScale(true);
|
||||||
this.target.size(core._PX_, core._PY_);
|
|
||||||
this.target.setAntiAliasing(false);
|
this.target.setAntiAliasing(false);
|
||||||
|
|
||||||
this.setAnchor(0.5, 0.5);
|
this.setAnchor(0.5, 0.5);
|
||||||
@ -81,6 +80,12 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
|||||||
this.listen();
|
this.listen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size(width: number, height: number): void {
|
||||||
|
super.size(width, height);
|
||||||
|
this.target.size(width, height);
|
||||||
|
this.transform.setTranslate(width / 2, height / 2);
|
||||||
|
}
|
||||||
|
|
||||||
private listen() {
|
private listen() {
|
||||||
// 画布监听
|
// 画布监听
|
||||||
const canvas = this.target.canvas;
|
const canvas = this.target.canvas;
|
||||||
|
@ -49,7 +49,11 @@ export const { createApp, render } = createRenderer<RenderItem, RenderItem>({
|
|||||||
},
|
},
|
||||||
|
|
||||||
createText: function (text: string): RenderItem<ETextEvent> {
|
createText: function (text: string): RenderItem<ETextEvent> {
|
||||||
if (!/^\s*$/.test(text)) logger.warn(38);
|
if (/^\s*$/.test(text)) {
|
||||||
|
return new Comment();
|
||||||
|
} else {
|
||||||
|
logger.warn(38);
|
||||||
|
}
|
||||||
return new Text(text);
|
return new Text(text);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
} from '../preset/layer';
|
} from '../preset/layer';
|
||||||
import type { EnemyCollection } from '@/game/enemy/damage';
|
import type { EnemyCollection } from '@/game/enemy/damage';
|
||||||
import { ILineProperty } from '../preset/graphics';
|
import { ILineProperty } from '../preset/graphics';
|
||||||
|
import { ElementAnchor, ElementLocator } from '../utils';
|
||||||
|
|
||||||
export interface CustomProps {
|
export interface CustomProps {
|
||||||
_item: (props: BaseProps) => RenderItem;
|
_item: (props: BaseProps) => RenderItem;
|
||||||
@ -32,6 +33,14 @@ export interface BaseProps {
|
|||||||
alpha?: number;
|
alpha?: number;
|
||||||
composite?: GlobalCompositeOperation;
|
composite?: GlobalCompositeOperation;
|
||||||
cursor?: string;
|
cursor?: string;
|
||||||
|
/**
|
||||||
|
* 定位属性,可以填 `[横坐标,纵坐标,宽度,高度,x锚点,y锚点]`,
|
||||||
|
* 对于横坐标与纵坐标、宽度与高度、x锚点与y锚点,两两一组要么都填,要么都不填
|
||||||
|
* 是 x, y, width, height, anchorX, anchorY 的简写属性
|
||||||
|
*/
|
||||||
|
loc?: ElementLocator;
|
||||||
|
/** 锚点属性,可以填 `[x锚点,y锚点]`,是 anchorX, anchorY 的简写属性 */
|
||||||
|
anc?: ElementAnchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SpriteProps extends BaseProps {
|
export interface SpriteProps extends BaseProps {
|
||||||
|
@ -19,6 +19,17 @@ export type Props<
|
|||||||
? InstanceType<T>['$props'] & InstanceType<T>['$emits']
|
? InstanceType<T>['$props'] & InstanceType<T>['$emits']
|
||||||
: unknown;
|
: unknown;
|
||||||
|
|
||||||
|
export type ElementLocator = [
|
||||||
|
x?: number,
|
||||||
|
y?: number,
|
||||||
|
width?: number,
|
||||||
|
height?: number,
|
||||||
|
anchorX?: number,
|
||||||
|
anchorY?: number
|
||||||
|
];
|
||||||
|
|
||||||
|
export type ElementAnchor = [x: number, y: number];
|
||||||
|
|
||||||
export function disableViewport() {
|
export function disableViewport() {
|
||||||
const adapter = RenderAdapter.get<FloorViewport>('viewport');
|
const adapter = RenderAdapter.get<FloorViewport>('viewport');
|
||||||
if (!adapter) return;
|
if (!adapter) return;
|
||||||
|
@ -1,86 +1,21 @@
|
|||||||
import { FloorItemDetail } from '@/plugin/fx/itemDetail';
|
|
||||||
import { FloorDamageExtends, LayerGroup } from '@/core/render';
|
|
||||||
import { LayerDoorAnimate } from '@/core/render';
|
|
||||||
import { HeroRenderer } from '@/core/render';
|
|
||||||
import { MotaRenderer } from '@/core/render';
|
import { MotaRenderer } from '@/core/render';
|
||||||
import { LayerShadowExtends } from '@/core/fx/shadow';
|
|
||||||
import { LayerGroupFilter } from '@/plugin/fx/gameCanvas';
|
|
||||||
import { LayerGroupAnimate } from '@/core/render';
|
|
||||||
import { LayerGroupPortal } from '@/plugin/fx/portal';
|
|
||||||
import { LayerGroupHalo } from '@/plugin/fx/halo';
|
|
||||||
import { FloorViewport } from '@/core/render';
|
|
||||||
import { PopText } from '@/plugin/fx/pop';
|
|
||||||
import { FloorChange } from '@/plugin/fallback';
|
|
||||||
import { createApp } from '@/core/render';
|
import { createApp } from '@/core/render';
|
||||||
import { defineComponent, onMounted, ref } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { Textbox } from './components';
|
|
||||||
import { ILayerGroupRenderExtends, ILayerRenderExtends } from '@/core/render';
|
|
||||||
import { Props } from '@/core/render';
|
|
||||||
import { WeatherController } from '../weather';
|
|
||||||
import { UIController } from '@/core/system';
|
import { UIController } from '@/core/system';
|
||||||
|
import { mainSceneUI } from './ui/main';
|
||||||
|
import { MAIN_HEIGHT, MAIN_WIDTH } from './shared';
|
||||||
|
|
||||||
export function create() {
|
export function create() {
|
||||||
const main = new MotaRenderer();
|
const main = new MotaRenderer();
|
||||||
|
main.size(MAIN_WIDTH, MAIN_HEIGHT);
|
||||||
|
|
||||||
const App = defineComponent(_props => {
|
const App = defineComponent(_props => {
|
||||||
const layerGroupExtends: ILayerGroupRenderExtends[] = [
|
const ui = new UIController('root-ui');
|
||||||
new FloorDamageExtends(),
|
ui.open(mainSceneUI, {});
|
||||||
new FloorItemDetail(),
|
|
||||||
new LayerGroupFilter(),
|
|
||||||
new LayerGroupPortal(),
|
|
||||||
new LayerGroupHalo(),
|
|
||||||
new LayerGroupAnimate(),
|
|
||||||
new FloorViewport()
|
|
||||||
];
|
|
||||||
const eventExtends: ILayerRenderExtends[] = [
|
|
||||||
new HeroRenderer(),
|
|
||||||
new LayerDoorAnimate(),
|
|
||||||
new LayerShadowExtends()
|
|
||||||
];
|
|
||||||
const mapDrawProps: Props<'container'> = {
|
|
||||||
width: core._PX_,
|
|
||||||
height: core._PY_
|
|
||||||
};
|
|
||||||
const mainTextboxProps: Props<typeof Textbox> = {
|
|
||||||
text: '',
|
|
||||||
hidden: true,
|
|
||||||
width: 480,
|
|
||||||
height: 150,
|
|
||||||
y: 330,
|
|
||||||
zIndex: 30,
|
|
||||||
fillStyle: '#fff',
|
|
||||||
titleFill: 'gold',
|
|
||||||
fontFamily: 'normal',
|
|
||||||
titleFont: '700 20px normal',
|
|
||||||
winskin: 'winskin2.png',
|
|
||||||
interval: 100,
|
|
||||||
lineHeight: 6
|
|
||||||
};
|
|
||||||
|
|
||||||
const map = ref<LayerGroup>();
|
|
||||||
const weather = new WeatherController('main');
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
weather.bind(map.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
const ui = new UIController('main-ui');
|
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<container id="map-draw" {...mapDrawProps}>
|
<container width={MAIN_WIDTH} height={MAIN_HEIGHT}>
|
||||||
<container width={480} height={480}>
|
{ui.render()}
|
||||||
{ui.render()}
|
|
||||||
</container>
|
|
||||||
<layer-group id="layer-main" ex={layerGroupExtends} ref={map}>
|
|
||||||
<layer layer="bg" zIndex={10}></layer>
|
|
||||||
<layer layer="bg2" zIndex={20}></layer>
|
|
||||||
<layer layer="event" zIndex={30} ex={eventExtends}></layer>
|
|
||||||
<layer layer="fg" zIndex={40}></layer>
|
|
||||||
<layer layer="fg2" zIndex={50}></layer>
|
|
||||||
<PopText id="pop-main" zIndex={80}></PopText>
|
|
||||||
</layer-group>
|
|
||||||
<Textbox id="main-textbox" {...mainTextboxProps}></Textbox>
|
|
||||||
<FloorChange id="floor-change" zIndex={50}></FloorChange>
|
|
||||||
</container>
|
</container>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -100,3 +35,5 @@ export function create() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export * from './components';
|
export * from './components';
|
||||||
|
export * from './ui';
|
||||||
|
export * from './use';
|
||||||
|
10
src/module/render/shared.ts
Normal file
10
src/module/render/shared.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export const STATUS_BAR_WIDTH = 180;
|
||||||
|
export const STATUS_BAR_HEIGHT = 480;
|
||||||
|
|
||||||
|
export const ENABLE_RIGHT_STATUS_BAR = true;
|
||||||
|
|
||||||
|
export const MAP_WIDTH = 480;
|
||||||
|
export const MAP_HEIGHT = 480;
|
||||||
|
|
||||||
|
export const MAIN_WIDTH = 480 + 180;
|
||||||
|
export const MAIN_HEIGHT = 480;
|
2
src/module/render/ui/index.ts
Normal file
2
src/module/render/ui/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './main';
|
||||||
|
export * from './statusBar';
|
112
src/module/render/ui/main.tsx
Normal file
112
src/module/render/ui/main.tsx
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { LayerShadowExtends } from '@/core/fx/shadow';
|
||||||
|
import {
|
||||||
|
ILayerGroupRenderExtends,
|
||||||
|
FloorDamageExtends,
|
||||||
|
LayerGroupAnimate,
|
||||||
|
FloorViewport,
|
||||||
|
ILayerRenderExtends,
|
||||||
|
HeroRenderer,
|
||||||
|
LayerDoorAnimate,
|
||||||
|
Props,
|
||||||
|
LayerGroup
|
||||||
|
} from '@/core/render';
|
||||||
|
import { WeatherController } from '@/module/weather';
|
||||||
|
import { FloorChange } from '@/plugin/fallback';
|
||||||
|
import { LayerGroupFilter } from '@/plugin/fx/gameCanvas';
|
||||||
|
import { LayerGroupHalo } from '@/plugin/fx/halo';
|
||||||
|
import { FloorItemDetail } from '@/plugin/fx/itemDetail';
|
||||||
|
import { PopText } from '@/plugin/fx/pop';
|
||||||
|
import { LayerGroupPortal } from '@/plugin/fx/portal';
|
||||||
|
import { defineComponent, onMounted, reactive, ref } from 'vue';
|
||||||
|
import { Textbox } from '../components';
|
||||||
|
import { GameUI, UIController } from '@/core/system';
|
||||||
|
import {
|
||||||
|
MAIN_HEIGHT,
|
||||||
|
MAIN_WIDTH,
|
||||||
|
STATUS_BAR_HEIGHT,
|
||||||
|
STATUS_BAR_WIDTH
|
||||||
|
} from '../shared';
|
||||||
|
import { IHeroStatus, StatusBar } from './statusBar';
|
||||||
|
import { onLoaded } from '../use';
|
||||||
|
|
||||||
|
const MainScene = defineComponent(() => {
|
||||||
|
const layerGroupExtends: ILayerGroupRenderExtends[] = [
|
||||||
|
new FloorDamageExtends(),
|
||||||
|
new FloorItemDetail(),
|
||||||
|
new LayerGroupFilter(),
|
||||||
|
new LayerGroupPortal(),
|
||||||
|
new LayerGroupHalo(),
|
||||||
|
new LayerGroupAnimate(),
|
||||||
|
new FloorViewport()
|
||||||
|
];
|
||||||
|
const eventExtends: ILayerRenderExtends[] = [
|
||||||
|
new HeroRenderer(),
|
||||||
|
new LayerDoorAnimate(),
|
||||||
|
new LayerShadowExtends()
|
||||||
|
];
|
||||||
|
const mapDrawProps: Props<'container'> = {
|
||||||
|
width: core._PX_,
|
||||||
|
height: core._PY_
|
||||||
|
};
|
||||||
|
const mainTextboxProps: Props<typeof Textbox> = {
|
||||||
|
text: '',
|
||||||
|
hidden: true,
|
||||||
|
width: 480,
|
||||||
|
height: 150,
|
||||||
|
y: 330,
|
||||||
|
zIndex: 30,
|
||||||
|
fillStyle: '#fff',
|
||||||
|
titleFill: 'gold',
|
||||||
|
fontFamily: 'normal',
|
||||||
|
titleFont: '700 20px normal',
|
||||||
|
winskin: 'winskin2.png',
|
||||||
|
interval: 100,
|
||||||
|
lineHeight: 6
|
||||||
|
};
|
||||||
|
|
||||||
|
const map = ref<LayerGroup>();
|
||||||
|
const weather = new WeatherController('main');
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
weather.bind(map.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const status: IHeroStatus = reactive({
|
||||||
|
hp: 0,
|
||||||
|
atk: 0,
|
||||||
|
def: 0,
|
||||||
|
mdef: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const loaded = ref(false);
|
||||||
|
onLoaded(() => {
|
||||||
|
loaded.value = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<container id="main-scene" width={MAIN_WIDTH} height={MAIN_HEIGHT}>
|
||||||
|
{loaded.value && (
|
||||||
|
<StatusBar
|
||||||
|
loc={[0, 0, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT]}
|
||||||
|
status={status}
|
||||||
|
></StatusBar>
|
||||||
|
)}
|
||||||
|
<container id="map-draw" {...mapDrawProps} x={180} zIndex={10}>
|
||||||
|
<layer-group id="layer-main" ex={layerGroupExtends} ref={map}>
|
||||||
|
<layer layer="bg" zIndex={10}></layer>
|
||||||
|
<layer layer="bg2" zIndex={20}></layer>
|
||||||
|
<layer layer="event" zIndex={30} ex={eventExtends}></layer>
|
||||||
|
<layer layer="fg" zIndex={40}></layer>
|
||||||
|
<layer layer="fg2" zIndex={50}></layer>
|
||||||
|
<PopText id="pop-main" zIndex={80}></PopText>
|
||||||
|
</layer-group>
|
||||||
|
<Textbox id="main-textbox" {...mainTextboxProps}></Textbox>
|
||||||
|
<FloorChange id="floor-change" zIndex={50}></FloorChange>
|
||||||
|
</container>
|
||||||
|
{mainUIController.render()}
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const mainSceneUI = new GameUI('main-scene', MainScene);
|
||||||
|
export const mainUIController = new UIController('main-ui');
|
56
src/module/render/ui/statusBar.tsx
Normal file
56
src/module/render/ui/statusBar.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { GameUI } from '@/core/system';
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { SetupComponentOptions } from '../components';
|
||||||
|
import { ElementLocator } from '@/core/render';
|
||||||
|
|
||||||
|
export interface IHeroStatus {
|
||||||
|
hp: number;
|
||||||
|
atk: number;
|
||||||
|
def: number;
|
||||||
|
mdef: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StatusBarProps {
|
||||||
|
loc: ElementLocator;
|
||||||
|
status: IHeroStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusBarProps = {
|
||||||
|
props: ['loc', 'status']
|
||||||
|
} satisfies SetupComponentOptions<StatusBarProps>;
|
||||||
|
|
||||||
|
export const StatusBar = defineComponent<StatusBarProps>(p => {
|
||||||
|
const hpIcon = core.material.images.images['hp.png'];
|
||||||
|
const atkIcon = core.material.images.images['atk.png'];
|
||||||
|
const defIcon = core.material.images.images['def.png'];
|
||||||
|
const mdefIcon = core.material.images.images['IQ.png'];
|
||||||
|
|
||||||
|
const s = p.status;
|
||||||
|
const f = core.formatBigNumber;
|
||||||
|
|
||||||
|
const iconLoc = (n: number): ElementLocator => {
|
||||||
|
return [16, 16 + 48 * n, 32, 32];
|
||||||
|
};
|
||||||
|
|
||||||
|
const textLoc = (n: number): ElementLocator => {
|
||||||
|
return [64, 32 + 48 * n, void 0, void 0, 0.5, 0.5];
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
return (
|
||||||
|
<container loc={p.loc}>
|
||||||
|
<g-rect loc={[0, 0, p.loc[2], p.loc[3]]} stroke></g-rect>
|
||||||
|
<image image={hpIcon} loc={iconLoc(0)}></image>
|
||||||
|
<text text={f(s.hp)} loc={textLoc(0)}></text>
|
||||||
|
<image image={atkIcon} loc={iconLoc(1)}></image>
|
||||||
|
<text text={f(s.atk)} loc={textLoc(1)}></text>
|
||||||
|
<image image={defIcon} loc={iconLoc(2)}></image>
|
||||||
|
<text text={f(s.atk)} loc={textLoc(2)}></text>
|
||||||
|
<image image={mdefIcon} loc={iconLoc(3)}></image>
|
||||||
|
<text text={f(s.atk)} loc={textLoc(3)}></text>
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}, statusBarProps);
|
||||||
|
|
||||||
|
export const statusBarUI = new GameUI('status-bar', StatusBar);
|
60
src/module/render/use.ts
Normal file
60
src/module/render/use.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { onMounted, onUnmounted } from 'vue';
|
||||||
|
|
||||||
|
export const enum Orientation {
|
||||||
|
/** 横屏 */
|
||||||
|
Landscape,
|
||||||
|
/** 竖屏 */
|
||||||
|
Portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OrientationHook = (
|
||||||
|
orientation: Orientation,
|
||||||
|
width: number,
|
||||||
|
height: number
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
let nowOrientation = Orientation.Landscape;
|
||||||
|
const orientationHooks = new Set<OrientationHook>();
|
||||||
|
|
||||||
|
function checkOrientation() {
|
||||||
|
const before = nowOrientation;
|
||||||
|
// 只要宽度大于高度,那么就视为横屏
|
||||||
|
if (window.innerWidth >= window.innerHeight) {
|
||||||
|
nowOrientation = Orientation.Landscape;
|
||||||
|
} else {
|
||||||
|
nowOrientation = Orientation.Portrait;
|
||||||
|
}
|
||||||
|
if (nowOrientation === before) return;
|
||||||
|
|
||||||
|
orientationHooks.forEach(v => {
|
||||||
|
v(nowOrientation, window.innerWidth, window.innerHeight);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', checkOrientation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当屏幕方向改变时执行函数
|
||||||
|
* @param hook 当屏幕方向改变时执行的函数
|
||||||
|
*/
|
||||||
|
export function onOrientationChange(hook: OrientationHook) {
|
||||||
|
onMounted(() => {
|
||||||
|
orientationHooks.add(hook);
|
||||||
|
hook(nowOrientation, window.innerWidth, window.innerHeight);
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
orientationHooks.delete(hook);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当游戏加载完成时执行函数,如果调用此函数时游戏已经加载,那么会立刻调用传入的钩子函数
|
||||||
|
* @param hook 当游戏加载完成时执行的函数
|
||||||
|
*/
|
||||||
|
export function onLoaded(hook: () => void) {
|
||||||
|
const loading = Mota.require('var', 'loading');
|
||||||
|
if (!loading.loaded) {
|
||||||
|
loading.once('loaded', hook);
|
||||||
|
} else {
|
||||||
|
hook();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user