Compare commits

..

8 Commits

9 changed files with 437 additions and 132 deletions

View File

@ -19,6 +19,7 @@ import {
Layer, Layer,
calNeedRenderOf calNeedRenderOf
} from './layer'; } from './layer';
import { MAP_BLOCK_WIDTH, MAP_HEIGHT, MAP_WIDTH } from '../shared';
/** /**
* *
@ -167,9 +168,9 @@ export class Damage extends RenderItem<EDamageEvent> {
constructor() { constructor() {
super('absolute', false, true); super('absolute', false, true);
this.block = new BlockCacher(0, 0, core._WIDTH_, 1); this.block = new BlockCacher(0, 0, MAP_BLOCK_WIDTH, 1);
this.type = 'absolute'; this.type = 'absolute';
this.size(core._PX_, core._PY_); this.size(MAP_WIDTH, MAP_HEIGHT);
this.setHD(true); this.setHD(true);
this.setAntiAliasing(true); this.setAntiAliasing(true);
} }

View File

@ -3,6 +3,12 @@ import { HeroRenderer } from './hero';
import { ILayerGroupRenderExtends, LayerGroup } from './layer'; import { ILayerGroupRenderExtends, LayerGroup } from './layer';
import { LayerGroupFloorBinder } from './layer'; import { LayerGroupFloorBinder } from './layer';
import { hyper, TimingFn } from 'mutate-animate'; import { hyper, TimingFn } from 'mutate-animate';
import {
MAP_BLOCK_HEIGHT,
MAP_BLOCK_WIDTH,
MAP_HEIGHT,
MAP_WIDTH
} from '../shared';
export class FloorViewport implements ILayerGroupRenderExtends { export class FloorViewport implements ILayerGroupRenderExtends {
id: string = 'viewport'; id: string = 'viewport';
@ -62,8 +68,8 @@ export class FloorViewport implements ILayerGroupRenderExtends {
this.enabled = true; this.enabled = true;
const { x, y } = core.status.hero.loc; const { x, y } = core.status.hero.loc;
const { x: nx, y: ny } = this.group.camera; const { x: nx, y: ny } = this.group.camera;
const halfWidth = core._PX_ / 2; const halfWidth = MAP_WIDTH / 2;
const halfHeight = core._PY_ / 2; const halfHeight = MAP_HEIGHT / 2;
const cell = this.group.cellSize; const cell = this.group.cellSize;
const half = cell / 2; const half = cell / 2;
this.applyPosition( this.applyPosition(
@ -94,8 +100,8 @@ export class FloorViewport implements ILayerGroupRenderExtends {
getBoundedPosition(x: number, y: number) { getBoundedPosition(x: number, y: number) {
if (!this.checkDependency()) return { x, y }; if (!this.checkDependency()) return { x, y };
if (!this.boundX && !this.boundY) return { x, y }; if (!this.boundX && !this.boundY) return { x, y };
const width = core._WIDTH_; const width = MAP_BLOCK_WIDTH;
const height = core._HEIGHT_; const height = MAP_BLOCK_HEIGHT;
const minX = (width - 1) / 2; const minX = (width - 1) / 2;
const minY = (height - 1) / 2; const minY = (height - 1) / 2;
const floor = core.status.maps[this.binder!.getFloor()]; const floor = core.status.maps[this.binder!.getFloor()];
@ -201,7 +207,7 @@ export class FloorViewport implements ILayerGroupRenderExtends {
this.applyPosition(nx, ny); this.applyPosition(nx, ny);
if (ending) { if (ending) {
if (this.ox === xTarget && this.oy == yTarget) { if (this.ox === xTarget && this.oy === yTarget) {
this.hero!.off('moveTick', this.movingFramer); this.hero!.off('moveTick', this.movingFramer);
return; return;
} }
@ -276,8 +282,8 @@ export class FloorViewport implements ILayerGroupRenderExtends {
private applyPosition(x: number, y: number) { private applyPosition(x: number, y: number) {
if (!this.enabled) return; if (!this.enabled) return;
if (x === this.nx && y === this.ny) return; if (x === this.nx && y === this.ny) return;
const halfWidth = core._PX_ / 2; const halfWidth = MAP_WIDTH / 2;
const halfHeight = core._PY_ / 2; const halfHeight = MAP_HEIGHT / 2;
const cell = this.group.cellSize; const cell = this.group.cellSize;
const half = cell / 2; const half = cell / 2;
this.nx = x; this.nx = x;

View File

@ -9,6 +9,7 @@ import {
LayerGroupFloorBinder, LayerGroupFloorBinder,
FloorViewport FloorViewport
} from './elements'; } from './elements';
import { MAP_WIDTH } from './shared';
const loopMaps = MiscData.loopMaps; const loopMaps = MiscData.loopMaps;
@ -71,13 +72,13 @@ function enableLoopMapElement(floorId: FloorIds) {
// 这个是计算循环地图应该显示在哪 // 这个是计算循环地图应该显示在哪
const [, y2] = transform.transformed(x1 - testPos, 0); const [, y2] = transform.transformed(x1 - testPos, 0);
camera.reset(); camera.reset();
camera.translate(core._PX_ - testPos, y2); camera.translate(MAP_WIDTH - testPos, y2);
loopLayer.pos(transform.x - core._PX_, 0); loopLayer.pos(transform.x - MAP_WIDTH, 0);
loopLayer.show(); loopLayer.show();
loopLayer.update(loopLayer); loopLayer.update(loopLayer);
} else { } else {
const [x2, y2] = transform.transformed(testPos, 0); const [x2, y2] = transform.transformed(testPos, 0);
if (x2 < core._PX_) { if (x2 < MAP_WIDTH) {
// 这个不用做其他运算,可以直接显示 // 这个不用做其他运算,可以直接显示
camera.reset(); camera.reset();
camera.translate(0, y2); camera.translate(0, y2);

View File

@ -8,9 +8,9 @@ import { Font } from '@motajs/render-style';
/** 每个格子的宽高 */ /** 每个格子的宽高 */
export const CELL_SIZE = 32; export const CELL_SIZE = 32;
/** 地图格子宽度,此处仅影响画面,不影响游戏内逻辑,游戏内逻辑地图大小请在 core.js 中修改 */ /** 地图格子宽度,此处仅影响画面,不影响游戏内逻辑,游戏内逻辑地图大小请在 core.js 中修改 */
export const MAP_BLOCK_WIDTH = 15; export const MAP_BLOCK_WIDTH = 13;
/** 地图格子高度,此处仅影响画面,不影响游戏内逻辑,游戏内逻辑地图大小请在 core.js 中修改 */ /** 地图格子高度,此处仅影响画面,不影响游戏内逻辑,游戏内逻辑地图大小请在 core.js 中修改 */
export const MAP_BLOCK_HEIGHT = 15; export const MAP_BLOCK_HEIGHT = 13;
/** 地图像素宽度 */ /** 地图像素宽度 */
export const MAP_WIDTH = CELL_SIZE * MAP_BLOCK_WIDTH; export const MAP_WIDTH = CELL_SIZE * MAP_BLOCK_WIDTH;
/** 地图像素高度 */ /** 地图像素高度 */
@ -29,7 +29,7 @@ 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 = false;
/** 状态栏数量,启用右侧状态栏为两个,不启用为一个 */ /** 状态栏数量,启用右侧状态栏为两个,不启用为一个 */
export const STATUS_BAR_COUNT = ENABLE_RIGHT_STATUS_BAR ? 2 : 1; export const STATUS_BAR_COUNT = ENABLE_RIGHT_STATUS_BAR ? 2 : 1;
/** 状态栏宽度的一半 */ /** 状态栏宽度的一半 */
@ -75,7 +75,7 @@ export const SAVE_ITEM_DOWN = 24;
/** 单个存档高度,包括存档下方的信息 */ /** 单个存档高度,包括存档下方的信息 */
export const SAVE_ITEM_HEIGHT = SAVE_ITEM_SIZE + SAVE_ITEM_TOP + SAVE_ITEM_DOWN; export const SAVE_ITEM_HEIGHT = SAVE_ITEM_SIZE + SAVE_ITEM_TOP + SAVE_ITEM_DOWN;
/** 存档间距 */ /** 存档间距 */
export const SAVE_INTERVAL = 30; export const SAVE_INTERVAL = 20;
/** 存档下巴高度,即下方显示页码和返回按钮的高度 */ /** 存档下巴高度,即下方显示页码和返回按钮的高度 */
export const SAVE_DOWN_PAD = 30; export const SAVE_DOWN_PAD = 30;
/** 存档页码数,调高并不会影响性能,但是如果玩家存档太多的话会导致存档体积很大 */ /** 存档页码数,调高并不会影响性能,但是如果玩家存档太多的话会导致存档体积很大 */

View File

@ -108,14 +108,25 @@ const MainScene = defineComponent(() => {
}); });
const leftStatus: ILeftHeroStatus = reactive({ const leftStatus: ILeftHeroStatus = reactive({
hp: 0, hp: 0,
hpmax: 0,
mana: 0,
manamax: 0,
atk: 0, atk: 0,
def: 0, def: 0,
mdef: 0, mdef: 0,
money: 0, money: 0,
exp: 0, exp: 0,
up: 0,
yellowKey: 0, yellowKey: 0,
blueKey: 0, blueKey: 0,
redKey: 0, redKey: 0,
greenKey: 0,
pickaxe: 0,
bomb: 0,
centerFly: 0,
poison: false,
weak: false,
curse: false,
floor: 'MT0', floor: 'MT0',
lv: '', lv: '',
replay: replayStatus replay: replayStatus
@ -132,13 +143,24 @@ const MainScene = defineComponent(() => {
const hero = core.status.hero; const hero = core.status.hero;
leftStatus.atk = getHeroStatusOn('atk'); leftStatus.atk = getHeroStatusOn('atk');
leftStatus.hp = getHeroStatusOn('hp'); leftStatus.hp = getHeroStatusOn('hp');
leftStatus.hpmax = getHeroStatusOn('hpmax');
leftStatus.mana = getHeroStatusOn('mana');
leftStatus.manamax = getHeroStatusOn('manamax');
leftStatus.def = getHeroStatusOn('def'); leftStatus.def = getHeroStatusOn('def');
leftStatus.mdef = getHeroStatusOn('mdef'); leftStatus.mdef = getHeroStatusOn('mdef');
leftStatus.money = getHeroStatusOn('money'); leftStatus.money = getHeroStatusOn('money');
leftStatus.exp = core.getNextLvUpNeed() ?? 0; leftStatus.exp = getHeroStatusOn('exp');
leftStatus.up = core.getNextLvUpNeed() ?? 0;
leftStatus.yellowKey = core.itemCount('yellowKey'); leftStatus.yellowKey = core.itemCount('yellowKey');
leftStatus.blueKey = core.itemCount('blueKey'); leftStatus.blueKey = core.itemCount('blueKey');
leftStatus.redKey = core.itemCount('redKey'); leftStatus.redKey = core.itemCount('redKey');
leftStatus.greenKey = core.itemCount('greenKey');
leftStatus.pickaxe = core.itemCount('pickaxe');
leftStatus.bomb = core.itemCount('bomb');
leftStatus.centerFly = core.itemCount('centerFly');
leftStatus.poison = core.getFlag('poison', true);
leftStatus.weak = core.getFlag('weak', true);
leftStatus.curse = core.getFlag('curse', true);
leftStatus.floor = core.status.floorId; leftStatus.floor = core.status.floorId;
leftStatus.lv = core.getLvName(hero.lv); leftStatus.lv = core.getLvName(hero.lv);

View File

@ -1,29 +1,68 @@
import { GameUI, SetupComponentOptions } from '@motajs/system-ui'; import { GameUI, SetupComponentOptions } from '@motajs/system-ui';
import { computed, defineComponent, ref } from 'vue'; import { computed, ComputedRef, defineComponent, shallowReactive } from 'vue';
import { TextContent } from '../components'; import { TextContent } from '../components';
import { DefaultProps, ElementLocator, Font } from '@motajs/render';
import { import {
NumpadToolbar, DefaultProps,
PlayingToolbar, ElementLocator,
ReplayingStatus, Font,
ReplayingToolbar SizedCanvasImageSource
} from './toolbar'; } from '@motajs/render';
import { MixedToolbar, ReplayingStatus } from './toolbar';
import { openViewMap } from './viewmap'; import { openViewMap } from './viewmap';
import { mainUIController } from './controller'; import { mainUIController } from './controller';
import { MAIN_HEIGHT, STATUS_BAR_WIDTH } from '../shared'; import {
MAIN_HEIGHT,
MAIN_WIDTH,
STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH
} from '../shared';
export interface ILeftHeroStatus { export interface ILeftHeroStatus {
hp: number; /** 楼层 id */
atk: number;
def: number;
mdef: number;
money: number;
exp: number;
yellowKey: number;
blueKey: number;
redKey: number;
floor: FloorIds; floor: FloorIds;
/** 等级名称 */
lv: string; lv: string;
/** 生命值 */
hp: number;
/** 生命上限 */
hpmax: number;
/** 魔力值 */
mana: number;
/** 魔力上限 */
manamax: number;
/** 攻击力 */
atk: number;
/** 防御力 */
def: number;
/** 魔防(护盾) */
mdef: number;
/** 金币 */
money: number;
/** 经验值 */
exp: number;
/** 距离升级剩余经验 */
up: number;
/** 黄钥匙数量 */
yellowKey: number;
/** 蓝钥匙数量 */
blueKey: number;
/** 红钥匙数量 */
redKey: number;
/** 绿钥匙数量 */
greenKey: number;
/** 破数量 */
pickaxe: number;
/** 炸数量 */
bomb: number;
/** 飞数量 */
centerFly: number;
/** 是否中毒 */
poison: boolean;
/** 是否中衰 */
weak: boolean;
/** 是否中咒 */
curse: boolean;
/** 录像状态 */
replay: ReplayingStatus; replay: ReplayingStatus;
} }
@ -32,6 +71,31 @@ export interface IRightHeroStatus {
exampleHard: number; exampleHard: number;
} }
interface StatusInfo {
/** 图标 */
icon: SizedCanvasImageSource;
/** 属性值,经过格式化 */
value: ComputedRef<string>;
/** 字体 */
font: Font;
/** 文字颜色 */
color: CanvasStyle;
}
interface KeyLikeItem {
/** 属性值,经过格式化 */
value: ComputedRef<string>;
/** 字体 */
font: Font;
/** 文字颜色 */
color: CanvasStyle;
}
interface KeyLikeInfo {
/** 这一行包含的内容 */
items: KeyLikeItem[];
}
interface StatusBarProps<T> extends DefaultProps { interface StatusBarProps<T> extends DefaultProps {
loc: ElementLocator; loc: ElementLocator;
status: T; status: T;
@ -44,96 +108,336 @@ const statusBarProps = {
export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>( export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>(
p => { p => {
const hpIcon = core.material.images.images['hp.png']; //#region 参数定义
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 TEXT_X = 54;
const moneyIcon = core.material.images.images['money.png']; /** 图标的横坐标 */
const expIcon = core.material.images.images['exp.png']; const STATUS_PAD = 8;
/** 楼层名称的高度 */
const TITLE_HEIGHT = 36;
/** 状态属性的开始纵坐标 */
const STATUS_Y = TITLE_HEIGHT + STATUS_PAD;
// 可以换成 core.material.images.images['xxx.png'] 来使用全塔属性注册的图片
const hpIcon = core.statusBar.icons.hp;
const atkIcon = core.statusBar.icons.atk;
const defIcon = core.statusBar.icons.def;
const mdefIcon = core.statusBar.icons.mdef;
const moneyIcon = core.statusBar.icons.money;
const expIcon = core.statusBar.icons.exp;
const manaIcon = core.statusBar.icons.mana;
const lvIcon = core.statusBar.icons.lv;
const s = p.status; const s = p.status;
const f = core.formatBigNumber;
const inNumpad = ref(false); /** 常规字体 */
const font1 = Font.defaults({ size: 18 });
/** 加粗字体 */
const font2 = Font.defaults({ size: 18, weight: 700 });
/** 楼层名 */
const floorName = computed(() => core.floors[s.floor]?.title ?? ''); const floorName = computed(() => core.floors[s.floor]?.title ?? '');
/** 钥匙显示文字 */
const key = (num: number) => { const key = (num: number) => {
return num.toString().padStart(2, '0'); return num.toString().padStart(2, '0');
}; };
const onNumpad = () => { //#region 属性显示
inNumpad.value = !inNumpad.value;
};
const font1 = Font.defaults({ size: 18 }); /** 一般属性 */
const font2 = Font.defaults({ size: 18, weight: 700 }); const statusInfo: StatusInfo[] = shallowReactive([]);
/** 钥匙属性 */
const keyLike: KeyLikeInfo[] = shallowReactive([]);
const iconLoc = (n: number): ElementLocator => { // 根据全塔属性配置显示属性
return [16, 76 + 44 * n, 32, 32]; // 如果你想修改状态栏显示,不建议修改这里的内容,而建议直接新增标签
}; // 这里的内容是为使用样板默认状态栏的人准备的,对于新增属性来说过于复杂,而且功能有限,对于新手来说也难以理解
// 可以参考说明文档中的常见需求指南中的新增状态教程
const textLoc = (n: number): ElementLocator => { const list = core.flags.statusBarItems;
return [60, 92 + 44 * n, void 0, void 0, 0, 0.5];
};
// 等级
if (list.includes('enableLv')) {
statusInfo.push({
icon: lvIcon,
value: computed(() => s.lv),
font: font1,
color: '#fff'
});
}
// 生命值
if (list.includes('enableHP')) {
if (list.includes('enableHPMax')) {
// 如果启用血限
statusInfo.push({
icon: hpIcon,
value: computed(() => {
const hp = core.formatBigNumber(s.hp);
const hpmax = core.formatBigNumber(s.hpmax);
return `${hp} / ${hpmax}`;
}),
font: font1,
color: '#fff'
});
} else {
// 如果禁用血限
statusInfo.push({
icon: hpIcon,
value: computed(() => core.formatBigNumber(s.hp)),
font: font1,
color: '#fff'
});
}
}
// 魔力
if (list.includes('enableMana')) {
statusInfo.push({
icon: manaIcon,
value: computed(() => {
const mana = core.formatBigNumber(s.mana);
const manamax = core.formatBigNumber(s.manamax);
if (s.manamax > 0) {
// 如果启用魔力上限
return `${mana} / ${manamax}`;
} else {
// 如果禁用魔力上限
return mana;
}
}),
font: font1,
color: '#fff'
});
}
// 攻击力
if (list.includes('enableAtk')) {
statusInfo.push({
icon: atkIcon,
value: computed(() => core.formatBigNumber(s.atk)),
font: font1,
color: '#fff'
});
}
// 防御力
if (list.includes('enableDef')) {
statusInfo.push({
icon: defIcon,
value: computed(() => core.formatBigNumber(s.def)),
font: font1,
color: '#fff'
});
}
// 魔防(护盾)
if (list.includes('enableMdef')) {
statusInfo.push({
icon: mdefIcon,
value: computed(() => core.formatBigNumber(s.mdef)),
font: font1,
color: '#fff'
});
}
// 金币
if (list.includes('enableMoney')) {
statusInfo.push({
icon: moneyIcon,
value: computed(() => core.formatBigNumber(s.money)),
font: font1,
color: '#fff'
});
}
// 经验值
if (list.includes('enableExp')) {
if (list.includes('enableLevelUp')) {
// 升级模式
statusInfo.push({
icon: expIcon,
value: computed(() => core.formatBigNumber(s.up)),
font: font1,
color: '#fff'
});
} else {
// 非升级模式
statusInfo.push({
icon: expIcon,
value: computed(() => core.formatBigNumber(s.exp)),
font: font1,
color: '#fff'
});
}
}
// 钥匙
if (list.includes('enableKeys')) {
const keys: KeyLikeItem[] = [];
keyLike.push({ items: keys });
// 黄钥匙
keys.push({
value: computed(() => key(s.yellowKey)),
font: font2,
color: '#fca'
});
// 蓝钥匙
keys.push({
value: computed(() => key(s.blueKey)),
font: font2,
color: '#aad'
});
// 红钥匙
keys.push({
value: computed(() => key(s.redKey)),
font: font2,
color: '#f88'
});
// 绿钥匙
if (list.includes('enableGreenKey')) {
keys.push({
value: computed(() => key(s.greenKey)),
font: font2,
color: '#8f8'
});
}
}
// 破炸飞
if (list.includes('enablePZF')) {
const items: KeyLikeItem[] = [];
keyLike.push({ items });
items.push({
value: computed(() => `${s.pickaxe}`),
font: font1,
color: '#bc6e27'
});
items.push({
value: computed(() => `${s.bomb}`),
font: font1,
color: '#fa14b9'
});
items.push({
value: computed(() => `${s.centerFly}`),
font: font1,
color: '#8db600'
});
}
// 毒衰咒
if (list.includes('enableDebuff')) {
const debuffs: KeyLikeItem[] = [];
keyLike.push({ items: debuffs });
debuffs.push({
value: computed(() => (s.poison ? '毒' : '')),
font: font1,
color: '#affca8'
});
debuffs.push({
value: computed(() => (s.weak ? '衰' : '')),
font: font1,
color: '#feccd0'
});
debuffs.push({
value: computed(() => (s.curse ? '咒' : '')),
font: font1,
color: '#c2f4e7'
});
}
//#region 布局控制
/** 用于显示状态的高度,高度=状态栏高度-工具栏高度-楼层名高度-填充高度 */
const statusHeight =
STATUS_BAR_HEIGHT - 113 - TITLE_HEIGHT - STATUS_PAD * 2;
/** 每一行的高度 */
const rowHeight = computed(() => {
const length = statusInfo.length + keyLike.length;
return statusHeight / length;
});
/** 钥匙、破炸飞、毒衰咒开始显示的纵坐标 */
const keyStart = computed(() => {
const statusHeight = statusInfo.length * rowHeight.value;
return STATUS_Y + statusHeight;
});
/**
*
* @param y
*/
const central = (y: number): ElementLocator => { const central = (y: number): ElementLocator => {
const width = p.loc[2] ?? 200; const width = p.loc[2] ?? 200;
return [width / 2, y, void 0, void 0, 0.5, 0.5]; return [width / 2, y, void 0, void 0, 0.5, 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];
};
const viewMap = () => { const viewMap = () => {
openViewMap(mainUIController, [0, 0, 840, 480]); openViewMap(mainUIController, [0, 0, MAIN_WIDTH, MAIN_HEIGHT]);
}; };
return () => ( return () => (
<container loc={p.loc} hidden={p.hidden}> <container loc={p.loc} hidden={p.hidden}>
<text <text
text={floorName.value} text={floorName.value}
loc={central(24)} loc={central(18)}
font={font1} font={font1}
cursor="pointer" cursor="pointer"
onClick={viewMap} onClick={viewMap}
></text> ></text>
<text text={s.lv} loc={central(54)} font={font1}></text> <g-line
<image image={hpIcon} loc={iconLoc(0)}></image> lineWidth={1}
<text text={f(s.hp)} loc={textLoc(0)} font={font1}></text> strokeStyle="#888"
<image image={atkIcon} loc={iconLoc(1)}></image> line={[0, TITLE_HEIGHT, STATUS_BAR_WIDTH, TITLE_HEIGHT]}
<text text={f(s.atk)} loc={textLoc(1)} font={font1}></text> />
<image image={defIcon} loc={iconLoc(2)}></image> {statusInfo
<text text={f(s.def)} loc={textLoc(2)} font={font1}></text> .map((v, i) => {
<image image={mdefIcon} loc={iconLoc(3)}></image> const h = rowHeight.value;
<text text={f(s.mdef)} loc={textLoc(3)} font={font1}></text> const y = STATUS_Y + i * h;
<image image={moneyIcon} loc={iconLoc(4)}></image> const cy = y + h / 2;
<text text={f(s.money)} loc={textLoc(4)} font={font1} /> const iconSize = Math.min(32, h * 0.8);
<image image={expIcon} loc={iconLoc(5)}></image> const pad = (h - iconSize) / 2;
<text text={f(s.exp)} loc={textLoc(5)} font={font1}></text> return [
<text <image
text={key(s.yellowKey)} loc={[STATUS_PAD, y + pad, iconSize, iconSize]}
loc={keyLoc(0)} image={v.icon}
font={font2} noanti // 取消抗锯齿
fillStyle="#fca" />,
></text> <text
<text loc={[TEXT_X, cy]}
text={key(s.blueKey)} anc={[0, 0.5]}
loc={keyLoc(1)} text={v.value.value}
font={font2} fillStyle={v.color}
fillStyle="#aad" font={v.font}
></text> />
<text ];
text={key(s.redKey)} })
loc={keyLoc(2)} .flat()}
font={font2} {keyLike
fillStyle="#f88" .map(({ items }, i) => {
></text> const h = rowHeight.value;
const y = keyStart.value + i * h;
const cy = y + h / 2;
const rw = STATUS_BAR_WIDTH / (items.length + 1);
return items.map((v, i) => {
const x = rw * (i + 1);
return (
<text
loc={[x, cy]}
anc={[0.5, 0.5]}
text={v.value.value}
font={v.font}
fillStyle={v.color}
/>
);
});
})
.flat()}
<g-line <g-line
lineWidth={1} lineWidth={1}
strokeStyle="#888" strokeStyle="#888"
@ -144,22 +448,10 @@ export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>(
MAIN_HEIGHT - 113 MAIN_HEIGHT - 113
]} ]}
/> />
{inNumpad.value ? ( <MixedToolbar
<NumpadToolbar loc={[0, MAIN_HEIGHT - 113, STATUS_BAR_WIDTH, 113]}
loc={[0, MAIN_HEIGHT - 113, STATUS_BAR_WIDTH, 113]} status={s.replay}
onNumpad={onNumpad} />
/>
) : s.replay.replaying ? (
<ReplayingToolbar
loc={[0, MAIN_HEIGHT - 113, STATUS_BAR_WIDTH, 113]}
status={s.replay}
/>
) : (
<PlayingToolbar
loc={[0, MAIN_HEIGHT - 113, STATUS_BAR_WIDTH, 113]}
onNumpad={onNumpad}
/>
)}
</container> </container>
); );
}, },

View File

@ -1,7 +1,6 @@
import { DefaultProps, ElementLocator, Font } from '@motajs/render'; import { DefaultProps, ElementLocator, Font } from '@motajs/render';
import { computed, defineComponent, ref } from 'vue'; import { computed, defineComponent, ref } from 'vue';
import { import {
DanmakuIcon,
DoubleArrow, DoubleArrow,
NumpadIcon, NumpadIcon,
PauseIcon, PauseIcon,
@ -12,7 +11,7 @@ import {
StepForward, StepForward,
ViewMapIcon ViewMapIcon
} from '../components/icons'; } from '../components/icons';
import { getVitualKeyOnce, openDanmakuPoster } from '@motajs/legacy-ui'; import { getVitualKeyOnce } from '@motajs/legacy-ui';
import { gameKey } from '@motajs/system-action'; import { gameKey } from '@motajs/system-action';
import { generateKeyboardEvent } from '@motajs/system-action'; import { generateKeyboardEvent } from '@motajs/system-action';
import { transitioned } from '../use'; import { transitioned } from '../use';
@ -113,7 +112,6 @@ export const PlayingToolbar = defineComponent<
const view = () => { const view = () => {
openViewMap(mainUIController, FULL_LOC); openViewMap(mainUIController, FULL_LOC);
}; };
const danmaku = () => requestAnimationFrame(openDanmakuPoster);
const replay = () => core.ui._drawReplay(); const replay = () => core.ui._drawReplay();
const settings = () => { const settings = () => {
const loc = CENTER_LOC.slice() as ElementLocator; const loc = CENTER_LOC.slice() as ElementLocator;
@ -136,7 +134,6 @@ export const PlayingToolbar = defineComponent<
<RetweetIcon loc={ic(4, 1)} strokeStyle="#eee" onClick={redo} /> <RetweetIcon loc={ic(4, 1)} strokeStyle="#eee" onClick={redo} />
<NumpadIcon loc={ic(0, 2)} strokeStyle="#eee" onClick={numpad} /> <NumpadIcon loc={ic(0, 2)} strokeStyle="#eee" onClick={numpad} />
<ViewMapIcon loc={ic(1, 2)} strokeStyle="#eee" onClick={view} /> <ViewMapIcon loc={ic(1, 2)} strokeStyle="#eee" onClick={view} />
<DanmakuIcon loc={ic(2, 2)} strokeStyle="#eee" onClick={danmaku} />
<ReplayIcon loc={ic(3, 2)} strokeStyle="#eee" onClick={replay} /> <ReplayIcon loc={ic(3, 2)} strokeStyle="#eee" onClick={replay} />
<text text="R" loc={middle(3, 2)} font={iconFont} noevent /> <text text="R" loc={middle(3, 2)} font={iconFont} noevent />
<image image={setIcon} loc={im(4, 2)} noanti onClick={settings} /> <image image={setIcon} loc={im(4, 2)} noanti onClick={settings} />
@ -155,8 +152,6 @@ export interface ReplayingStatus {
played: number; played: number;
/** 总长度 */ /** 总长度 */
total: number; total: number;
/** 是否是录像模式 */
replaying: boolean;
} }
export interface ReplayingProps extends ToolbarProps { export interface ReplayingProps extends ToolbarProps {

View File

@ -528,9 +528,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_type": "checkboxSet", "_type": "checkboxSet",
"_checkboxSet": { "_checkboxSet": {
"prefix": [ "prefix": [
"楼层", "等级",
"名字",
"<br>等级",
"血限", "血限",
"<br>生命", "<br>生命",
"魔力", "魔力",
@ -540,16 +538,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"金币", "金币",
"<br>经验", "<br>经验",
"升级", "升级",
"<br>升级扣除模式",
"<br>钥匙", "<br>钥匙",
"绿钥", "绿钥",
"<br>破炸", "<br>破炸",
"负面", "负面"
"<br>技能"
], ],
"key": [ "key": [
"enableFloor",
"enableName",
"enableLv", "enableLv",
"enableHPMax", "enableHPMax",
"enableHP", "enableHP",
@ -560,12 +554,10 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"enableMoney", "enableMoney",
"enableExp", "enableExp",
"enableLevelUp", "enableLevelUp",
"levelUpLeftMode",
"enableKeys", "enableKeys",
"enableGreenKey", "enableGreenKey",
"enablePZF", "enablePZF",
"enableDebuff", "enableDebuff"
"enableSkill"
] ]
}, },
"_data": "状态栏显示项" "_data": "状态栏显示项"

View File

@ -803,16 +803,12 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
}, },
"flags": { "flags": {
"statusBarItems": [ "statusBarItems": [
"enableFloor",
"enableLv",
"enableHP", "enableHP",
"enableAtk", "enableAtk",
"enableDef", "enableDef",
"enableMDef", "enableMDef",
"enableMoney", "enableMoney",
"enableExp", "enableExp",
"enableLevelUp",
"levelUpLeftMode",
"enableKeys" "enableKeys"
], ],
"flyNearStair": false, "flyNearStair": false,
@ -836,7 +832,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"enableRouteFolding": true, "enableRouteFolding": true,
"disableShopOnDamage": false, "disableShopOnDamage": false,
"blurFg": true, "blurFg": true,
"extendToolbar": true, "extendToolbar": false,
"enableEnemyPoint": null, "enableEnemyPoint": null,
"autoScale": true "autoScale": true
} }