From ca4a9dd51297b251d375c9e74567de1487b14e15 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Sat, 5 Oct 2024 23:39:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E8=BF=BD=E9=80=90=E6=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/project/floors/MT16.js | 2 +- src/core/render/preset/viewport.ts | 20 +- src/data/logger.json | 3 +- src/game/state/move.ts | 2 +- src/game/system.ts | 2 +- src/plugin/chase/chase.ts | 505 ++++++++++--------- src/plugin/chase/chase1.ts | 754 +++++++++++++---------------- src/plugin/chase/data.ts | 52 -- src/plugin/chase/index.ts | 9 + src/plugin/game/fallback.ts | 2 +- src/plugin/index.ts | 3 +- 11 files changed, 641 insertions(+), 713 deletions(-) delete mode 100644 src/plugin/chase/data.ts create mode 100644 src/plugin/chase/index.ts diff --git a/public/project/floors/MT16.js b/public/project/floors/MT16.js index a52a9d5..7f89fe2 100644 --- a/public/project/floors/MT16.js +++ b/public/project/floors/MT16.js @@ -400,7 +400,7 @@ main.floors.MT16= }, { "type": "function", - "function": "function(){\ncore.startChase(1);\n}" + "function": "function(){\nMota.Plugin.require('chase_r').startChase(0);\n}" }, { "type": "autoSave" diff --git a/src/core/render/preset/viewport.ts b/src/core/render/preset/viewport.ts index dadfe0e..f80de61 100644 --- a/src/core/render/preset/viewport.ts +++ b/src/core/render/preset/viewport.ts @@ -145,15 +145,15 @@ export class FloorViewport implements ILayerGroupRenderExtends { * @param x 目标图格横坐标 * @param y 目标图格纵坐标 */ - moveTo(x: number, y: number) { + moveTo(x: number, y: number, time: number = 200) { if (!this.enabled) return; const { x: nx, y: ny } = this.getBoundedPosition(x, y); if (this.inTransition) { const distance = Math.hypot(this.nx - nx, this.ny - ny); - const time = core.clamp(distance * 200, 200, 600); - this.createTransition(nx, ny, time); + const t = core.clamp(distance * time, time, time * 3); + this.createTransition(nx, ny, t); } else { - this.createTransition(nx, ny, 200); + this.createTransition(nx, ny, time); // const moveSpeed = 1000 / this.hero.speed; // this.speedX = moveSpeed; // this.speedY = moveSpeed; @@ -182,10 +182,10 @@ export class FloorViewport implements ILayerGroupRenderExtends { * @param x 目标图格横坐标 * @param y 目标图格纵坐标 */ - mutateTo(x: number, y: number) { + mutateTo(x: number, y: number, time: number = this.transitionTime) { if (!this.enabled) return; const { x: nx, y: ny } = this.getBoundedPosition(x, y); - this.createTransition(nx, ny, this.transitionTime); + this.createTransition(nx, ny, time); } private createTransition(x: number, y: number, time: number) { @@ -374,12 +374,12 @@ export class FloorViewport implements ILayerGroupRenderExtends { } const adapter = new RenderAdapter('viewport'); -adapter.receive('mutateTo', (item, x, y) => { - item.mutateTo(x, y); +adapter.receive('mutateTo', (item, x, y, time) => { + item.mutateTo(x, y, time); return Promise.resolve(); }); -adapter.receive('moveTo', (item, x, y) => { - item.moveTo(x, y); +adapter.receive('moveTo', (item, x, y, time) => { + item.moveTo(x, y, time); return Promise.resolve(); }); adapter.receive('setPosition', (item, x, y) => { diff --git a/src/data/logger.json b/src/data/logger.json index 24d801a..5e5b70f 100644 --- a/src/data/logger.json +++ b/src/data/logger.json @@ -18,7 +18,8 @@ "1101": "Shadow extension needs 'floor-hero' extension as dependency.", "1201": "Floor-damage extension needs 'floor-binder' extension as dependency.", "1301": "Portal extension need 'floor-binder' extension as dependency.", - "1401": "Halo extension needs 'floor-binder' extension as dependency." + "1401": "Halo extension needs 'floor-binder' extension as dependency.", + "1501": "Cannot add listener to started chase." }, "warn": { "1": "Resource with type of 'none' is loaded.", diff --git a/src/game/state/move.ts b/src/game/state/move.ts index 889eda0..f5ba890 100644 --- a/src/game/state/move.ts +++ b/src/game/state/move.ts @@ -617,7 +617,7 @@ export class HeroMover extends ObjectMoverBase { const adapter = HeroMover.adapter; const viewport = HeroMover.viewport; if (!adapter || !viewport) return; - viewport.all('moveTo', x, y); + viewport.all('moveTo', x, y, this.moveSpeed * 2); adapter.sync('setAnimateDir', showDir); await adapter.all('move', moveDir); } diff --git a/src/game/system.ts b/src/game/system.ts index f1ad5c2..97e756d 100644 --- a/src/game/system.ts +++ b/src/game/system.ts @@ -155,7 +155,7 @@ interface PluginInterface { pop_r: typeof import('../plugin/pop'); use_r: typeof import('../plugin/use'); fly_r: typeof import('../plugin/ui/fly'); - chase_r: typeof import('../plugin/chase/chase'); + chase_r: typeof import('../plugin/chase'); completion_r: typeof import('../plugin/completion'); gameCanvas_r: typeof import('../plugin/fx/gameCanvas'); frag_r: typeof import('../plugin/fx/frag'); diff --git a/src/plugin/chase/chase.ts b/src/plugin/chase/chase.ts index 26b0e59..b1e24e6 100644 --- a/src/plugin/chase/chase.ts +++ b/src/plugin/chase/chase.ts @@ -1,256 +1,305 @@ -import { Animation, circle, hyper, sleep, TimingFn } from 'mutate-animate'; -import { completeAchievement } from '../ui/achievement'; -import { has } from '../utils'; -import { ChaseCameraData, ChasePath, getChaseDataByIndex } from './data'; +import { logger } from '@/core/common/logger'; +import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d'; +import { CameraAnimation } from '@/core/render/camera'; +import { LayerGroup } from '@/core/render/preset/layer'; +import { MotaRenderer } from '@/core/render/render'; +import { Sprite } from '@/core/render/sprite'; +import { disableViewport, enableViewport } from '@/core/render/utils'; +import type { HeroMover, MoveStep } from '@/game/state/move'; +import EventEmitter from 'eventemitter3'; -// todo: 优化,可以继承自EventEmitter - -export function shake2(power: number, timing: TimingFn): TimingFn { - let r = 0; - return t => { - r += Math.PI / 2; - return Math.sin(r) * power * timing(t); - }; +export interface ChaseData { + path: Partial>; + camera: Partial>; } -export class Chase { - /** - * 动画实例 - */ - ani: Animation = new Animation(); +interface TimeListener { + fn: (emitTime: number) => void; + time: number; +} - /** - * 追逐战的路径 - */ - path: ChasePath; +interface LocListener { + fn: (x: number, y: number) => void; + floorId: FloorIds; + once: boolean; +} - /** - * 是否展示路径 - */ - showPath: boolean = false; +interface ChaseEvent { + changeFloor: [floor: FloorIds]; + end: [success: boolean]; + start: []; + step: [x: number, y: number]; + frame: [totalTime: number, floorTime: number]; +} - endFn?: (lose: boolean) => void; +export class Chase extends EventEmitter { + /** 本次追逐战的数据 */ + private readonly data: ChaseData; - /** - * 开始一个追逐战 - * @param index 追逐战索引 - * @param path 追逐战的路线 - * @param fn 开始时执行的函数 - */ - constructor( - path: ChasePath, - fns: ((chase: Chase) => void)[], - camera: ChaseCameraData[], - showPath: boolean = false - ) { - this.path = path; - flags.__lockViewport__ = true; - flags.onChase = true; - flags.chaseTime = { - [core.status.floorId]: Date.now() - }; - this.ani - .absolute() - .time(0) - .move(core.bigmap.offsetX / 32, core.bigmap.offsetY / 32); - fns.forEach(v => v(this)); - const added: FloorIds[] = []; - const ctx = core.createCanvas('chasePath', 0, 0, 0, 0, 35); + /** 是否显示路线 */ + private showPath: boolean = false; + /** 每层的路线显示 */ + private pathMap: Map = new Map(); + /** 当前的摄像机动画 */ + private nowCamera?: CameraAnimation; + /** 当前楼层 */ + private nowFloor?: FloorIds; - for (const [id, x, y, start, time, mode, path] of camera) { - if (!added.includes(id)) { - this.on( - id, - 0, - () => { - flags.__lockViewport__ = false; - core.drawHero(); - flags.__lockViewport__ = true; - this.ani - .time(0) - .move( - core.bigmap.offsetX / 32, - core.bigmap.offsetY / 32 - ); - }, - true - ); - added.push(id); - } - if (!has(path)) { - this.on(id, start, () => { - this.ani.time(time).mode(mode).move(x, y); - }); - } else { - this.on(id, start, () => { - this.ani.time(time).mode(mode).moveAs(path); - }); - } - } + /** 开始时刻 */ + private startTime: number = 0; + /** 进入当前楼层的时刻 */ + private nowFloorTime: number = 0; + /** 是否正在进行追逐战 */ + private started: boolean = false; - this.ani.ticker.add(() => { - if (!flags.floorChanging) { - core.setViewport(this.ani.x * 32, this.ani.y * 32); - core.relocateCanvas(ctx, -this.ani.x * 32, -this.ani.y * 32); + /** 路径显示的sprite */ + private pathSprite?: Sprite; + /** 当前 LayerGroup 渲染元素 */ + private layer: LayerGroup; + /** 委托ticker的id */ + private delegation: number = -1; + + /** 时间监听器 */ + private onTimeListener: TimeListener[] = []; + /** 楼层时间监听器 */ + private onFloorTimeListener: Partial> = {}; + /** 勇士位置监听器 */ + private onHeroLocListener: Map> = new Map(); + + /** 勇士移动实例 */ + private heroMove: HeroMover; + + constructor(data: ChaseData, showPath: boolean = false) { + super(); + + this.data = data; + this.showPath = showPath; + + const render = MotaRenderer.get('render-main')!; + const layer = render.getElementById('layer-main')! as LayerGroup; + this.layer = layer; + + const mover = Mota.require('module', 'State').heroMoveCollection.mover; + this.heroMove = mover; + + mover.on('stepEnd', this.onStepEnd); + } + + private onStepEnd = (step: MoveStep) => { + if (step.type === 'speed') return; + const { x, y } = core.status.hero.loc; + this.emitHeroLoc(x, y); + this.emit('step', x, y); + }; + + private emitHeroLoc(x: number, y: number) { + if (!this.nowFloor) return; + const floor = core.status.maps[this.nowFloor]; + const width = floor.width; + const index = x + y * width; + const list = this.onHeroLocListener.get(index); + if (!list) return; + const toDelete = new Set(); + list.forEach(v => { + if (v.floorId === this.nowFloor) { + v.fn(x, y); + if (v.once) toDelete.add(v); } }); + toDelete.forEach(v => list.delete(v)); + } - if (showPath) { - for (const [id, p] of Object.entries(path) as [ - FloorIds, - LocArr[] - ][]) { - this.on(id, 0, () => { - const floor = core.status.maps[id]; - core.resizeCanvas(ctx, floor.width * 32, floor.height * 32); - ctx.beginPath(); - ctx.moveTo(p[0][0] * 32 + 16, p[1][1] * 32 + 24); - ctx.lineJoin = 'round'; - ctx.lineWidth = 4; - ctx.strokeStyle = 'cyan'; - ctx.globalAlpha = 0.3; - p.forEach((v, i, a) => { - if (i === 0) return; - const [x, y] = v; - ctx.lineTo(x * 32 + 16, y * 32 + 24); - }); - ctx.stroke(); - }); + private emitTime() { + const now = Date.now(); + const nTime = now - this.startTime; + const fTime = now - this.nowFloorTime; + + this.emit('frame', nTime, fTime); + + while (1) { + const time = this.onTimeListener[0]; + if (!time) break; + if (time.time <= nTime) { + time.fn(nTime); + this.onTimeListener.shift(); + } else { + break; + } + } + + if (!this.nowFloor) return; + const floor = this.onFloorTimeListener[this.nowFloor]; + if (!floor) return; + + while (1) { + const time = floor[0]; + if (!time) break; + if (time.time <= fTime) { + time.fn(nTime); + floor.shift(); + } else { + break; } } } - /** - * 在追逐战的某个时刻执行函数 - * @param floorId 楼层id - * @param time 该楼层中经过的时间 - * @param fn 执行的函数 - */ - on( - floorId: FloorIds, - time: number, - fn: (chase: Chase) => void, - first: boolean = false - ) { - const func = () => { - if (!flags.chaseTime?.[floorId]) return; - if ( - Date.now() - (flags.chaseTime?.[floorId] ?? Date.now()) >= - time - ) { - fn(this); - this.ani.ticker.remove(func); - } - }; - this.ani.ticker.add(func, first); + private tick = () => { + if (!this.started) return; + const floor = core.status.floorId; + if (floor !== this.nowFloor) { + this.changeFloor(floor); + } + this.emitTime(); + }; + + private readyPath() { + for (const [key, nodes] of Object.entries(this.data.path)) { + if (nodes.length === 0) return; + const floor = key as FloorIds; + const canvas = new MotaOffscreenCanvas2D(); + const ctx = canvas.ctx; + const cell = 32; + const { width, height } = core.status.maps[floor]; + canvas.setHD(true); + canvas.size(width * cell, height * cell); + const [fx, fy] = nodes.shift()!; + ctx.beginPath(); + ctx.moveTo(fx, fy); + nodes.forEach(([x, y]) => { + ctx.lineTo(x, y); + }); + ctx.strokeStyle = '#0ff'; + ctx.globalAlpha = 0.6; + ctx.stroke(); + this.pathMap.set(floor, canvas); + } + this.pathSprite = new Sprite('absolute', false, true); + this.layer.appendChild(this.pathSprite); } /** - * 当勇士移动到某个点上时执行函数 - * @param x 横坐标 - * @param y 纵坐标 - * @param floorId 楼层id - * @param fn 执行的函数 - * @param mode 为0时,当传入数组时表示勇士在任意一个位置都执行,否则是每个位置执行一次 + * 当到达某个时间时触发函数 + * @param time 触发时刻 + * @param fn 触发时执行的函数,函数的参数表示实际触发时间 */ - onHeroLoc( - floorId: FloorIds, - fn: (chase: Chase) => void, - x?: number | number[], - y?: number | number[], - mode: 0 | 1 = 0 - ) { - if (mode === 1) { - if (typeof x === 'number') x = [x]; - if (typeof y === 'number') y = [y]; - x!.forEach(v => { - (y as number[]).forEach(vv => { - this.onHeroLoc(floorId, fn, v, vv); - }); - }); + onTime(time: number, fn: (emitTime: number) => void) { + if (this.started) { + logger.error(1501); return; } - const judge = () => { - if (core.status.floorId !== floorId) return false; - if (has(x)) { - if (typeof x === 'number') { - if (core.status.hero.loc.x !== x) return false; - } else { - if (!x.includes(core.status.hero.loc.x)) return false; - } - } - if (has(y)) { - if (typeof y === 'number') { - if (core.status.hero.loc.y !== y) return false; - } else { - if (!y.includes(core.status.hero.loc.y)) return false; - } - } - return true; - }; - const func = () => { - if (judge()) { - fn(this); - try { - this.ani.ticker.remove(func); - } catch {} - } - }; - this.ani.ticker.add(func); + this.onTimeListener.push({ time, fn }); } /** - * 设置路径显示状态 - * @param show 是否显示路径 + * 当在某个楼层中到达某个时间时触发函数 + * @param floor 触发楼层 + * @param time 从进入该楼层开始计算的触发时刻 + * @param fn 触发时执行的函数 */ - setPathShowStatus(show: boolean) { - this.showPath = show; - } - - /** - * 当追逐战结束后执行函数 - * @param fn 执行的函数 - */ - onEnd(fn: (lose: boolean) => void) { - this.endFn = fn; - } - - /** - * 结束这个追逐战 - */ - end(lose: boolean = false) { - this.ani.ticker.destroy(); - delete flags.onChase; - delete flags.chase; - delete flags.chaseTime; - delete flags.chaseHard; - delete flags.chaseIndex; - flags.__lockViewport__ = false; - core.deleteCanvas('chasePath'); - if (this.endFn) this.endFn(lose); - } -} - -export async function startChase(index: number) { - const data = getChaseDataByIndex(index); - flags.chaseIndex = index; - flags.onChase = true; - await sleep(20); - const chase = new Chase( - data.path, - data.fns, - data.camera, - flags.chaseHard === 0 - ); - flags.chase = chase; - const hard = flags.chaseHard; - - // 成就 - chase.onEnd(lose => { - if (hard === 1) { - if (index === 1 && !lose) { - completeAchievement('challenge', 0); - } + onFloorTime(floor: FloorIds, time: number, fn: (emitTime: number) => void) { + if (this.started) { + logger.error(1501); + return; } - }); + this.onFloorTimeListener[floor] ??= []; + const list = this.onFloorTimeListener[floor]; + list.push({ time, fn }); + } + + private ensureLocListener(index: number) { + const listener = this.onHeroLocListener.get(index); + if (listener) return listener; + else { + const set = new Set(); + this.onHeroLocListener.set(index, set); + return set; + } + } + + /** + * 当勇士走到某一层的某一格时执行函数 + * @param x 触发横坐标 + * @param y 触发纵坐标 + * @param floor 触发楼层 + * @param fn 触发函数 + * @param once 是否只执行一次 + */ + onLoc( + x: number, + y: number, + floor: FloorIds, + fn: (x: number, y: number) => void, + once: boolean = false + ) { + if (this.started) { + logger.error(1501); + return; + } + const map = core.status.maps[floor]; + const { width } = map; + const index = x + y * width; + const set = this.ensureLocListener(index); + set.add({ floorId: floor, fn, once }); + } + + /** + * 当勇士走到某一层的某一格时执行函数,且只执行一次 + * @param x 触发横坐标 + * @param y 触发纵坐标 + * @param floor 触发楼层 + * @param fn 触发函数 + */ + onceLoc( + x: number, + y: number, + floor: FloorIds, + fn: (x: number, y: number) => void + ) { + this.onLoc(x, y, floor, fn, true); + } + + /** + * 切换楼层 + * @param floor 目标楼层 + */ + changeFloor(floor: FloorIds) { + if (floor === this.nowFloor) return; + this.nowFloor = floor; + if (this.nowCamera) { + this.nowCamera.destroy(); + } + const camera = this.data.camera[floor]; + if (camera) { + camera.start(); + this.nowCamera = camera; + } + this.nowFloorTime = Date.now(); + this.emit('changeFloor', floor); + } + + start() { + disableViewport(); + if (this.showPath) this.readyPath(); + this.changeFloor(core.status.floorId); + this.startTime = Date.now(); + this.delegation = this.layer.delegateTicker(this.tick); + this.started = true; + for (const floorTime of Object.values(this.onFloorTimeListener)) { + floorTime.sort((a, b) => a.time - b.time); + } + this.onTimeListener.sort((a, b) => a.time - b.time); + this.emit('start'); + } + + /** + * 结束这次追逐战 + * @param success 是否成功逃脱 + */ + end(success: boolean) { + enableViewport(); + this.layer.removeTicker(this.delegation); + this.pathSprite?.destroy(); + this.heroMove.off('stepEnd', this.onStepEnd); + this.emit('end', success); + } } diff --git a/src/plugin/chase/chase1.ts b/src/plugin/chase/chase1.ts index bfed89b..0cbcee7 100644 --- a/src/plugin/chase/chase1.ts +++ b/src/plugin/chase/chase1.ts @@ -1,12 +1,12 @@ import { Animation, bezier, hyper, linear, shake, sleep } from 'mutate-animate'; -import { Chase, shake2 } from './chase'; -import { ChaseCameraData } from './data'; +import { Chase, ChaseData } from './chase'; import { completeAchievement } from '../ui/achievement'; +import { Camera, CameraAnimation } from '@/core/render/camera'; +import { LayerGroup } from '@/core/render/preset/layer'; +import { MotaRenderer } from '@/core/render/render'; +import { Sprite } from '@/core/render/sprite'; -const ani = new Animation(); -ani.register('rect', 0); - -export const path1: Partial> = { +const path: Partial> = { MT16: [ [23, 23], [0, 23] @@ -97,75 +97,117 @@ export const path1: Partial> = { ] }; -export const camera1: ChaseCameraData[] = [ - ['MT16', 0, 10, 0, 1600, hyper('sin', 'in')], - ['MT15', 45, 0, 0, 2324, hyper('sin', 'in')], - ['MT15', 40, 0, 2324, 1992, hyper('sin', 'out')], - ['MT15', 41, 0, 5312, 498, hyper('sin', 'in-out')], - ['MT15', 37, 0, 5810, 1660, hyper('sin', 'in')], - ['MT15', 29, 0, 7470, 830, hyper('sin', 'out')], - ['MT15', 25, 0, 11454, 996, hyper('sin', 'in')], - ['MT15', 12, 0, 12450, 996, linear()], - ['MT15', 0, 0, 13446, 1470, hyper('sin', 'out')], - ['MT14', 109, 0, 0, 1328, hyper('sin', 'in')], - ['MT14', 104, 0, 1328, 332, hyper('sin', 'out')], - ['MT14', 92, 0, 5478, 2822, hyper('sin', 'in')], - ['MT14', 84, 0, 8300, 1992, linear()], - ['MT14', 74, 0, 10292, 2988, linear()], - ['MT14', 65, 0, 13280, 2988, linear()], - ['MT14', 58, 0, 16268, 1992, linear()], - ['MT14', 47, 0, 18260, 3320, linear()], - ['MT14', 36, 0, 21580, 3320, linear()], - ['MT14', 0, 0, 24900, 9960, linear()] -]; +let back: Sprite | undefined; /** - * 追逐战开始前的初始化函数,移除所有血瓶和门等 + * 初始化并开始这个追逐战 */ -export function init1() { - return Mota.Plugin.require('chase_g').chaseInit1(); +export function initChase() { + const ani = new Animation(); + + const render = MotaRenderer.get('render-main')!; + const layer = render.getElementById('layer-main')! as LayerGroup; + + const camera = Camera.for(layer); + camera.clearOperation(); + const animation16 = new CameraAnimation(camera); + const animation15 = new CameraAnimation(camera); + const animation14 = new CameraAnimation(camera); + + const data: ChaseData = { + path, + camera: { + MT16: animation16, + MT15: animation15, + MT14: animation14 + } + }; + + const chase = new Chase(data, flags.chaseHard === 0); + + const translate = camera.addTranslate(); + const rotate = camera.addRotate(); + + // MT16 摄像机动画 + animation16.translate(translate, 0, 10, 1600, 0, hyper('sin', 'in')); + // MT15 摄像机动画 + animation15.translate(translate, 45, 0, 2324, 0, hyper('sin', 'in')); + animation15.translate(translate, 40, 0, 1992, 2324, hyper('sin', 'out')); + animation15.translate(translate, 41, 0, 498, 5312, hyper('sin', 'in-out')); + animation15.translate(translate, 37, 0, 1660, 5810, hyper('sin', 'in')); + animation15.translate(translate, 29, 0, 830, 7470, hyper('sin', 'out')); + animation15.translate(translate, 25, 0, 996, 11454, hyper('sin', 'in')); + animation15.translate(translate, 12, 0, 996, 12450, linear()); + animation15.translate(translate, 0, 0, 1470, 13446, hyper('sin', 'out')); + // MT14 摄像机动画 + animation14.translate(translate, 109, 0, 1328, 0, hyper('sin', 'in')); + animation14.translate(translate, 104, 0, 332, 1328, hyper('sin', 'out')); + animation14.translate(translate, 92, 0, 2822, 5478, hyper('sin', 'in')); + animation14.translate(translate, 84, 0, 1992, 8300, linear()); + animation14.translate(translate, 74, 0, 2988, 10292, linear()); + animation14.translate(translate, 65, 0, 2988, 13280, linear()); + animation14.translate(translate, 58, 0, 1992, 16268, linear()); + animation14.translate(translate, 47, 0, 3320, 18260, linear()); + animation14.translate(translate, 36, 0, 3320, 21580, linear()); + animation14.translate(translate, 0, 0, 9960, 24900, linear()); + + judgeFail1(chase, ani); + drawBack(chase, ani); + para1(chase); + para2(chase); + para3(chase, ani); + + Mota.Plugin.require('chase_g').chaseInit1(); + + chase.start(); + wolfMove(chase); } -export function chaseShake(chase: Chase) { - chase.ani - .mode(shake2(2 / 32, bezier(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), true) - .time(50000) - .shake(1, 0); -} +// function chaseShake(chase: Chase) { +// chase.ani +// .mode(shake2(2 / 32, bezier(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), true) +// .time(50000) +// .shake(1, 0); +// } -export async function wolfMove(chase: Chase) { +async function wolfMove(chase: Chase) { core.moveBlock(23, 17, Array(6).fill('down'), 80); await sleep(550); core.setBlock(508, 23, 23); } -export function judgeFail1(chase: Chase) { - chase.ani.ticker.add(() => { +function judgeFail1(chase: Chase, ani: Animation) { + chase.on('frame', () => { if (core.status.hero.loc.x > core.bigmap.offsetX / 32 + 17) { - chase.end(true); + chase.end(false); ani.time(750).apply('rect', 0); core.lose('逃跑失败'); } }); } -export function drawBack(chase: Chase) { - chase.on('MT15', 0, () => { +function drawBack(chase: Chase, ani: Animation) { + chase.onFloorTime('MT15', 0, () => { + ani.register('rect', 0); ani.mode(hyper('sin', 'out')).time(1500).absolute().apply('rect', 64); - const ctx = core.createCanvas('chaseBack', 0, 0, 480, 480, 120); - ctx.fillStyle = '#000'; - const fn = () => { - if (!ctx) ani.ticker.remove(fn); - core.clearMap(ctx); + + const render = MotaRenderer.get('render-main')!; + const layer = render.getElementById('layer-main')! as LayerGroup; + back = new Sprite('absolute', false); + back.size(480, 480); + back.pos(0, 0); + back.append(layer); + back.setRenderFn(canvas => { + const ctx = canvas.ctx; + ctx.fillStyle = '#000'; ctx.fillRect(0, 0, 480, ani.value.rect); ctx.fillRect(0, 480, 480, -ani.value.rect); - }; - ani.ticker.add(fn); + }); }); } -export function para1(chase: Chase) { - chase.on('MT15', 830, () => { +function para1(chase: Chase) { + chase.onFloorTime('MT15', 830, () => { for (let tx = 53; tx < 58; tx++) { for (let ty = 3; ty < 8; ty++) { core.setBlock(336, tx, ty); @@ -174,23 +216,23 @@ export function para1(chase: Chase) { core.drawAnimate('explosion3', 55, 5); core.drawAnimate('stone', 55, 5); }); - chase.on('MT15', 1080, () => { + chase.onFloorTime('MT15', 1080, () => { core.setBlock(336, 58, 9); core.setBlock(336, 59, 9); core.drawAnimate('explosion1', 58, 9); core.drawAnimate('explosion1', 59, 9); }); - chase.on('MT15', 1190, () => { + chase.onFloorTime('MT15', 1190, () => { core.setBlock(336, 53, 8); core.setBlock(336, 52, 8); core.drawAnimate('explosion1', 53, 8); core.drawAnimate('explosion1', 52, 8); }); - chase.on('MT15', 1580, () => { + chase.onFloorTime('MT15', 1580, () => { core.setBlock(336, 51, 7); core.drawAnimate('explosion1', 51, 7); }); - chase.on('MT15', 1830, () => { + chase.onFloorTime('MT15', 1830, () => { core.setBlock(336, 47, 7); core.setBlock(336, 49, 9); core.drawAnimate('explosion1', 49, 9); @@ -198,377 +240,255 @@ export function para1(chase: Chase) { }); } -export function para2(chase: Chase) { - chase.onHeroLoc( - 'MT15', - () => { - core.setBlock(336, 45, 9); - core.drawAnimate('explosion1', 45, 9); - }, - 45, - 8 - ); - chase.onHeroLoc( - 'MT15', - () => { - core.setBlock(336, 44, 6); - core.drawAnimate('explosion1', 44, 6); - }, - 45, - 6 - ); - chase.onHeroLoc( - 'MT15', - () => { - core.setBlock(336, 44, 4); - core.drawAnimate('explosion1', 44, 4); - core.drawAnimate('explosion1', 48, 6); - core.removeBlock(48, 6); - }, - 45, - 4 - ); - chase.onHeroLoc( - 'MT15', - () => { - core.setBlock(336, 41, 4); - core.setBlock(336, 32, 6); - core.drawAnimate('explosion1', 41, 4); - core.drawAnimate('explosion1', 32, 6); - }, - 41, - 3 - ); - chase.onHeroLoc( - 'MT15', - () => { - core.drawAnimate('explosion3', 37, 7); - core.vibrate('vertical', 1000, 25, 10); - for (let tx = 36; tx < 42; tx++) { - for (let ty = 4; ty < 11; ty++) { - core.setBlock(336, tx, ty); - } +function para2(chase: Chase) { + let emitted32x9 = false; + chase.onceLoc(45, 8, 'MT15', () => { + core.setBlock(336, 45, 9); + core.drawAnimate('explosion1', 45, 9); + }); + chase.onceLoc(45, 6, 'MT15', () => { + core.setBlock(336, 44, 6); + core.drawAnimate('explosion1', 44, 6); + }); + chase.onceLoc(45, 4, 'MT15', () => { + core.setBlock(336, 44, 4); + core.drawAnimate('explosion1', 44, 4); + core.drawAnimate('explosion1', 48, 6); + core.removeBlock(48, 6); + }); + chase.onceLoc(41, 3, 'MT15', () => { + core.setBlock(336, 41, 4); + core.setBlock(336, 32, 6); + core.drawAnimate('explosion1', 41, 4); + core.drawAnimate('explosion1', 32, 6); + }); + chase.onceLoc(35, 3, 'MT15', () => { + core.drawAnimate('explosion3', 37, 7); + core.vibrate('vertical', 1000, 25, 10); + for (let tx = 36; tx < 42; tx++) { + for (let ty = 4; ty < 11; ty++) { + core.setBlock(336, tx, ty); } - }, - 35, - 3 - ); - chase.onHeroLoc( - 'MT15', - () => { - core.vibrate('vertical', 10000, 25, 1); - core.removeBlock(34, 8); - core.removeBlock(33, 8); - core.drawAnimate('explosion1', 34, 8); - core.drawAnimate('explosion1', 33, 8); - }, - 31, - 5 - ); - chase.onHeroLoc( - 'MT15', - () => { - core.setBlock(336, 32, 9); - core.drawAnimate('explosion1', 32, 9); - }, - 33, - 7 - ); - chase.onHeroLoc( - 'MT15', - () => { - core.removeBlock(32, 9); - core.drawAnimate('explosion1', 32, 9); - }, - [33, 34, 34], - 9 - ); + } + }); + chase.onceLoc(31, 5, 'MT15', () => { + core.vibrate('vertical', 10000, 25, 1); + core.removeBlock(34, 8); + core.removeBlock(33, 8); + core.drawAnimate('explosion1', 34, 8); + core.drawAnimate('explosion1', 33, 8); + }); + chase.onceLoc(33, 7, 'MT15', () => { + core.setBlock(336, 32, 9); + core.drawAnimate('explosion1', 32, 9); + }); + chase.onceLoc(33, 9, 'MT15', () => { + if (emitted32x9) return; + emitted32x9 = true; + core.removeBlock(32, 9); + core.drawAnimate('explosion1', 32, 9); + }); + chase.onceLoc(34, 9, 'MT15', () => { + if (emitted32x9) return; + emitted32x9 = true; + core.removeBlock(32, 9); + core.drawAnimate('explosion1', 32, 9); + }); + chase.onceLoc(35, 9, 'MT15', () => { + if (emitted32x9) return; + emitted32x9 = true; + core.removeBlock(32, 9); + core.drawAnimate('explosion1', 32, 9); + }); for (let x = 19; x < 31; x++) { const xx = x; - chase.onHeroLoc( - 'MT15', - () => { - core.setBlock(336, xx + 1, 11); - core.drawAnimate('explosion1', xx + 1, 11); - }, - xx, - 11 - ); + chase.onceLoc(xx, 11, 'MT15', () => { + core.setBlock(336, xx + 1, 11); + core.drawAnimate('explosion1', xx + 1, 11); + }); } } -export function para3(chase: Chase) { - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 126, 6); - core.setBlock(336, 124, 6); - core.setBlock(336, 124, 9); - core.setBlock(336, 126, 9); - core.drawAnimate('explosion1', 126, 6); - core.drawAnimate('explosion1', 124, 6); - core.drawAnimate('explosion1', 124, 9); - core.drawAnimate('explosion1', 126, 9); - }, - 126, - 7 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(508, 127, 7); - core.jumpBlock(127, 7, 112, 7, 500, true); - setTimeout(() => { - core.setBlock(509, 112, 7); - }, 520); - core.drawHeroAnimate('amazed'); - core.setBlock(336, 121, 6); - core.setBlock(336, 122, 6); - core.setBlock(336, 120, 8); - core.setBlock(336, 121, 8); - core.setBlock(336, 122, 8); - core.drawAnimate('explosion1', 121, 6); - core.drawAnimate('explosion1', 122, 6); - core.drawAnimate('explosion1', 120, 8); - core.drawAnimate('explosion1', 121, 8); - core.drawAnimate('explosion1', 122, 8); - }, - 123, - 7 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 109, 11); - core.removeBlock(112, 8); - core.drawAnimate('explosion1', 109, 11); - core.drawAnimate('explosion1', 112, 8); - core.insertAction([ - { type: 'moveHero', time: 400, steps: ['backward:1'] } - ]); - chase.onHeroLoc( - 'MT14', - () => { - core.jumpBlock(112, 7, 110, 4, 500, true); - core.drawHeroAnimate('amazed'); - setTimeout(() => { - core.setBlock(506, 110, 4); - }, 540); - }, - 112, - 8 - ); - }, - 110, - 10 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 117, 6); - core.setBlock(336, 116, 6); - core.setBlock(336, 115, 6); - core.setBlock(336, 114, 6); - core.setBlock(336, 117, 8); - core.setBlock(336, 116, 8); - core.drawAnimate('explosion1', 117, 6); - core.drawAnimate('explosion1', 116, 6); - core.drawAnimate('explosion1', 115, 6); - core.drawAnimate('explosion1', 114, 6); - core.drawAnimate('explosion1', 116, 8); - core.drawAnimate('explosion1', 117, 8); - }, - 118, - 7 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 112, 8); - core.setBlock(336, 113, 7); - core.drawAnimate('explosion1', 112, 8); - core.drawAnimate('explosion1', 113, 7); - }, - 112, - 7 - ); - chase.onHeroLoc( - 'MT14', - () => { - for (let tx = 111; tx <= 115; tx++) { - core.setBlock(336, tx, 10); - core.drawAnimate('explosion1', tx, 10); +function para3(chase: Chase, ani: Animation) { + chase.onceLoc(126, 7, 'MT14', () => { + core.setBlock(336, 126, 6); + core.setBlock(336, 124, 6); + core.setBlock(336, 124, 9); + core.setBlock(336, 126, 9); + core.drawAnimate('explosion1', 126, 6); + core.drawAnimate('explosion1', 124, 6); + core.drawAnimate('explosion1', 124, 9); + core.drawAnimate('explosion1', 126, 9); + }); + chase.onceLoc(123, 7, 'MT14', () => { + core.setBlock(508, 127, 7); + core.jumpBlock(127, 7, 112, 7, 500, true); + setTimeout(() => { + core.setBlock(509, 112, 7); + }, 520); + core.drawHeroAnimate('amazed'); + core.setBlock(336, 121, 6); + core.setBlock(336, 122, 6); + core.setBlock(336, 120, 8); + core.setBlock(336, 121, 8); + core.setBlock(336, 122, 8); + core.drawAnimate('explosion1', 121, 6); + core.drawAnimate('explosion1', 122, 6); + core.drawAnimate('explosion1', 120, 8); + core.drawAnimate('explosion1', 121, 8); + core.drawAnimate('explosion1', 122, 8); + }); + let emitted110x10 = false; + let emitted112x8 = false; + chase.onceLoc(110, 10, 'MT14', () => { + core.setBlock(336, 109, 11); + core.removeBlock(112, 8); + core.drawAnimate('explosion1', 109, 11); + core.drawAnimate('explosion1', 112, 8); + core.insertAction([ + { type: 'moveHero', time: 400, steps: ['backward:1'] } + ]); + emitted110x10 = true; + }); + chase.onLoc(112, 8, 'MT14', () => { + if (!emitted110x10 || emitted112x8) return; + core.jumpBlock(112, 7, 110, 4, 500, true); + core.drawHeroAnimate('amazed'); + setTimeout(() => { + core.setBlock(506, 110, 4); + }, 540); + emitted112x8 = true; + }); + chase.onceLoc(118, 7, 'MT14', () => { + core.setBlock(336, 117, 6); + core.setBlock(336, 116, 6); + core.setBlock(336, 115, 6); + core.setBlock(336, 114, 6); + core.setBlock(336, 117, 8); + core.setBlock(336, 116, 8); + core.drawAnimate('explosion1', 117, 6); + core.drawAnimate('explosion1', 116, 6); + core.drawAnimate('explosion1', 115, 6); + core.drawAnimate('explosion1', 114, 6); + core.drawAnimate('explosion1', 116, 8); + core.drawAnimate('explosion1', 117, 8); + }); + chase.onceLoc(112, 7, 'MT14', () => { + core.setBlock(336, 112, 8); + core.setBlock(336, 113, 7); + core.drawAnimate('explosion1', 112, 8); + core.drawAnimate('explosion1', 113, 7); + }); + chase.onceLoc(115, 7, 'MT14', () => { + for (let tx = 111; tx <= 115; tx++) { + core.setBlock(336, tx, 10); + core.drawAnimate('explosion1', tx, 10); + } + core.setBlock(336, 112, 8); + core.drawAnimate('explosion1', 112, 8); + }); + chase.onceLoc(110, 7, 'MT14', () => { + core.jumpBlock(97, 4, 120, -3, 2000); + for (let tx = 109; tx <= 120; tx++) { + for (let ty = 3; ty <= 11; ty++) { + if (ty == 7) continue; + core.setBlock(336, tx, ty); } - core.setBlock(336, 112, 8); - core.drawAnimate('explosion1', 112, 8); - }, - 115, - 7 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.jumpBlock(97, 4, 120, -3, 2000); - for (let tx = 109; tx <= 120; tx++) { - for (let ty = 3; ty <= 11; ty++) { - if (ty == 7) continue; - core.setBlock(336, tx, ty); - } + } + core.drawAnimate('explosion2', 119, 7); + core.removeBlock(105, 7); + core.drawAnimate('explosion1', 105, 7); + }); + chase.onceLoc(97, 3, 'MT14', () => { + core.setBlock(336, 95, 3); + core.setBlock(336, 93, 6); + core.drawAnimate('explosion1', 95, 3); + core.drawAnimate('explosion1', 93, 6); + }); + chase.onceLoc(88, 6, 'MT14', () => { + core.setBlock(336, 87, 4); + core.setBlock(336, 88, 5); + core.drawAnimate('explosion1', 87, 4); + core.drawAnimate('explosion1', 88, 5); + }); + chase.onceLoc(86, 6, 'MT14', () => { + core.setBlock(336, 84, 6); + core.setBlock(336, 85, 5); + core.setBlock(336, 86, 8); + core.drawAnimate('explosion1', 84, 6); + core.drawAnimate('explosion1', 85, 5); + core.drawAnimate('explosion1', 86, 8); + }); + chase.onceLoc(81, 9, 'MT14', () => { + core.setBlock(336, 81, 8); + core.setBlock(336, 82, 11); + core.drawAnimate('explosion1', 81, 8); + core.drawAnimate('explosion1', 82, 11); + }); + chase.onceLoc(72, 11, 'MT14', () => { + core.setBlock(336, 73, 8); + core.setBlock(336, 72, 4); + core.drawAnimate('explosion1', 73, 8); + core.drawAnimate('explosion1', 72, 4); + }); + chase.onceLoc(71, 7, 'MT14', () => { + for (let tx = 74; tx < 86; tx++) { + for (let ty = 3; ty < 12; ty++) { + core.setBlock(336, tx, ty); } - core.drawAnimate('explosion2', 119, 7); - core.removeBlock(105, 7); - core.drawAnimate('explosion1', 105, 7); - }, - 110, - 7 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 95, 3); - core.setBlock(336, 93, 6); - core.drawAnimate('explosion1', 95, 3); - core.drawAnimate('explosion1', 93, 6); - }, - 97, - 3 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 87, 4); - core.setBlock(336, 88, 5); - core.drawAnimate('explosion1', 87, 4); - core.drawAnimate('explosion1', 88, 5); - }, - 88, - 6 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 84, 6); - core.setBlock(336, 85, 5); - core.setBlock(336, 86, 8); - core.drawAnimate('explosion1', 84, 6); - core.drawAnimate('explosion1', 85, 5); - core.drawAnimate('explosion1', 86, 8); - }, - 86, - 6 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 81, 8); - core.setBlock(336, 82, 11); - core.drawAnimate('explosion1', 81, 8); - core.drawAnimate('explosion1', 82, 11); - }, - 81, - 9 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 73, 8); - core.setBlock(336, 72, 4); - core.drawAnimate('explosion1', 73, 8); - core.drawAnimate('explosion1', 72, 4); - }, - 72, - 11 - ); - chase.onHeroLoc( - 'MT14', - () => { - for (let tx = 74; tx < 86; tx++) { - for (let ty = 3; ty < 12; ty++) { - core.setBlock(336, tx, ty); - } + } + core.drawAnimate('explosion2', 79, 7); + core.vibrate('vertical', 4000, 25, 15); + }); + chase.onceLoc(68, 5, 'MT14', () => { + core.setBlock(336, 68, 4); + core.setBlock(336, 67, 6); + core.drawAnimate('explosion1', 68, 4); + core.drawAnimate('explosion1', 67, 6); + }); + chase.onceLoc(67, 10, 'MT14', () => { + for (let tx = 65; tx <= 72; tx++) { + for (let ty = 3; ty <= 9; ty++) { + core.setBlock(336, tx, ty); } - core.drawAnimate('explosion2', 79, 7); - core.vibrate('vertical', 4000, 25, 15); - }, - 71, - 7 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 68, 4); - core.setBlock(336, 67, 6); - core.drawAnimate('explosion1', 68, 4); - core.drawAnimate('explosion1', 67, 6); - }, - 68, - 5 - ); - chase.onHeroLoc( - 'MT14', - () => { - for (let tx = 65; tx <= 72; tx++) { - for (let ty = 3; ty <= 9; ty++) { - core.setBlock(336, tx, ty); - } + } + core.setBlock(336, 72, 10); + core.setBlock(336, 72, 11); + core.drawAnimate('explosion3', 69, 5); + }); + chase.onceLoc(64, 11, 'MT14', () => { + core.setBlock(336, 63, 9); + core.setBlock(336, 60, 8); + core.setBlock(336, 56, 11); + core.drawAnimate('explosion1', 63, 9); + core.drawAnimate('explosion1', 60, 8); + core.drawAnimate('explosion1', 56, 11); + }); + chase.onceLoc(57, 9, 'MT14', () => { + for (let tx = 58; tx <= 64; tx++) { + for (let ty = 3; ty <= 11; ty++) { + core.setBlock(336, tx, ty); } - core.setBlock(336, 72, 10); - core.setBlock(336, 72, 11); - core.drawAnimate('explosion3', 69, 5); - }, - 67, - 10 - ); - chase.onHeroLoc( - 'MT14', - () => { - core.setBlock(336, 63, 9); - core.setBlock(336, 60, 8); - core.setBlock(336, 56, 11); - core.drawAnimate('explosion1', 63, 9); - core.drawAnimate('explosion1', 60, 8); - core.drawAnimate('explosion1', 56, 11); - }, - 64, - 11 - ); - chase.onHeroLoc( - 'MT14', - () => { - for (let tx = 58; tx <= 64; tx++) { - for (let ty = 3; ty <= 11; ty++) { - core.setBlock(336, tx, ty); - } + } + core.drawAnimate('explosion2', 61, 7); + }); + chase.on('step', (x, y) => { + if (core.status.floorId !== 'MT14') return; + if (x > 20 && x < 49) { + for (let ty = 3; ty <= 11; ty++) { + core.setBlock(336, x + 4, ty); + core.drawAnimate('explosion1', x + 4, ty); } - core.drawAnimate('explosion2', 61, 7); - }, - 57, - 9 - ); - for (let x = 21; x < 49; x++) { - chase.onHeroLoc( - 'MT14', - () => { - for (let ty = 3; ty <= 11; ty++) { - core.setBlock(336, x + 4, ty); - core.drawAnimate('explosion1', x + 4, ty); - } - }, - x - ); - } - chase.onHeroLoc( - 'MT14', - async () => { - flags.finishChase1 = true; - Mota.Plugin.require('replay_g').clip('choices:0'); - core.showStatusBar(); - ani.time(750).apply('rect', 0); - chase.end(); - await sleep(750); - ani.ticker.destroy(); - core.deleteCanvas('chaseBack'); - }, - 21 - ); + } + }); + chase.onceLoc(21, 7, 'MT14', async () => { + flags.finishChase1 = true; + Mota.Plugin.require('replay_g').clip('choices:0'); + core.showStatusBar(); + ani.time(750).apply('rect', 0); + chase.end(true); + await sleep(750); + ani.ticker.destroy(); + core.deleteCanvas('chaseBack'); + }); } diff --git a/src/plugin/chase/data.ts b/src/plugin/chase/data.ts deleted file mode 100644 index 0a79ff5..0000000 --- a/src/plugin/chase/data.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathFn, TimingFn } from 'mutate-animate'; -import { Chase } from './chase'; -import { - camera1, - para1, - para2, - para3, - path1, - chaseShake, - wolfMove, - init1, - judgeFail1, - drawBack -} from './chase1'; - -export type ChaseCameraData = [ - floorId: FloorIds, // 楼层 - x: number, // 目标横坐标 - y: number, // 目标纵坐标 - start: number, // 开始时间 - time: number, // 持续时间 - mode: TimingFn, // 渐变函数 - path?: PathFn // 路径函数 -]; - -export type ChasePath = Partial>; - -interface ChaseData { - camera: ChaseCameraData[]; - fns: ((chase: Chase) => void)[]; - path: ChasePath; -} - -export function getChaseDataByIndex(index: number): ChaseData { - if (index === 1) { - init1(); - return { - camera: camera1, - fns: [ - para1, - para2, - para3, - chaseShake, - wolfMove, - drawBack, - judgeFail1 - ], - path: path1 - }; - } - throw new ReferenceError(`Deliver wrong chase index.`); -} diff --git a/src/plugin/chase/index.ts b/src/plugin/chase/index.ts new file mode 100644 index 0000000..2797c5f --- /dev/null +++ b/src/plugin/chase/index.ts @@ -0,0 +1,9 @@ +import { initChase as init1 } from './chase1'; + +const chaseIndexes: Record void> = { + 0: init1 +}; + +export function startChase(index: number) { + chaseIndexes[index](); +} diff --git a/src/plugin/game/fallback.ts b/src/plugin/game/fallback.ts index e8d4ab3..6867342 100644 --- a/src/plugin/game/fallback.ts +++ b/src/plugin/game/fallback.ts @@ -541,7 +541,7 @@ export function init() { const sx = core.getHeroLoc('x'); const sy = core.getHeroLoc('y'); - adapters.viewport?.all('mutateTo', ex, ey); + adapters.viewport?.all('mutateTo', ex, ey, time); const locked = core.status.lockControl; core.lockControl(); diff --git a/src/plugin/index.ts b/src/plugin/index.ts index 0c5c320..409caf8 100644 --- a/src/plugin/index.ts +++ b/src/plugin/index.ts @@ -1,5 +1,5 @@ import * as fly from './ui/fly'; -import * as chase from './chase/chase'; +import * as chase from './chase'; import * as completion from './completion'; import * as pop from './pop'; import * as frag from './fx/frag'; @@ -19,3 +19,4 @@ Mota.Plugin.register( animateController, animateController.default ); +Mota.Plugin.register('chase_r', chase);