mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-10-29 10:22:59 +08:00
feat: scan animater & refactor: 动画输出类型
This commit is contained in:
parent
fc1c0b14d6
commit
77246b571a
@ -105,6 +105,7 @@
|
|||||||
"71": "Cannot start animate when animater not created on texture.",
|
"71": "Cannot start animate when animater not created on texture.",
|
||||||
"72": "Frame count delivered to frame-based animater need to exactly divide texture's height.",
|
"72": "Frame count delivered to frame-based animater need to exactly divide texture's height.",
|
||||||
"73": "Consistent size is needed when using WebGL2 composer.",
|
"73": "Consistent size is needed when using WebGL2 composer.",
|
||||||
|
"74": "Frame size not match texture's size, incomplete data will be skipped.",
|
||||||
"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."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
import { logger } from '@motajs/common';
|
import { logger } from '@motajs/common';
|
||||||
import {
|
import { IRect, ITexture, ITextureAnimater, ITextureRenderable } from './types';
|
||||||
IRect,
|
|
||||||
ITexture,
|
|
||||||
ITextureAnimater,
|
|
||||||
ITextureListedRenderable
|
|
||||||
} from './types';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于帧的动画控制器,创建时传入的参数代表帧数,生成动画时传入的参数自定义
|
* 基于帧的动画控制器,创建时传入的参数代表帧数,生成动画时传入的参数自定义
|
||||||
@ -41,31 +36,31 @@ export abstract class FrameBasedAnimater<T>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract open(init: T): Generator<ITextureListedRenderable> | null;
|
abstract open(init: T): Generator<ITextureRenderable> | null;
|
||||||
|
|
||||||
abstract cycled(init: T): Generator<ITextureListedRenderable> | null;
|
abstract cycled(init: T): Generator<ITextureRenderable> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 行动画控制器,将贴图按照从上到下的顺序依次组成帧动画,创建时传入的参数代表帧数
|
* 行动画控制器,将贴图按照从上到下的顺序依次组成帧动画,创建时传入的参数代表帧数
|
||||||
*/
|
*/
|
||||||
export class TextureRowAnimater extends FrameBasedAnimater<void> {
|
export class TextureRowAnimater extends FrameBasedAnimater<void> {
|
||||||
*open(): Generator<ITextureListedRenderable> | null {
|
*open(): Generator<ITextureRenderable> | null {
|
||||||
if (!this.check()) return null;
|
if (!this.check()) return null;
|
||||||
const renderable = this.texture!.static();
|
const renderable = this.texture!.static();
|
||||||
const { x: ox, y: oy } = renderable.rect;
|
const { x: ox, y: oy } = renderable.rect;
|
||||||
const { width: w, height } = this.texture!;
|
const { width: w, height } = this.texture!;
|
||||||
const h = height / this.frames;
|
const h = height / this.frames;
|
||||||
for (let i = 0; i < this.frames; i++) {
|
for (let i = 0; i < this.frames; i++) {
|
||||||
const renderable: ITextureListedRenderable = {
|
const renderable: ITextureRenderable = {
|
||||||
source: this.texture!.source,
|
source: this.texture!.source,
|
||||||
rect: [{ x: ox, y: i * h + oy, w, h }]
|
rect: { x: ox, y: i * h + oy, w, h }
|
||||||
};
|
};
|
||||||
yield renderable;
|
yield renderable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*cycled(): Generator<ITextureListedRenderable> | null {
|
*cycled(): Generator<ITextureRenderable> | null {
|
||||||
if (!this.check()) return null;
|
if (!this.check()) return null;
|
||||||
const renderable = this.texture!.static();
|
const renderable = this.texture!.static();
|
||||||
const { x: ox, y: oy } = renderable.rect;
|
const { x: ox, y: oy } = renderable.rect;
|
||||||
@ -74,9 +69,9 @@ export class TextureRowAnimater extends FrameBasedAnimater<void> {
|
|||||||
let i = 0;
|
let i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (i === this.frames) i = 0;
|
if (i === this.frames) i = 0;
|
||||||
const renderable: ITextureListedRenderable = {
|
const renderable: ITextureRenderable = {
|
||||||
source: this.texture!.source,
|
source: this.texture!.source,
|
||||||
rect: [{ x: ox, y: i * h + oy, w, h }]
|
rect: { x: ox, y: i * h + oy, w, h }
|
||||||
};
|
};
|
||||||
yield renderable;
|
yield renderable;
|
||||||
}
|
}
|
||||||
@ -87,22 +82,22 @@ export class TextureRowAnimater extends FrameBasedAnimater<void> {
|
|||||||
* 列动画控制器,将贴图按照从左到右的顺序依次组成帧动画,创建时传入的参数代表帧数
|
* 列动画控制器,将贴图按照从左到右的顺序依次组成帧动画,创建时传入的参数代表帧数
|
||||||
*/
|
*/
|
||||||
export class TextureColumnAnimater extends FrameBasedAnimater<void> {
|
export class TextureColumnAnimater extends FrameBasedAnimater<void> {
|
||||||
*open(): Generator<ITextureListedRenderable> | null {
|
*open(): Generator<ITextureRenderable> | null {
|
||||||
if (!this.check()) return null;
|
if (!this.check()) return null;
|
||||||
const renderable = this.texture!.static();
|
const renderable = this.texture!.static();
|
||||||
const { x: ox, y: oy } = renderable.rect;
|
const { x: ox, y: oy } = renderable.rect;
|
||||||
const { width, height: h } = this.texture!;
|
const { width, height: h } = this.texture!;
|
||||||
const w = width / this.frames;
|
const w = width / this.frames;
|
||||||
for (let i = 0; i < this.frames; i++) {
|
for (let i = 0; i < this.frames; i++) {
|
||||||
const renderable: ITextureListedRenderable = {
|
const renderable: ITextureRenderable = {
|
||||||
source: this.texture!.source,
|
source: this.texture!.source,
|
||||||
rect: [{ x: i * width + ox, y: oy, w, h }]
|
rect: { x: i * width + ox, y: oy, w, h }
|
||||||
};
|
};
|
||||||
yield renderable;
|
yield renderable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*cycled(): Generator<ITextureListedRenderable> | null {
|
*cycled(): Generator<ITextureRenderable> | null {
|
||||||
if (!this.check()) return null;
|
if (!this.check()) return null;
|
||||||
const renderable = this.texture!.static();
|
const renderable = this.texture!.static();
|
||||||
const { x: ox, y: oy } = renderable.rect;
|
const { x: ox, y: oy } = renderable.rect;
|
||||||
@ -111,15 +106,92 @@ export class TextureColumnAnimater extends FrameBasedAnimater<void> {
|
|||||||
let i = 0;
|
let i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (i === this.frames) i = 0;
|
if (i === this.frames) i = 0;
|
||||||
const renderable: ITextureListedRenderable = {
|
const renderable: ITextureRenderable = {
|
||||||
source: this.texture!.source,
|
source: this.texture!.source,
|
||||||
rect: [{ x: i * w + ox, y: oy, w, h }]
|
rect: { x: i * w + ox, y: oy, w, h }
|
||||||
};
|
};
|
||||||
yield renderable;
|
yield renderable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IScanAnimaterCreate {
|
||||||
|
/** 每帧的宽度 */
|
||||||
|
readonly width: number;
|
||||||
|
/** 每帧的高度 */
|
||||||
|
readonly height: number;
|
||||||
|
/** 总帧数 */
|
||||||
|
readonly frames: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扫描动画控制器,会按照先从左到右,再从上到下的顺序依次输出,可以用于动画精灵图等
|
||||||
|
*/
|
||||||
|
export class TextureScanAnimater
|
||||||
|
implements ITextureAnimater<IScanAnimaterCreate, void>
|
||||||
|
{
|
||||||
|
texture: ITexture<IScanAnimaterCreate, void> | null = null;
|
||||||
|
|
||||||
|
private width: number = 0;
|
||||||
|
private height: number = 0;
|
||||||
|
|
||||||
|
private frames: number = 0;
|
||||||
|
private frameX: number = 0;
|
||||||
|
private frameY: number = 0;
|
||||||
|
|
||||||
|
create(texture: ITexture, data: IScanAnimaterCreate): void {
|
||||||
|
if (this.texture) {
|
||||||
|
logger.warn(70);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.texture = texture;
|
||||||
|
|
||||||
|
this.width = data.width;
|
||||||
|
this.height = data.height;
|
||||||
|
this.frames = data.frames;
|
||||||
|
|
||||||
|
// 如果尺寸不匹配
|
||||||
|
if (
|
||||||
|
texture.width % data.width !== 0 ||
|
||||||
|
texture.height % data.height !== 0
|
||||||
|
) {
|
||||||
|
logger.warn(74);
|
||||||
|
}
|
||||||
|
|
||||||
|
const frameX = Math.floor(texture.width / data.width);
|
||||||
|
const frameY = Math.floor(texture.height / data.height);
|
||||||
|
const possibleFrames = frameX * frameY;
|
||||||
|
|
||||||
|
// 如果传入的帧数超出了可能的帧数上限
|
||||||
|
if (this.frames > possibleFrames) {
|
||||||
|
this.frames = possibleFrames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*open(): Generator<ITextureRenderable, void> | null {
|
||||||
|
const texture = this.texture;
|
||||||
|
if (!texture) return null;
|
||||||
|
|
||||||
|
const w = this.width;
|
||||||
|
const h = this.height;
|
||||||
|
|
||||||
|
for (let y = 0; y < this.frameY; y++) {
|
||||||
|
for (let x = 0; x < this.frameX; x++) {
|
||||||
|
const rect: IRect = { x: x * w, y: y * h, w, h };
|
||||||
|
const data: ITextureRenderable = {
|
||||||
|
source: texture.source,
|
||||||
|
rect
|
||||||
|
};
|
||||||
|
yield data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cycled(): Generator<ITextureRenderable, void> | null {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface IAnimaterTranslatedInit<T> {
|
export interface IAnimaterTranslatedInit<T> {
|
||||||
/** 以此矩形作为参考矩形 */
|
/** 以此矩形作为参考矩形 */
|
||||||
readonly rect: Readonly<IRect>;
|
readonly rect: Readonly<IRect>;
|
||||||
@ -141,11 +213,15 @@ export class TextureAnimaterTranslated<T> implements AdderImplements<T> {
|
|||||||
texture: AdderTexture<T> | null = null;
|
texture: AdderTexture<T> | null = null;
|
||||||
|
|
||||||
create(texture: ITexture): void {
|
create(texture: ITexture): void {
|
||||||
|
if (this.texture) {
|
||||||
|
logger.warn(70);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
*output(
|
*output(
|
||||||
ani: Generator<ITextureListedRenderable>,
|
ani: Generator<ITextureRenderable>,
|
||||||
origin: Readonly<IRect>,
|
origin: Readonly<IRect>,
|
||||||
rect: Readonly<IRect>
|
rect: Readonly<IRect>
|
||||||
) {
|
) {
|
||||||
@ -157,13 +233,11 @@ export class TextureAnimaterTranslated<T> implements AdderImplements<T> {
|
|||||||
const next = ani.next();
|
const next = ani.next();
|
||||||
if (next.done) break;
|
if (next.done) break;
|
||||||
const renderable = next.value;
|
const renderable = next.value;
|
||||||
const list: IRect[] = [];
|
const { x, y, w, h } = renderable.rect;
|
||||||
renderable.rect.forEach(({ x, y, w, h }) => {
|
const translated: IRect = { x: x - ox + nx, y: y - oy + ny, w, h };
|
||||||
list.push({ x: x - ox + nx, y: y - oy + ny, w, h });
|
const res: ITextureRenderable = {
|
||||||
});
|
|
||||||
const res: ITextureListedRenderable = {
|
|
||||||
source,
|
source,
|
||||||
rect: list
|
rect: translated
|
||||||
};
|
};
|
||||||
yield res;
|
yield res;
|
||||||
}
|
}
|
||||||
@ -171,7 +245,7 @@ export class TextureAnimaterTranslated<T> implements AdderImplements<T> {
|
|||||||
|
|
||||||
open(
|
open(
|
||||||
init: IAnimaterTranslatedInit<T>
|
init: IAnimaterTranslatedInit<T>
|
||||||
): Generator<ITextureListedRenderable> | null {
|
): Generator<ITextureRenderable> | null {
|
||||||
const ani = init.texture.dynamic(init.data);
|
const ani = init.texture.dynamic(init.data);
|
||||||
const origin = init.texture.static().rect;
|
const origin = init.texture.static().rect;
|
||||||
if (!ani || !origin) return null;
|
if (!ani || !origin) return null;
|
||||||
@ -180,7 +254,7 @@ export class TextureAnimaterTranslated<T> implements AdderImplements<T> {
|
|||||||
|
|
||||||
cycled(
|
cycled(
|
||||||
init: IAnimaterTranslatedInit<T>
|
init: IAnimaterTranslatedInit<T>
|
||||||
): Generator<ITextureListedRenderable> | null {
|
): Generator<ITextureRenderable> | null {
|
||||||
const ani = init.texture.cycled(init.data);
|
const ani = init.texture.cycled(init.data);
|
||||||
const origin = init.texture.static().rect;
|
const origin = init.texture.static().rect;
|
||||||
if (!ani || !origin) return null;
|
if (!ani || !origin) return null;
|
||||||
|
|||||||
@ -55,7 +55,8 @@ interface GridNeededSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网格组合器,将等大小的贴图组合成图集,要求每个贴图的尺寸一致
|
* 网格组合器,将等大小的贴图组合成图集,要求每个贴图的尺寸一致。
|
||||||
|
* 组合时按照先从左到右,再从上到下的顺序组合。
|
||||||
*/
|
*/
|
||||||
export class TextureGridComposer<T>
|
export class TextureGridComposer<T>
|
||||||
implements TranslatedComposer<IGridComposerData, T>
|
implements TranslatedComposer<IGridComposerData, T>
|
||||||
|
|||||||
@ -2,8 +2,7 @@ import { logger } from '@motajs/common';
|
|||||||
import {
|
import {
|
||||||
ITexture,
|
ITexture,
|
||||||
ITextureAnimater,
|
ITextureAnimater,
|
||||||
ITextureListedRenderable,
|
ITextureRenderable,
|
||||||
ITextureSingleRenderable,
|
|
||||||
ITextureSplitter,
|
ITextureSplitter,
|
||||||
SizedCanvasImageSource
|
SizedCanvasImageSource
|
||||||
} from './types';
|
} from './types';
|
||||||
@ -63,20 +62,20 @@ export class Texture<T = unknown, A = unknown> implements ITexture<T, A> {
|
|||||||
animater.create(this, data);
|
animater.create(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static(): ITextureSingleRenderable {
|
static(): ITextureRenderable {
|
||||||
const renderable: ITextureSingleRenderable = {
|
const renderable: ITextureRenderable = {
|
||||||
source: this.source,
|
source: this.source,
|
||||||
rect: { x: this.cx, y: this.cy, w: this.width, h: this.height }
|
rect: { x: this.cx, y: this.cy, w: this.width, h: this.height }
|
||||||
};
|
};
|
||||||
return renderable;
|
return renderable;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic(data: A): Generator<ITextureListedRenderable> | null {
|
dynamic(data: A): Generator<ITextureRenderable> | null {
|
||||||
if (!this.animater) return null;
|
if (!this.animater) return null;
|
||||||
return this.animater.open(data);
|
return this.animater.open(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
cycled(data: A): Generator<ITextureListedRenderable> | null {
|
cycled(data: A): Generator<ITextureRenderable> | null {
|
||||||
if (!this.animater) return null;
|
if (!this.animater) return null;
|
||||||
return this.animater.cycled(data);
|
return this.animater.cycled(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,20 +12,13 @@ export interface IRect {
|
|||||||
h: number;
|
h: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITextureSingleRenderable {
|
export interface ITextureRenderable {
|
||||||
/** 可渲染贴图对象的图像源 */
|
/** 可渲染贴图对象的图像源 */
|
||||||
readonly source: SizedCanvasImageSource;
|
readonly source: SizedCanvasImageSource;
|
||||||
/** 贴图裁剪区域 */
|
/** 贴图裁剪区域 */
|
||||||
readonly rect: Readonly<IRect>;
|
readonly rect: Readonly<IRect>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITextureListedRenderable {
|
|
||||||
/** 可渲染贴图对象的图像源 */
|
|
||||||
readonly source: SizedCanvasImageSource;
|
|
||||||
/** 贴图裁剪区域 */
|
|
||||||
readonly rect: Readonly<IRect>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ITextureComposedData<T = unknown, A = unknown> {
|
export interface ITextureComposedData<T = unknown, A = unknown> {
|
||||||
/** 这个纹理图集的贴图对象 */
|
/** 这个纹理图集的贴图对象 */
|
||||||
readonly texture: ITexture<T, A>;
|
readonly texture: ITexture<T, A>;
|
||||||
@ -69,13 +62,13 @@ export interface ITextureAnimater<T, I> {
|
|||||||
* 开始动画序列
|
* 开始动画序列
|
||||||
* @param init 动画初始化参数
|
* @param init 动画初始化参数
|
||||||
*/
|
*/
|
||||||
open(init: I): Generator<ITextureListedRenderable, void> | null;
|
open(init: I): Generator<ITextureRenderable, void> | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始循环动画序列
|
* 开始循环动画序列
|
||||||
* @param init 动画初始化参数
|
* @param init 动画初始化参数
|
||||||
*/
|
*/
|
||||||
cycled(init: I): Generator<ITextureListedRenderable, void> | null;
|
cycled(init: I): Generator<ITextureRenderable, void> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITexture<T = unknown, A = unknown> {
|
export interface ITexture<T = unknown, A = unknown> {
|
||||||
@ -111,19 +104,19 @@ export interface ITexture<T = unknown, A = unknown> {
|
|||||||
/**
|
/**
|
||||||
* 获取整张图的可渲染对象
|
* 获取整张图的可渲染对象
|
||||||
*/
|
*/
|
||||||
static(): ITextureSingleRenderable;
|
static(): ITextureRenderable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取一系列动画可渲染对象,不循环,按帧数依次排列
|
* 获取一系列动画可渲染对象,不循环,按帧数依次排列
|
||||||
* @param data 传递给动画控制器的初始化参数
|
* @param data 传递给动画控制器的初始化参数
|
||||||
*/
|
*/
|
||||||
dynamic(data: A): Generator<ITextureListedRenderable, void> | null;
|
dynamic(data: A): Generator<ITextureRenderable, void> | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取无限循环的动画可渲染对象
|
* 获取无限循环的动画可渲染对象
|
||||||
* @param data 传递给动画控制器的初始化参数
|
* @param data 传递给动画控制器的初始化参数
|
||||||
*/
|
*/
|
||||||
cycled(data: A): Generator<ITextureListedRenderable, void> | null;
|
cycled(data: A): Generator<ITextureRenderable, void> | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 释放此贴图的资源,将不能再被使用
|
* 释放此贴图的资源,将不能再被使用
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user