fix: icon

This commit is contained in:
unanmed 2025-01-12 13:09:10 +08:00
parent ba1e7ea228
commit b2a391a212
6 changed files with 48 additions and 12 deletions

View File

@ -211,6 +211,7 @@ class TextureCache extends EventEmitter<TextureCacheEvent> {
// enemy48和npc48都应该视为大怪物 // enemy48和npc48都应该视为大怪物
if (cls === 'enemy48' || cls === 'npc48') { if (cls === 'enemy48' || cls === 'npc48') {
const img = core.material.images[cls]; const img = core.material.images[cls];
if (!img) return null;
// @ts-ignore // @ts-ignore
const line = icons[cls][id]; const line = icons[cls][id];
const w = 32; const w = 32;
@ -234,6 +235,7 @@ class TextureCache extends EventEmitter<TextureCacheEvent> {
} }
// 自动元件 // 自动元件
if (cls === 'autotile') { if (cls === 'autotile') {
if (!this.autotile) return null;
const auto = this.autotile[num as AllNumbersOf<'autotile'>]; const auto = this.autotile[num as AllNumbersOf<'autotile'>];
const cell = 32; const cell = 32;
const render: [number, number, number, number][] = []; const render: [number, number, number, number][] = [];
@ -264,6 +266,7 @@ class TextureCache extends EventEmitter<TextureCacheEvent> {
core.material.images[ core.material.images[
cls as Exclude<Cls, 'tileset' | 'autotile'> cls as Exclude<Cls, 'tileset' | 'autotile'>
]; ];
if (!image) return null;
const frame = core.getAnimateFrames(cls); const frame = core.getAnimateFrames(cls);
const cell = 32; const cell = 32;
// @ts-ignore // @ts-ignore

View File

@ -69,6 +69,7 @@ Mota.require('var', 'loading').once('coreInit', () => {
</layer-group> </layer-group>
<Textbox id="main-textbox" {...mainTextboxProps}></Textbox> <Textbox id="main-textbox" {...mainTextboxProps}></Textbox>
<FloorChange id="floor-change" zIndex={50}></FloorChange> <FloorChange id="floor-change" zIndex={50}></FloorChange>
<icon icon={13} animate></icon>
</container> </container>
); );
}); });

View File

@ -10,6 +10,8 @@ import { Transform } from '../transform';
import { ElementNamespace, ComponentInternalInstance } from 'vue'; import { ElementNamespace, ComponentInternalInstance } from 'vue';
import { AutotileRenderable, RenderableData } from '../cache'; import { AutotileRenderable, RenderableData } from '../cache';
import { texture } from '../cache'; import { texture } from '../cache';
import { isNil } from 'lodash-es';
import { logger } from '@/core/common/logger';
type CanvasStyle = string | CanvasGradient | CanvasPattern; type CanvasStyle = string | CanvasGradient | CanvasPattern;
@ -223,6 +225,14 @@ export class Icon extends RenderItem<EIconEvent> implements IAnimateFrame {
/** 图标的渲染信息 */ /** 图标的渲染信息 */
private renderable?: RenderableData | AutotileRenderable; private renderable?: RenderableData | AutotileRenderable;
private pendingIcon?: AllNumbers;
constructor(type: RenderItemPosition, cache?: boolean, fall?: boolean) {
super(type, cache, fall);
this.setAntiAliasing(false);
this.setHD(false);
}
protected render( protected render(
canvas: MotaOffscreenCanvas2D, canvas: MotaOffscreenCanvas2D,
_transform: Transform _transform: Transform
@ -236,6 +246,7 @@ export class Icon extends RenderItem<EIconEvent> implements IAnimateFrame {
const frame = this.animate const frame = this.animate
? RenderItem.animatedFrame % renderable.frame ? RenderItem.animatedFrame % renderable.frame
: 0; : 0;
if (!this.animate) { if (!this.animate) {
if (renderable.autotile) { if (renderable.autotile) {
ctx.drawImage(renderable.image[0], x, y, w, h, 0, 0, cw, ch); ctx.drawImage(renderable.image[0], x, y, w, h, 0, 0, cw, ch);
@ -250,8 +261,6 @@ export class Icon extends RenderItem<EIconEvent> implements IAnimateFrame {
} else { } else {
ctx.drawImage(renderable.image, x1, y1, w1, h1, 0, 0, cw, ch); ctx.drawImage(renderable.image, x1, y1, w1, h1, 0, 0, cw, ch);
} }
this.update(this);
renderEmits.addFramer(this);
} }
} }
@ -261,24 +270,35 @@ export class Icon extends RenderItem<EIconEvent> implements IAnimateFrame {
*/ */
setIcon(id: AllIds | AllNumbers) { setIcon(id: AllIds | AllNumbers) {
const num = typeof id === 'number' ? id : texture.idNumberMap[id]; const num = typeof id === 'number' ? id : texture.idNumberMap[id];
const loading = Mota.require('var', 'loading');
if (loading.loaded) {
this.setIconRenderable(num);
} else {
if (isNil(this.pendingIcon)) {
loading.once('loaded', () => {
this.setIconRenderable(this.pendingIcon ?? 0);
this.pendingIcon = void 0;
});
}
this.pendingIcon = num;
}
}
private setIconRenderable(num: AllNumbers) {
const renderable = texture.getRenderable(num); const renderable = texture.getRenderable(num);
if (!renderable) { if (!renderable) {
//todo: logger.warn() logger.warn(42, num.toString());
return; return;
} else { } else {
this.icon = num; this.icon = num;
this.renderable = renderable;
this.frame = renderable.frame; this.frame = renderable.frame;
} }
this.update(); this.update();
} }
destroy(): void {
renderEmits.removeFramer(this);
super.destroy();
}
/** /**
* *
*/ */
@ -286,6 +306,11 @@ export class Icon extends RenderItem<EIconEvent> implements IAnimateFrame {
this.update(this); this.update(this);
} }
destroy(): void {
renderEmits.removeFramer(this);
super.destroy();
}
patchProp( patchProp(
key: string, key: string,
prevValue: any, prevValue: any,
@ -300,6 +325,8 @@ export class Icon extends RenderItem<EIconEvent> implements IAnimateFrame {
case 'animate': case 'animate':
if (!this.assertType(nextValue, 'boolean', key)) return; if (!this.assertType(nextValue, 'boolean', key)) return;
this.animate = nextValue; this.animate = nextValue;
if (nextValue) renderEmits.addFramer(this);
else renderEmits.removeFramer(this);
this.update(); this.update();
return; return;
case 'frame': case 'frame':

View File

@ -178,8 +178,8 @@ export interface RectRProps extends GraphicPropsBase {
export interface IconProps extends BaseProps { export interface IconProps extends BaseProps {
icon: AllNumbers; icon: AllNumbers;
frame: number; frame?: number;
animate: boolean; animate?: boolean;
} }
export interface WinskinProps extends BaseProps { export interface WinskinProps extends BaseProps {

View File

@ -70,6 +70,7 @@
"40": "Cannot return canvas that is not provided by this pool.", "40": "Cannot return canvas that is not provided by this pool.",
"41": "Width of text content components must be positive. receive: $1", "41": "Width of text content components must be positive. receive: $1",
"42": "Repeated Textbox id: '$1'.", "42": "Repeated Textbox id: '$1'.",
"43": "Cannot set icon of '$1', since it does not exists. Please ensure you have delivered correct icon id or number.",
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.", "1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.",
"1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance." "1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance."
} }

View File

@ -13,12 +13,16 @@ class GameLoading extends EventEmitter<GameLoadEvent> {
private autotileLoaded: number = 0; private autotileLoaded: number = 0;
private autotileNum?: number; private autotileNum?: number;
private autotileListened: boolean = false; private autotileListened: boolean = false;
loaded: boolean = false;
constructor() { constructor() {
super(); super();
this.on('coreInit', () => { this.once('coreInit', () => {
this.autotileNum = Object.keys(core.material.icons.autotile).length; this.autotileNum = Object.keys(core.material.icons.autotile).length;
}); });
this.once('loaded', () => {
this.loaded = true;
});
} }
addAutotileLoaded() { addAutotileLoaded() {