mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-11 15:47:06 +08:00
refactor: MotaOffscreenCanvas2D 的垃圾回收机制
This commit is contained in:
parent
e79c530c48
commit
ac5eefdb02
@ -3149,7 +3149,7 @@ control.prototype.resize = function () {
|
||||
core.domStyle.scale = target - 0.25;
|
||||
}
|
||||
|
||||
const pw = (480 + 180) * core.domStyle.scale;
|
||||
const pw = (480 + 180 * 2) * core.domStyle.scale;
|
||||
const ph = 480 * core.domStyle.scale;
|
||||
core.dom.gameDraw.style.width = `${pw}px`;
|
||||
core.dom.gameDraw.style.height = `${ph}px`;
|
||||
|
@ -33,8 +33,14 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
|
||||
return this._freezed;
|
||||
}
|
||||
|
||||
private _active: boolean = true;
|
||||
get active() {
|
||||
return this._active;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个新的离屏画布
|
||||
* 创建一个新的离屏画布\
|
||||
* **注意**:如果你在自定义渲染元素中使用,请避免使用此构造函数,而应该使用 `RenderItem.requireCanvas`
|
||||
* @param alpha 是否启用透明度通道
|
||||
* @param canvas 指定画布,不指定时会自动创建一个新画布
|
||||
*/
|
||||
@ -146,6 +152,27 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
|
||||
MotaOffscreenCanvas2D.list.delete(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使此画布生效,使用前请务必调用此函数,生效后会跟随游戏的放缩比例更改大小,但会导致不会被垃圾回收
|
||||
*/
|
||||
activate() {
|
||||
if (this._active || this._freezed) return;
|
||||
MotaOffscreenCanvas2D.list.add(this);
|
||||
if (this.autoScale) {
|
||||
this.size(this.width, this.height);
|
||||
this.symbol++;
|
||||
this.emit('resize');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使此画布失效,当这个画布暂时不会被使用时请务必调用此函数,失效后若没有对此画布的引用,那么会自动垃圾回收
|
||||
*/
|
||||
deactivate() {
|
||||
if (!this._active || this._freezed) return;
|
||||
MotaOffscreenCanvas2D.list.delete(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制一个离屏Canvas2D对象,一般用于缓存等操作
|
||||
* @param canvas 被复制的MotaOffscreenCanvas2D对象
|
||||
|
@ -316,13 +316,15 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
|
||||
//#region 渲染配置与缓存
|
||||
/** 渲染缓存信息 */
|
||||
protected cache: MotaOffscreenCanvas2D = new MotaOffscreenCanvas2D();
|
||||
protected cache: MotaOffscreenCanvas2D;
|
||||
/** 是否需要更新缓存 */
|
||||
protected cacheDirty: boolean = false;
|
||||
/** 是否启用缓存机制 */
|
||||
readonly enableCache: boolean = true;
|
||||
/** 是否启用transform下穿机制,即画布的变换是否会继续作用到下一层画布 */
|
||||
readonly transformFallThrough: boolean = false;
|
||||
/** 这个渲染元素使用到的所有画布 */
|
||||
protected readonly canvases: Set<MotaOffscreenCanvas2D> = new Set();
|
||||
//#endregion
|
||||
|
||||
//#region 交互事件
|
||||
@ -356,6 +358,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
this.type = type;
|
||||
|
||||
this._transform.bind(this);
|
||||
this.cache = this.requireCanvas();
|
||||
this.cache.withGameScale(true);
|
||||
}
|
||||
|
||||
@ -414,6 +417,16 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
this.emit('afterRender', transform);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请一个 `MotaOffscreenCanvas2D`,即申请一个画布
|
||||
* @param alpha 是否启用画布的 alpha 通道
|
||||
*/
|
||||
protected requireCanvas(alpha: boolean = true) {
|
||||
const canvas = new MotaOffscreenCanvas2D(alpha);
|
||||
this.canvases.add(canvas);
|
||||
return canvas;
|
||||
}
|
||||
|
||||
//#region 修改元素属性
|
||||
|
||||
/**
|
||||
@ -625,6 +638,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
this.update();
|
||||
this.checkRoot();
|
||||
this._root?.connect(this);
|
||||
this.canvases.forEach(v => v.activate());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -638,6 +652,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
||||
this._parent = void 0;
|
||||
parent.requestSort();
|
||||
parent.update();
|
||||
this.canvases.forEach(v => v.deactivate());
|
||||
if (!success) return false;
|
||||
this._root?.disconnect(this);
|
||||
this._root = void 0;
|
||||
|
@ -498,8 +498,7 @@ export class Damage extends RenderItem<EDamageEvent> {
|
||||
this.emit('dirtyUpdate', v);
|
||||
|
||||
// 否则依次渲染并写入缓存
|
||||
const temp =
|
||||
block.cache.get(v)?.canvas ?? new MotaOffscreenCanvas2D();
|
||||
const temp = block.cache.get(v)?.canvas ?? this.requireCanvas();
|
||||
temp.clear();
|
||||
temp.setHD(true);
|
||||
temp.setAntiAliasing(true);
|
||||
|
@ -10,7 +10,6 @@ import { Transform } from '../transform';
|
||||
import { LayerFloorBinder, LayerGroupFloorBinder } from './floor';
|
||||
import { RenderAdapter } from '../adapter';
|
||||
import { ElementNamespace, ComponentInternalInstance } from 'vue';
|
||||
import { Camera } from '../camera';
|
||||
import { IAnimateFrame, renderEmits } from '../frame';
|
||||
|
||||
export interface ILayerGroupRenderExtends {
|
||||
@ -358,7 +357,7 @@ export class LayerGroup
|
||||
return;
|
||||
}
|
||||
case 'camera':
|
||||
if (!this.assertType(nextValue, Camera, key)) return;
|
||||
if (!this.assertType(nextValue, Transform, key)) return;
|
||||
this.camera = nextValue;
|
||||
return;
|
||||
}
|
||||
@ -571,11 +570,11 @@ export class Layer extends Container<ELayerEvent> {
|
||||
static readonly FRAME_ALL = 15;
|
||||
|
||||
/** 静态层,包含除大怪物及正在移动的内容外的内容 */
|
||||
protected staticMap: MotaOffscreenCanvas2D = new MotaOffscreenCanvas2D();
|
||||
protected staticMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
||||
/** 移动层,包含大怪物及正在移动的内容 */
|
||||
protected movingMap: MotaOffscreenCanvas2D = new MotaOffscreenCanvas2D();
|
||||
protected movingMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
||||
/** 背景图层 */
|
||||
protected backMap: MotaOffscreenCanvas2D = new MotaOffscreenCanvas2D();
|
||||
protected backMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
||||
|
||||
/** 最终渲染至的Sprite */
|
||||
main: Sprite = new Sprite('absolute', false, true);
|
||||
@ -783,12 +782,12 @@ export class Layer extends Container<ELayerEvent> {
|
||||
if (!data) return;
|
||||
|
||||
const frame = data.frame;
|
||||
const temp = new MotaOffscreenCanvas2D();
|
||||
const temp = this.requireCanvas();
|
||||
temp.setHD(false);
|
||||
temp.setAntiAliasing(false);
|
||||
temp.withGameScale(false);
|
||||
for (let i = 0; i < frame; i++) {
|
||||
const canvas = new MotaOffscreenCanvas2D();
|
||||
const canvas = this.requireCanvas();
|
||||
const ctx = canvas.ctx;
|
||||
const tempCtx = temp.ctx;
|
||||
const [sx, sy, w, h] = data.render[i];
|
||||
@ -1206,7 +1205,7 @@ export class Layer extends Container<ELayerEvent> {
|
||||
const ex = Math.min(sx + blockSize, this.mapWidth);
|
||||
const ey = Math.min(sy + blockSize, this.mapHeight);
|
||||
|
||||
const temp = new MotaOffscreenCanvas2D();
|
||||
const temp = this.requireCanvas();
|
||||
temp.setAntiAliasing(false);
|
||||
temp.setHD(false);
|
||||
temp.withGameScale(false);
|
||||
@ -1478,7 +1477,7 @@ export class Layer extends Container<ELayerEvent> {
|
||||
return;
|
||||
case 'floorImage':
|
||||
if (!this.assertType(nextValue, Array, key)) return;
|
||||
this.setFloorImage(nextValue);
|
||||
this.setFloorImage(nextValue as FloorAnimate[]);
|
||||
return;
|
||||
}
|
||||
super.patchProp(key, prevValue, nextValue, namespace, parentComponent);
|
||||
|
@ -19,7 +19,7 @@ export class Text extends RenderItem<ETextEvent> {
|
||||
|
||||
fillStyle?: CanvasStyle = '#fff';
|
||||
strokeStyle?: CanvasStyle;
|
||||
font?: string = '';
|
||||
font: string = '16px Verdana';
|
||||
strokeWidth: number = 1;
|
||||
|
||||
private length: number = 0;
|
||||
@ -42,7 +42,7 @@ export class Text extends RenderItem<ETextEvent> {
|
||||
ctx.textBaseline = 'bottom';
|
||||
ctx.fillStyle = this.fillStyle ?? 'transparent';
|
||||
ctx.strokeStyle = this.strokeStyle ?? 'transparent';
|
||||
ctx.font = this.font ?? '';
|
||||
ctx.font = this.font;
|
||||
ctx.lineWidth = this.strokeWidth;
|
||||
|
||||
if (this.strokeStyle) {
|
||||
@ -59,7 +59,7 @@ export class Text extends RenderItem<ETextEvent> {
|
||||
measure() {
|
||||
const ctx = Text.measureCanvas.ctx;
|
||||
ctx.textBaseline = 'bottom';
|
||||
ctx.font = this.font ?? '';
|
||||
ctx.font = this.font;
|
||||
const res = ctx.measureText(this.text);
|
||||
return res;
|
||||
}
|
||||
|
42
src/module/render/components/misc.tsx
Normal file
42
src/module/render/components/misc.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import { ElementLocator, Sprite } from '@/core/render';
|
||||
import { defineComponent, onMounted, ref, watch } from 'vue';
|
||||
import { SetupComponentOptions } from './types';
|
||||
|
||||
interface ProgressProps {
|
||||
/** 进度条的位置 */
|
||||
loc: ElementLocator;
|
||||
/** 进度条的进度,1表示完成,0表示未完成 */
|
||||
progress: number;
|
||||
/** 已完成部分的样式,默认为绿色(green) */
|
||||
success?: CanvasStyle;
|
||||
/** 未完成部分的样式,默认为灰色(gray) */
|
||||
background?: CanvasStyle;
|
||||
}
|
||||
|
||||
const progressProps = {
|
||||
props: ['loc', 'progress', 'success', 'background']
|
||||
} satisfies SetupComponentOptions<ProgressProps>;
|
||||
|
||||
export const Progress = defineComponent<ProgressProps>(props => {
|
||||
const element = ref<Sprite>();
|
||||
|
||||
onMounted(() => {
|
||||
element.value?.setRenderFn(canvas => {
|
||||
const { ctx } = canvas;
|
||||
const width = props.loc[2] ?? 200;
|
||||
const height = props.loc[3] ?? 200;
|
||||
ctx.fillStyle = props.background ?? 'gray';
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
ctx.fillStyle = props.success ?? 'green';
|
||||
ctx.fillRect(0, 0, width * props.progress, height);
|
||||
});
|
||||
});
|
||||
|
||||
watch(props, () => {
|
||||
element.value?.update();
|
||||
});
|
||||
|
||||
return () => {
|
||||
return <sprite ref={element} loc={props.loc}></sprite>;
|
||||
};
|
||||
}, progressProps);
|
@ -6,5 +6,5 @@ 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_WIDTH = 480 + 180 * 2;
|
||||
export const MAIN_HEIGHT = 480;
|
||||
|
@ -26,7 +26,12 @@ import {
|
||||
STATUS_BAR_HEIGHT,
|
||||
STATUS_BAR_WIDTH
|
||||
} from '../shared';
|
||||
import { IHeroStatus, StatusBar } from './statusBar';
|
||||
import {
|
||||
ILeftHeroStatus,
|
||||
IRightHeroStatus,
|
||||
LeftStatusBar,
|
||||
RightStatusBar
|
||||
} from './statusBar';
|
||||
import { onLoaded } from '../use';
|
||||
|
||||
const MainScene = defineComponent(() => {
|
||||
@ -71,25 +76,58 @@ const MainScene = defineComponent(() => {
|
||||
weather.bind(map.value);
|
||||
});
|
||||
|
||||
const status: IHeroStatus = reactive({
|
||||
const leftStatus: ILeftHeroStatus = reactive({
|
||||
hp: 0,
|
||||
atk: 0,
|
||||
def: 0,
|
||||
mdef: 0
|
||||
mdef: 0,
|
||||
money: 0,
|
||||
exp: 0,
|
||||
yellowKey: 0,
|
||||
blueKey: 0,
|
||||
redKey: 0,
|
||||
floor: 'MT0',
|
||||
lv: '',
|
||||
regen: 0,
|
||||
exAtk: 0,
|
||||
magicDef: 0
|
||||
});
|
||||
const rightStatus: IRightHeroStatus = reactive({});
|
||||
|
||||
const { getHeroStatusOn } = Mota.requireAll('fn');
|
||||
|
||||
const updateStatus = () => {
|
||||
const hero = core.status.hero;
|
||||
leftStatus.atk = getHeroStatusOn('atk');
|
||||
leftStatus.hp = getHeroStatusOn('hp');
|
||||
leftStatus.def = getHeroStatusOn('def');
|
||||
leftStatus.mdef = getHeroStatusOn('mdef');
|
||||
leftStatus.money = getHeroStatusOn('money');
|
||||
leftStatus.exp = core.getNextLvUpNeed() ?? 0;
|
||||
leftStatus.yellowKey = core.itemCount('yellowKey');
|
||||
leftStatus.blueKey = core.itemCount('blueKey');
|
||||
leftStatus.redKey = core.itemCount('redKey');
|
||||
leftStatus.floor = core.status.floorId;
|
||||
leftStatus.lv = core.getLvName(hero.lv);
|
||||
leftStatus.regen = getHeroStatusOn('hpmax');
|
||||
leftStatus.exAtk = getHeroStatusOn('mana');
|
||||
leftStatus.magicDef = getHeroStatusOn('magicDef');
|
||||
};
|
||||
|
||||
const loaded = ref(false);
|
||||
onLoaded(() => {
|
||||
loaded.value = true;
|
||||
});
|
||||
|
||||
Mota.require('var', 'hook').on('statusBarUpdate', updateStatus);
|
||||
|
||||
return () => (
|
||||
<container id="main-scene" width={MAIN_WIDTH} height={MAIN_HEIGHT}>
|
||||
{loaded.value && (
|
||||
<StatusBar
|
||||
<LeftStatusBar
|
||||
loc={[0, 0, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT]}
|
||||
status={status}
|
||||
></StatusBar>
|
||||
status={leftStatus}
|
||||
></LeftStatusBar>
|
||||
)}
|
||||
<container id="map-draw" {...mapDrawProps} x={180} zIndex={10}>
|
||||
<layer-group id="layer-main" ex={layerGroupExtends} ref={map}>
|
||||
@ -103,6 +141,12 @@ const MainScene = defineComponent(() => {
|
||||
<Textbox id="main-textbox" {...mainTextboxProps}></Textbox>
|
||||
<FloorChange id="floor-change" zIndex={50}></FloorChange>
|
||||
</container>
|
||||
{loaded.value && (
|
||||
<RightStatusBar
|
||||
loc={[480 + 180, 0, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT]}
|
||||
status={rightStatus}
|
||||
></RightStatusBar>
|
||||
)}
|
||||
{mainUIController.render()}
|
||||
</container>
|
||||
);
|
||||
|
@ -3,54 +3,181 @@ import { defineComponent } from 'vue';
|
||||
import { SetupComponentOptions } from '../components';
|
||||
import { ElementLocator } from '@/core/render';
|
||||
|
||||
export interface IHeroStatus {
|
||||
export interface ILeftHeroStatus {
|
||||
hp: number;
|
||||
atk: number;
|
||||
def: number;
|
||||
mdef: number;
|
||||
money: number;
|
||||
exp: number;
|
||||
yellowKey: number;
|
||||
blueKey: number;
|
||||
redKey: number;
|
||||
floor: FloorIds;
|
||||
lv: string;
|
||||
/** 生命回复 */
|
||||
regen: number;
|
||||
/** 额外攻击 */
|
||||
exAtk: number;
|
||||
/** 魔法防御 */
|
||||
magicDef: number;
|
||||
}
|
||||
|
||||
interface StatusBarProps {
|
||||
export interface IRightHeroStatus {}
|
||||
|
||||
interface StatusBarProps<T> {
|
||||
loc: ElementLocator;
|
||||
status: IHeroStatus;
|
||||
status: T;
|
||||
}
|
||||
|
||||
const statusBarProps = {
|
||||
props: ['loc', 'status']
|
||||
} satisfies SetupComponentOptions<StatusBarProps>;
|
||||
} satisfies SetupComponentOptions<StatusBarProps<unknown>>;
|
||||
|
||||
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'];
|
||||
export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>(
|
||||
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 moneyIcon = core.material.images.images['money.png'];
|
||||
const expIcon = core.material.images.images['exp.png'];
|
||||
|
||||
const s = p.status;
|
||||
const f = core.formatBigNumber;
|
||||
const s = p.status;
|
||||
const f = core.formatBigNumber;
|
||||
|
||||
const iconLoc = (n: number): ElementLocator => {
|
||||
return [16, 16 + 48 * n, 32, 32];
|
||||
};
|
||||
const floorName = core.floors[s.floor].title;
|
||||
|
||||
const textLoc = (n: number): ElementLocator => {
|
||||
return [64, 32 + 48 * n, void 0, void 0, 0.5, 0.5];
|
||||
};
|
||||
const key = (num: number) => {
|
||||
return num.toString().padStart(2, '0');
|
||||
};
|
||||
|
||||
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);
|
||||
const font1 = '18px normal';
|
||||
const font2 = 'bold 18px normal';
|
||||
const font3 = 'bold 14px normal';
|
||||
|
||||
export const statusBarUI = new GameUI('status-bar', StatusBar);
|
||||
const iconLoc = (n: number): ElementLocator => {
|
||||
return [16, 76 + 44 * n, 32, 32];
|
||||
};
|
||||
|
||||
const textLoc = (n: number): ElementLocator => {
|
||||
return [60, 92 + 44 * n, void 0, void 0, 0, 0.5];
|
||||
};
|
||||
|
||||
const central = (y: number): ElementLocator => {
|
||||
const width = p.loc[2] ?? 200;
|
||||
return [width / 2, y, void 0, void 0, 0.5, 0.5];
|
||||
};
|
||||
|
||||
const right = (y: number): ElementLocator => {
|
||||
const width = p.loc[2] ?? 200;
|
||||
return [width - 16, y, void 0, void 0, 1, 0.5];
|
||||
};
|
||||
|
||||
const keyCount = 3;
|
||||
const keyY = 92 + 44 * 6;
|
||||
const keyLoc = (n: number): ElementLocator => {
|
||||
const width = p.loc[2] ?? 200;
|
||||
const per = width / (keyCount + 1);
|
||||
return [per * (n + 1), keyY, 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>
|
||||
<text
|
||||
text={floorName}
|
||||
loc={central(24)}
|
||||
font={font1}
|
||||
cursor="pointer"
|
||||
></text>
|
||||
<text text={s.lv} loc={central(54)} font={font1}></text>
|
||||
<image image={hpIcon} loc={iconLoc(0)}></image>
|
||||
<text text={f(s.hp)} loc={textLoc(0)} font={font1}></text>
|
||||
<text
|
||||
text={`+${f(s.regen)}/t`}
|
||||
loc={right(110)}
|
||||
font={font3}
|
||||
fillStyle="#a7ffa7"
|
||||
></text>
|
||||
<image image={atkIcon} loc={iconLoc(1)}></image>
|
||||
<text text={f(s.atk)} loc={textLoc(1)} font={font1}></text>
|
||||
<text
|
||||
text={`+${f(s.exAtk)}`}
|
||||
loc={right(154)}
|
||||
font={font3}
|
||||
fillStyle="#ffd3d3"
|
||||
></text>
|
||||
<image image={defIcon} loc={iconLoc(2)}></image>
|
||||
<text text={f(s.def)} loc={textLoc(2)} font={font1}></text>
|
||||
{s.magicDef > 0 && (
|
||||
<text
|
||||
text={`+${f(s.magicDef)}`}
|
||||
loc={right(198)}
|
||||
font={font3}
|
||||
fillStyle="#b0bdff"
|
||||
></text>
|
||||
)}
|
||||
<image image={mdefIcon} loc={iconLoc(3)}></image>
|
||||
<text text={f(s.mdef)} loc={textLoc(3)} font={font1}></text>
|
||||
<image image={moneyIcon} loc={iconLoc(4)}></image>
|
||||
<text
|
||||
text={f(s.money)}
|
||||
loc={textLoc(4)}
|
||||
font={font1}
|
||||
></text>
|
||||
<image image={expIcon} loc={iconLoc(5)}></image>
|
||||
<text text={f(s.exp)} loc={textLoc(5)} font={font1}></text>
|
||||
<text
|
||||
text={key(s.yellowKey)}
|
||||
loc={keyLoc(0)}
|
||||
font={font2}
|
||||
fillStyle="#fca"
|
||||
></text>
|
||||
<text
|
||||
text={key(s.blueKey)}
|
||||
loc={keyLoc(1)}
|
||||
font={font2}
|
||||
fillStyle="#aad"
|
||||
></text>
|
||||
<text
|
||||
text={key(s.redKey)}
|
||||
loc={keyLoc(2)}
|
||||
font={font2}
|
||||
fillStyle="#f88"
|
||||
></text>
|
||||
<text
|
||||
text="技能树"
|
||||
loc={central(396)}
|
||||
font={font1}
|
||||
cursor="pointer"
|
||||
></text>
|
||||
<text
|
||||
text="查看技能"
|
||||
loc={central(428)}
|
||||
font={font1}
|
||||
cursor="pointer"
|
||||
></text>
|
||||
</container>
|
||||
);
|
||||
};
|
||||
},
|
||||
statusBarProps
|
||||
);
|
||||
|
||||
export const RightStatusBar = defineComponent<StatusBarProps<IRightHeroStatus>>(
|
||||
p => {
|
||||
return () => {
|
||||
return (
|
||||
<container loc={p.loc}>
|
||||
<g-rect loc={[0, 0, p.loc[2], p.loc[3]]} stroke></g-rect>
|
||||
</container>
|
||||
);
|
||||
};
|
||||
},
|
||||
statusBarProps
|
||||
);
|
||||
|
||||
export const leftStatusBarUI = new GameUI('left-status-bar', LeftStatusBar);
|
||||
export const rightStatusBarUI = new GameUI('right-status-bar', RightStatusBar);
|
||||
|
@ -262,7 +262,9 @@ onUnmounted(() => {
|
||||
font-size: 200%;
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
text-shadow: 3px 2px 3px #000, 0px 0px 3px #111;
|
||||
text-shadow:
|
||||
3px 2px 3px #000,
|
||||
0px 0px 3px #111;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
@ -303,7 +305,9 @@ onUnmounted(() => {
|
||||
font-size: 200%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
text-shadow: 3px 2px 3px #000, 0px 0px 3px #111;
|
||||
text-shadow:
|
||||
3px 2px 3px #000,
|
||||
0px 0px 3px #111;
|
||||
}
|
||||
|
||||
#status-lv {
|
||||
@ -311,7 +315,9 @@ onUnmounted(() => {
|
||||
font-size: 200%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
text-shadow: 3px 2px 3px #000, 0px 0px 3px #111;
|
||||
text-shadow:
|
||||
3px 2px 3px #000,
|
||||
0px 0px 3px #111;
|
||||
}
|
||||
|
||||
.status-extra {
|
||||
|
Loading…
Reference in New Issue
Block a user