mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-06-08 00:07:59 +08:00
feat: render 包单独构建 & fix: 画布高清问题
This commit is contained in:
parent
e4a6a136ed
commit
226b841124
@ -12,15 +12,15 @@
|
||||
"declare": "tsx script/declare.ts",
|
||||
"type": "vue-tsc --noEmit",
|
||||
"lines": "tsx script/lines.ts packages packages-user",
|
||||
"build:packages": "vue-tsx --noEmit && tsx script/build-packages.ts",
|
||||
"build:game": "vue-tsx --noEmit && tsx script/build-game.ts",
|
||||
"build:packages": "vue-tsc --noEmit && tsx script/build-packages.ts",
|
||||
"build:game": "vue-tsc --noEmit && tsx script/build-game.ts",
|
||||
"build:lib": "vue-tsc --noEmit && tsx script/build-lib.ts",
|
||||
"docs:dev": "concurrently -k -n SIDEBAR,VITEPRESS -c blue,green \"tsx docs/.vitepress/api.ts\" \"vitepress dev docs\"",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^6.1.0",
|
||||
"@vueuse/core": "^10.11.1",
|
||||
"@wasm-audio-decoders/ogg-vorbis": "^0.1.16",
|
||||
"anon-tokyo": "0.0.0-alpha.0",
|
||||
"ant-design-vue": "^3.2.20",
|
||||
@ -35,6 +35,7 @@
|
||||
"mutate-animate": "^1.4.2",
|
||||
"ogg-opus-decoder": "^1.6.14",
|
||||
"opus-decoder": "^0.7.7",
|
||||
"vite-plugin-dts": "^4.5.4",
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -81,7 +82,6 @@
|
||||
"typescript-eslint": "^8.27.0",
|
||||
"unplugin-vue-components": "^0.22.12",
|
||||
"vite": "^6.2.2",
|
||||
"vite-plugin-dts": "^4.5.3",
|
||||
"vitepress": "^1.6.3",
|
||||
"vitepress-plugin-mermaid": "^2.0.17",
|
||||
"vue-tsc": "^2.2.8",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DefaultProps, ElementLocator, Font, useKey } from '@motajs/render';
|
||||
import { DefaultProps, ElementLocator, Font } from '@motajs/render';
|
||||
import { computed, defineComponent, reactive, ref } from 'vue';
|
||||
import { Background, Selection } from './misc';
|
||||
import { TextContent, TextContentExpose, TextContentProps } from './textbox';
|
||||
@ -6,6 +6,7 @@ import { SetupComponentOptions } from './types';
|
||||
import { TextAlign } from './textboxTyper';
|
||||
import { Page, PageExpose } from './page';
|
||||
import { GameUI, IUIMountable } from '@motajs/system-ui';
|
||||
import { useKey } from '../use';
|
||||
|
||||
export interface ConfirmBoxProps extends DefaultProps, TextContentProps {
|
||||
text: string;
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { DefaultProps } from '@motajs/render-vue';
|
||||
import Scroll from 'packages/legacy-ui/src/components/scroll.vue';
|
||||
import { computed, defineComponent, ref, SlotsType, VNode } from 'vue';
|
||||
import { Selection } from './misc';
|
||||
import { ElementLocator } from '@motajs/render-core';
|
||||
import { Font } from '@motajs/render-style';
|
||||
import { SetupComponentOptions } from '@motajs/system-ui';
|
||||
import { Scroll } from './scroll';
|
||||
|
||||
export interface ListProps extends DefaultProps {
|
||||
/** 列表内容,第一项表示 id,第二项表示显示的内容 */
|
||||
@ -64,7 +64,7 @@ export const List = defineComponent<ListProps, ListEmits, keyof ListEmits>(
|
||||
};
|
||||
|
||||
return () => (
|
||||
<Scroll>
|
||||
<Scroll loc={props.loc}>
|
||||
{props.list.map((v, i) => {
|
||||
const [key, value] = v;
|
||||
const loc: ElementLocator = [
|
||||
|
@ -70,9 +70,12 @@ export * from './animate';
|
||||
export * from './block';
|
||||
export * from './cache';
|
||||
export * from './camera';
|
||||
export * from './damage';
|
||||
export * from './frame';
|
||||
export * from './hero';
|
||||
export * from './itemDetail';
|
||||
export * from './layer';
|
||||
export * from './misc';
|
||||
export * from './viewport';
|
||||
export * from './props';
|
||||
export * from './utils';
|
||||
export * from './viewport';
|
||||
|
@ -570,11 +570,11 @@ export class Layer extends Container<ELayerEvent> {
|
||||
static readonly FRAME_ALL = 15;
|
||||
|
||||
/** 静态层,包含除大怪物及正在移动的内容外的内容 */
|
||||
protected staticMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
||||
protected staticMap = this.requireCanvas(true, false);
|
||||
/** 移动层,包含大怪物及正在移动的内容 */
|
||||
protected movingMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
||||
protected movingMap = this.requireCanvas(true, false);
|
||||
/** 背景图层 */
|
||||
protected backMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
||||
protected backMap = this.requireCanvas(true, false);
|
||||
|
||||
/** 最终渲染至的Sprite */
|
||||
main: Sprite = new Sprite('absolute', false, true);
|
||||
|
@ -9,9 +9,21 @@ import {
|
||||
} from './layer';
|
||||
import { EAnimateEvent } from './animate';
|
||||
import { EIconEvent, EWinskinEvent } from './misc';
|
||||
import { IEnemyCollection } from '@motajs/types';
|
||||
import { CanvasStyle } from '@motajs/render-elements';
|
||||
|
||||
export interface AnimateProps extends BaseProps {}
|
||||
|
||||
export interface DamageProps extends BaseProps {
|
||||
mapWidth?: number;
|
||||
mapHeight?: number;
|
||||
cellSize?: number;
|
||||
enemy?: IEnemyCollection;
|
||||
font?: string;
|
||||
strokeStyle?: CanvasStyle;
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
export interface IconProps extends BaseProps {
|
||||
/** 图标 id 或数字 */
|
||||
icon: AllNumbers | AllIds;
|
||||
|
@ -47,3 +47,4 @@ export * from './components';
|
||||
export * from './ui';
|
||||
export * from './use';
|
||||
export * from './elements';
|
||||
export * from './renderer';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GameUI, UIComponentProps } from '@motajs/system-ui';
|
||||
import { GameUI } from '@motajs/system-ui';
|
||||
import { computed, defineComponent, ref, watch } from 'vue';
|
||||
import { SetupComponentOptions, TextContent } from '../components';
|
||||
import {
|
||||
@ -40,7 +40,7 @@ export interface ILeftHeroStatus {
|
||||
magicDef: number;
|
||||
}
|
||||
|
||||
interface StatusBarProps<T> extends DefaultProps, UIComponentProps {
|
||||
interface StatusBarProps<T> extends DefaultProps {
|
||||
loc: ElementLocator;
|
||||
status: T;
|
||||
hidden: boolean;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Hotkey, gameKey } from '@motajs/system-action';
|
||||
import { loading } from '@user/data-base';
|
||||
import { TimingFn, Transition } from 'mutate-animate';
|
||||
import {
|
||||
@ -67,6 +68,25 @@ export function onLoaded(hook: () => void) {
|
||||
}
|
||||
}
|
||||
|
||||
type KeyUsing = [Hotkey, symbol];
|
||||
|
||||
/**
|
||||
* 在组件中定义按键操作
|
||||
* @param noScope 是否不创建新作用域
|
||||
*/
|
||||
export function useKey(noScope: boolean = false): KeyUsing {
|
||||
if (noScope) {
|
||||
return [gameKey, gameKey.scope];
|
||||
} else {
|
||||
const sym = Symbol();
|
||||
gameKey.use(sym);
|
||||
onUnmounted(() => {
|
||||
gameKey.dispose();
|
||||
});
|
||||
return [gameKey, sym];
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITransitionedController<T> {
|
||||
readonly ref: Ref<T>;
|
||||
readonly value: T;
|
||||
|
@ -5,7 +5,7 @@ import type { TowerBoss } from './towerBoss';
|
||||
import { IStateDamageable } from '@user/data-state';
|
||||
import { PointEffect, PointEffectType } from '../fx/pointShader';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { mainRenderer } from 'packages-user/client-modules/src/render/renderer';
|
||||
import { mainRenderer } from '@user/client-modules';
|
||||
|
||||
export const enum ProjectileDirection {
|
||||
Vertical,
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
type MoveStep
|
||||
} from '@user/data-state';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import { mainRenderer } from 'packages-user/client-modules/src/render/renderer';
|
||||
import { mainRenderer } from '@user/client-modules';
|
||||
|
||||
export interface IChaseController {
|
||||
/** 本次追逐战实例 */
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { debounce } from 'lodash-es';
|
||||
import logInfo from './logger.json';
|
||||
|
||||
export const enum LogLevel {
|
||||
@ -21,28 +20,28 @@ interface LoggerCatchReturns<T> {
|
||||
info: LoggerCatchInfo[];
|
||||
}
|
||||
|
||||
let logTip: HTMLSpanElement;
|
||||
if (!main.replayChecking) {
|
||||
const tip = document.createElement('span');
|
||||
logTip = tip;
|
||||
tip.style.position = 'fixed';
|
||||
tip.style.right = '0';
|
||||
tip.style.bottom = '0';
|
||||
tip.style.height = '20px';
|
||||
tip.style.width = 'auto';
|
||||
tip.style.textAlign = 'right';
|
||||
tip.style.padding = '0 5px';
|
||||
tip.style.fontSize = '16px';
|
||||
tip.style.fontFamily = 'Arial';
|
||||
tip.style.display = 'none';
|
||||
tip.style.margin = '2px';
|
||||
document.body.appendChild(tip);
|
||||
}
|
||||
// let logTip: HTMLSpanElement;
|
||||
// if (!main.replayChecking) {
|
||||
// const tip = document.createElement('span');
|
||||
// logTip = tip;
|
||||
// tip.style.position = 'fixed';
|
||||
// tip.style.right = '0';
|
||||
// tip.style.bottom = '0';
|
||||
// tip.style.height = '20px';
|
||||
// tip.style.width = 'auto';
|
||||
// tip.style.textAlign = 'right';
|
||||
// tip.style.padding = '0 5px';
|
||||
// tip.style.fontSize = '16px';
|
||||
// tip.style.fontFamily = 'Arial';
|
||||
// tip.style.display = 'none';
|
||||
// tip.style.margin = '2px';
|
||||
// document.body.appendChild(tip);
|
||||
// }
|
||||
|
||||
const hideTipText = debounce(() => {
|
||||
if (main.replayChecking) return;
|
||||
logTip.style.display = 'none';
|
||||
}, 5000);
|
||||
// const hideTipText = debounce(() => {
|
||||
// if (main.replayChecking) return;
|
||||
// logTip.style.display = 'none';
|
||||
// }, 5000);
|
||||
|
||||
const nums = new Set('1234567890');
|
||||
|
||||
@ -117,12 +116,12 @@ export class Logger {
|
||||
});
|
||||
}
|
||||
if (this.level <= LogLevel.ERROR && this.enabled) {
|
||||
if (!main.replayChecking) {
|
||||
logTip.style.color = 'lightcoral';
|
||||
logTip.style.display = 'block';
|
||||
logTip.textContent = `Error thrown, please check in console.`;
|
||||
hideTipText();
|
||||
}
|
||||
// if (!main.replayChecking) {
|
||||
// logTip.style.color = 'lightcoral';
|
||||
// logTip.style.display = 'block';
|
||||
// logTip.textContent = `Error thrown, please check in console.`;
|
||||
// hideTipText();
|
||||
// }
|
||||
const n = Math.floor(code / 50) + 1;
|
||||
const n2 = code % 50;
|
||||
const url = `/_docs/logger/error/error${n}.html#error-code-${n2}`;
|
||||
@ -150,12 +149,12 @@ export class Logger {
|
||||
});
|
||||
}
|
||||
if (this.level <= LogLevel.WARNING && this.enabled) {
|
||||
if (!main.replayChecking) {
|
||||
logTip.style.color = 'gold';
|
||||
logTip.style.display = 'block';
|
||||
logTip.textContent = `Warning thrown, please check in console.`;
|
||||
hideTipText();
|
||||
}
|
||||
// if (!main.replayChecking) {
|
||||
// logTip.style.color = 'gold';
|
||||
// logTip.style.display = 'block';
|
||||
// logTip.textContent = `Warning thrown, please check in console.`;
|
||||
// hideTipText();
|
||||
// }
|
||||
const n = Math.floor(code / 50) + 1;
|
||||
const n2 = code % 50;
|
||||
const url = `/_docs/logger/warn/warn${n}.html#warn-code-${n2}`;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
|
||||
interface OffscreenCanvasEvent {
|
||||
/** 当被动触发resize时(例如core.domStyle.scale变化、窗口大小变化)时触发,使用size函数并不会触发 */
|
||||
/** 当被动触发resize时(例如窗口大小变化)时触发,使用size函数并不会触发 */
|
||||
resize: [];
|
||||
}
|
||||
|
||||
@ -22,11 +22,6 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
|
||||
/** 更新标识符,如果发生变化则说明画布被动清空 */
|
||||
symbol: number = 0;
|
||||
|
||||
private _active: boolean = true;
|
||||
get active() {
|
||||
return this._active;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个新的离屏画布\
|
||||
* **注意**:如果你在自定义渲染元素中使用,请避免使用此构造函数,而应该使用 `RenderItem.requireCanvas`
|
||||
|
@ -43,7 +43,7 @@ export class Container<E extends EContainerEvent = EContainerEvent>
|
||||
}
|
||||
|
||||
onResize(scale: number): void {
|
||||
this.sortedChildren.forEach(v => v.onResize(scale));
|
||||
this.children.forEach(v => v.onResize(scale));
|
||||
super.onResize(scale);
|
||||
}
|
||||
|
||||
|
@ -283,6 +283,8 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
composite: GlobalCompositeOperation = 'source-over';
|
||||
/** 不透明度 */
|
||||
alpha: number = 1;
|
||||
/** 缩放比 */
|
||||
protected scale: number = 1;
|
||||
|
||||
/** 鼠标覆盖在此元素上时的光标样式 */
|
||||
cursor: string = 'inherit';
|
||||
@ -391,6 +393,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
this.cache = this.requireCanvas();
|
||||
if (!enableCache) {
|
||||
this.cache.size(1, 1);
|
||||
this.deleteCanvas(this.cache);
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,7 +459,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
* @param alpha 是否启用画布的 alpha 通道
|
||||
* @param autoScale 是否自动跟随缩放
|
||||
*/
|
||||
requireCanvas(alpha: boolean = true, autoScale: boolean = false) {
|
||||
requireCanvas(alpha: boolean = true, autoScale: boolean = true) {
|
||||
const canvas = new MotaOffscreenCanvas2D(alpha);
|
||||
this.canvases.add(canvas);
|
||||
this.canvasMap.set(canvas, { autoScale });
|
||||
@ -475,12 +478,20 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
//#region 事件处理
|
||||
|
||||
onResize(scale: number): void {
|
||||
this.cache.setScale(scale);
|
||||
this.scale = scale;
|
||||
this.canvases.forEach(v => {
|
||||
if (this.canvasMap.get(v)?.autoScale) {
|
||||
v.setScale(scale);
|
||||
}
|
||||
});
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前元素的缩放比,它与根元素应当保持一致
|
||||
*/
|
||||
getScale() {
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
//#region 修改元素属性
|
||||
@ -590,7 +601,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
/**
|
||||
* 获取当前元素的绝对位置(不建议使用,因为应当很少会有获取绝对位置的需求)
|
||||
*/
|
||||
getAbsolutePosition(x: number = 0, y: number = 0): LocArr {
|
||||
getAbsolutePosition(x: number = 0, y: number = 0): [number, number] {
|
||||
if (this.type === 'absolute') {
|
||||
if (this.parent) return this.parent.getAbsolutePosition(0, 0);
|
||||
else return [0, 0];
|
||||
@ -765,6 +776,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
this.checkRoot();
|
||||
this._root?.connect(this);
|
||||
this._transform.bind(this);
|
||||
this.onResize(parent.scale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,9 +42,6 @@ export interface MotaRendererConfig {
|
||||
export class MotaRenderer extends Container implements IRenderTreeRoot {
|
||||
static list: Map<string, MotaRenderer> = new Map();
|
||||
|
||||
/** 缩放比 */
|
||||
private scale: number = 1;
|
||||
|
||||
/** 所有连接到此根元素的渲染元素的 id 到元素自身的映射 */
|
||||
protected idMap: Map<string, RenderItem> = new Map();
|
||||
|
||||
@ -85,7 +82,6 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
||||
this.target.setAntiAliasing(false);
|
||||
|
||||
this.setAnchor(0.5, 0.5);
|
||||
this.transform.translate(240, 240);
|
||||
|
||||
MotaRenderer.list.set(canvas.id, this);
|
||||
|
||||
@ -105,17 +101,9 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
||||
* @param scale 缩放比
|
||||
*/
|
||||
setScale(scale: number) {
|
||||
this.scale = scale;
|
||||
this.onResize(scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取这个渲染器的缩放比
|
||||
*/
|
||||
getScale() {
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
onResize(scale: number): void {
|
||||
this.target.setScale(scale);
|
||||
const width = this.target.width * scale;
|
||||
@ -355,8 +343,8 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
||||
mouse: MouseType = this.getMouseType(event)
|
||||
): IActionEvent {
|
||||
const id = this.getMouseIdentifier(type, mouse);
|
||||
const x = event.offsetX / core.domStyle.scale;
|
||||
const y = event.offsetY / core.domStyle.scale;
|
||||
const x = event.offsetX / this.scale;
|
||||
const y = event.offsetY / this.scale;
|
||||
|
||||
return {
|
||||
target: this,
|
||||
@ -426,8 +414,8 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
||||
event: TouchEvent,
|
||||
rect: DOMRect
|
||||
): IActionEvent {
|
||||
const x = (touch.clientX - rect.left) / core.domStyle.scale;
|
||||
const y = (touch.clientY - rect.top) / core.domStyle.scale;
|
||||
const x = (touch.clientX - rect.left) / this.scale;
|
||||
const y = (touch.clientY - rect.top) / this.scale;
|
||||
return {
|
||||
target: this,
|
||||
identifier: this.getTouchIdentifier(touch, type),
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
} from '@motajs/render-core';
|
||||
import { logger } from '@motajs/common';
|
||||
import { clamp, isNil } from 'lodash-es';
|
||||
import { CanvasStyle } from './types';
|
||||
|
||||
export type CircleParams = [
|
||||
cx?: number,
|
||||
|
@ -2,3 +2,5 @@ export type SizedCanvasImageSource = Exclude<
|
||||
CanvasImageSource,
|
||||
VideoFrame | SVGElement
|
||||
>;
|
||||
|
||||
export type CanvasStyle = string | CanvasGradient | CanvasPattern;
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
ConatinerCustomProps,
|
||||
ContainerProps,
|
||||
CustomProps,
|
||||
DamageProps,
|
||||
EllipseProps,
|
||||
ImageProps,
|
||||
LineProps,
|
||||
@ -87,7 +86,6 @@ declare module 'vue/jsx-runtime' {
|
||||
image: TagDefine<ImageProps, EImageEvent>;
|
||||
comment: TagDefine<CommentProps, ERenderItemEvent>;
|
||||
custom: TagDefine<CustomProps, ERenderItemEvent>;
|
||||
damage: TagDefine<DamageProps, ERenderItemEvent>;
|
||||
'g-rect': TagDefine<RectProps, EGraphicItemEvent>;
|
||||
'g-circle': TagDefine<CirclesProps, EGraphicItemEvent>;
|
||||
'g-ellipse': TagDefine<EllipseProps, EGraphicItemEvent>;
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
} from '@motajs/render-core';
|
||||
import {
|
||||
BezierParams,
|
||||
CanvasStyle,
|
||||
CircleParams,
|
||||
EllipseParams,
|
||||
ILineProperty,
|
||||
@ -19,7 +20,6 @@ import {
|
||||
RectREllipseParams
|
||||
} from '@motajs/render-elements';
|
||||
import { Font } from '@motajs/render-style';
|
||||
import { IEnemyCollection } from '@motajs/types';
|
||||
|
||||
export interface CustomProps {
|
||||
_item: (props: BaseProps) => RenderItem;
|
||||
@ -122,16 +122,6 @@ export interface CommentProps extends BaseProps {
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export interface DamageProps extends BaseProps {
|
||||
mapWidth?: number;
|
||||
mapHeight?: number;
|
||||
cellSize?: number;
|
||||
enemy?: IEnemyCollection;
|
||||
font?: string;
|
||||
strokeStyle?: CanvasStyle;
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
export interface GraphicPropsBase extends BaseProps, Partial<ILineProperty> {
|
||||
/** 是否填充,若填写 {@link stroke},那么表现为先填充后描边 */
|
||||
fill?: boolean;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Animation, Ticker, Transition } from 'mutate-animate';
|
||||
import { ERenderItemEvent, RenderItem } from '@motajs/render-core';
|
||||
import { gameKey, Hotkey } from '@motajs/system-action';
|
||||
import { onMounted, onUnmounted } from 'vue';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
@ -44,25 +43,6 @@ export function useTransition(): TransitionUsing {
|
||||
return [tran];
|
||||
}
|
||||
|
||||
type KeyUsing = [Hotkey, symbol];
|
||||
|
||||
/**
|
||||
* 在组件中定义按键操作
|
||||
* @param noScope 是否不创建新作用域
|
||||
*/
|
||||
export function useKey(noScope: boolean = false): KeyUsing {
|
||||
if (noScope) {
|
||||
return [gameKey, gameKey.scope];
|
||||
} else {
|
||||
const sym = Symbol();
|
||||
gameKey.use(sym);
|
||||
onUnmounted(() => {
|
||||
gameKey.dispose();
|
||||
});
|
||||
return [gameKey, sym];
|
||||
}
|
||||
}
|
||||
|
||||
export function onEvent<
|
||||
T extends ERenderItemEvent,
|
||||
K extends EventEmitter.EventNames<T>
|
||||
|
1
packages/render/README.md
Normal file
1
packages/render/README.md
Normal file
@ -0,0 +1 @@
|
||||
Documentation is working...
|
@ -1,9 +1,41 @@
|
||||
{
|
||||
"name": "@motajs/render",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/render.cjs.js",
|
||||
"module": "dist/render.es.js",
|
||||
"types": "dist/render.es.d.ts",
|
||||
"keywords": [
|
||||
"render",
|
||||
"game",
|
||||
"vue",
|
||||
"graphics"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/unanmed/HumanBreak/tree/dev"
|
||||
},
|
||||
"author": {
|
||||
"name": "AncTe",
|
||||
"email": "1319491857@qq.com"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/render.es.js",
|
||||
"require": "./dist/render.cjs.js",
|
||||
"types": "./dist/render.es.d.ts"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@motajs/render-core": "workspace:*",
|
||||
"@motajs/render-elements": "workspace:*",
|
||||
"@motajs/render-style": "workspace:*",
|
||||
"@motajs/render-vue": "workspace:*"
|
||||
}
|
||||
}
|
||||
"eventemitter3": "^5.0.1",
|
||||
"gl-matrix": "^3.4.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mutate-animate": "^1.4.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"license": "LGPL-3.0-only"
|
||||
}
|
||||
|
2265
pnpm-lock.yaml
2265
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -330,7 +330,9 @@ main.prototype.loadAsync = async function (mode, callback) {
|
||||
core.domStyle.scale = window.innerWidth / core._PX_;
|
||||
}
|
||||
Mota.r(() => {
|
||||
Mota.require('@motajs/render').MotaOffscreenCanvas2D.refreshAll();
|
||||
Mota.require('@user/client-modules').mainRenderer.setScale(
|
||||
core.domStyle.scale
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1,30 +1,55 @@
|
||||
import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
|
||||
import legacy from '@vitejs/plugin-legacy';
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
const outputDir = path.resolve(__dirname, '../dist/game');
|
||||
const outputDir = path.resolve('./dist/game');
|
||||
|
||||
// 清空 dist/game 目录
|
||||
fs.emptyDirSync(outputDir);
|
||||
|
||||
// 构建游戏
|
||||
async function buildGame() {
|
||||
const configFile = path.resolve(__dirname, '../vite.config.ts');
|
||||
const configFile = path.resolve('./vite.config.ts');
|
||||
const config = await loadConfigFromFile(
|
||||
{ command: 'build', mode: 'production' },
|
||||
configFile
|
||||
);
|
||||
const resolved = mergeConfig(config?.config ?? {}, {
|
||||
plugins: [
|
||||
legacy({
|
||||
targets: [
|
||||
'Chrome >= 56',
|
||||
'Firefox >= 51',
|
||||
'Edge >= 79',
|
||||
'Safari >= 15',
|
||||
'Opera >= 43'
|
||||
],
|
||||
polyfills: true,
|
||||
modernPolyfills: true
|
||||
})
|
||||
],
|
||||
build: {
|
||||
outDir: outputDir,
|
||||
sourcemap: true,
|
||||
rollupOptions: {
|
||||
input: path.resolve(__dirname, '../src/main.ts'),
|
||||
input: path.resolve('./src/main.ts'),
|
||||
output: {
|
||||
format: 'es',
|
||||
entryFileNames: '[name].[hash].js',
|
||||
chunkFileNames: 'chunks/[name].[hash].js',
|
||||
assetFileNames: 'assets/[name].[hash][extname]'
|
||||
assetFileNames: 'assets/[name].[hash][extname]',
|
||||
manualChunks: {
|
||||
antdv: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||
common: [
|
||||
'lodash-es',
|
||||
'axios',
|
||||
'lz-string',
|
||||
'chart.js',
|
||||
'mutate-animate',
|
||||
'@vueuse/core'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
65
script/build-lib.ts
Normal file
65
script/build-lib.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import dts from 'vite-plugin-dts';
|
||||
|
||||
const packages = path.resolve(process.cwd(), './packages');
|
||||
|
||||
// 获取所有包目录
|
||||
const packageDirs = ['render'];
|
||||
|
||||
// 构建每一个包
|
||||
async function buildPackages() {
|
||||
for (const packageName of packageDirs) {
|
||||
const packageDir = path.join(packages, packageName);
|
||||
const output = path.join(packageDir, 'dist');
|
||||
await fs.emptyDir(output);
|
||||
const configFile = path.resolve('./vite.config.ts');
|
||||
const config = await loadConfigFromFile(
|
||||
{ command: 'build', mode: 'production' },
|
||||
configFile
|
||||
);
|
||||
const resolved = mergeConfig(config?.config ?? {}, {
|
||||
plugins: [
|
||||
dts({
|
||||
entryRoot: path.join(packageDir, 'src/index.ts'),
|
||||
rollupTypes: true,
|
||||
strictOutput: false,
|
||||
copyDtsFiles: false,
|
||||
exclude: ['packages-user/**/*']
|
||||
})
|
||||
],
|
||||
build: {
|
||||
lib: {
|
||||
entry: path.join(packageDir, 'src/index.ts'),
|
||||
name: packageName,
|
||||
formats: ['es', 'cjs'],
|
||||
fileName: format => `${packageName}.${format}.js`
|
||||
},
|
||||
outDir: output,
|
||||
sourcemap: true,
|
||||
emptyOutDir: true
|
||||
},
|
||||
publicDir: false
|
||||
} satisfies UserConfig);
|
||||
|
||||
await build(resolved);
|
||||
console.log(`✅ Package ${packageName} built successfully.`);
|
||||
}
|
||||
const dirs = await fs.readdir(packages);
|
||||
for (const name of dirs) {
|
||||
const dir = path.join(process.cwd(), name);
|
||||
if (name === 'types') {
|
||||
await fs.emptyDir(path.join(dir, 'src'));
|
||||
await fs.rmdir(path.join(dir, 'src'));
|
||||
} else {
|
||||
await fs.emptyDir(dir);
|
||||
await fs.rmdir(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildPackages().catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
@ -2,8 +2,8 @@ import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
const packagesDir = path.resolve(__dirname, '../packages');
|
||||
const outputDir = path.resolve(__dirname, '../dist/packages');
|
||||
const packagesDir = path.resolve('./packages');
|
||||
const outputDir = path.resolve('./dist/packages');
|
||||
|
||||
// 清空 dist 目录
|
||||
fs.emptyDirSync(outputDir);
|
||||
@ -18,7 +18,7 @@ const packageDirs = fs.readdirSync(packagesDir).filter(name => {
|
||||
async function buildPackages() {
|
||||
for (const packageName of packageDirs) {
|
||||
const packageDir = path.join(packagesDir, packageName);
|
||||
const configFile = path.resolve(__dirname, '../vite.config.ts');
|
||||
const configFile = path.resolve('./vite.config.ts');
|
||||
const config = await loadConfigFromFile(
|
||||
{ command: 'build', mode: 'production' },
|
||||
configFile
|
||||
@ -37,7 +37,8 @@ async function buildPackages() {
|
||||
rollupOptions: {
|
||||
external: [/node_modules/, /^@motajs\/.*/]
|
||||
}
|
||||
}
|
||||
},
|
||||
publicDir: false
|
||||
} satisfies UserConfig);
|
||||
|
||||
await build(resolved);
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import legacy from '@vitejs/plugin-legacy';
|
||||
import components from 'unplugin-vue-components/vite';
|
||||
import vuejsx from '@vitejs/plugin-vue-jsx'
|
||||
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
|
||||
import path, { resolve } from 'path';
|
||||
import path from 'path';
|
||||
import postcssPresetEnv from 'postcss-preset-env';
|
||||
import * as glob from 'glob'
|
||||
|
||||
@ -43,17 +42,6 @@ export default defineConfig({
|
||||
return custom.includes(tag) || tag.startsWith('g-');
|
||||
}
|
||||
}),
|
||||
legacy({
|
||||
targets: [
|
||||
'Chrome >= 56',
|
||||
'Firefox >= 51',
|
||||
'Edge >= 79',
|
||||
'Safari >= 15',
|
||||
'Opera >= 43'
|
||||
],
|
||||
polyfills: true,
|
||||
modernPolyfills: true
|
||||
}),
|
||||
components({ resolvers: [AntDesignVueResolver()] })
|
||||
],
|
||||
base: `./`,
|
||||
@ -63,23 +51,6 @@ export default defineConfig({
|
||||
...aliasesUser
|
||||
]
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
antdv: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||
common: [
|
||||
'lodash-es',
|
||||
'axios',
|
||||
'lz-string',
|
||||
'chart.js',
|
||||
'mutate-animate',
|
||||
'@vueuse/core'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
less: {
|
||||
|
Loading…
Reference in New Issue
Block a user