fix: 追逐战的bug

This commit is contained in:
unanmed 2024-10-06 16:04:17 +08:00
parent ca4a9dd512
commit 787fc7e837
7 changed files with 66 additions and 31 deletions

View File

@ -89,7 +89,7 @@ export class Camera extends EventEmitter<CameraEvent> {
trans.reset();
for (const o of this.operation) {
if (o.type === 'translate') {
trans.translate(o.x, o.y);
trans.translate(-o.x, -o.y);
} else if (o.type === 'rotate') {
trans.rotate(o.angle);
} else {
@ -436,12 +436,13 @@ export class CameraAnimation extends EventEmitter<CameraAnimationEvent> {
const data = exe.data;
if (data.length === 0) return;
const item = data[0];
if (item.time < time) {
if (item.start < time) {
this.executeAnimate(exe, item);
data.shift();
this.emit('animate', ope, exe, item);
}
});
this.camera.requestUpdate();
};
private executeAnimate(
@ -507,8 +508,8 @@ export class CameraAnimation extends EventEmitter<CameraAnimationEvent> {
const data: TranslateAnimation = {
type: 'translate',
timing,
x,
y,
x: x * 32,
y: y * 32,
time,
start
};
@ -592,6 +593,7 @@ export class CameraAnimation extends EventEmitter<CameraAnimationEvent> {
}
});
this.endTime = endTime + this.startTime;
this.tick();
}
destroy() {

View File

@ -3,7 +3,7 @@ import { HeroRenderer } from './hero';
import { ILayerGroupRenderExtends, LayerGroup } from './layer';
import { Transform } from '../transform';
import { LayerGroupFloorBinder } from './floor';
import { hyper, TimingFn } from 'mutate-animate';
import { hyper, inverseTrigo, power, TimingFn, trigo } from 'mutate-animate';
import { RenderAdapter } from '../adapter';
export class FloorViewport implements ILayerGroupRenderExtends {
@ -11,14 +11,13 @@ export class FloorViewport implements ILayerGroupRenderExtends {
group!: LayerGroup;
hero!: HeroRenderer;
transform!: Transform;
binder!: LayerGroupFloorBinder;
/** 是否启用视角控制拓展 */
enabled: boolean = true;
/** 渐变的速率曲线 */
transitionFn: TimingFn = hyper('sin', 'out');
transitionFn: TimingFn = hyper('sec', 'out');
/** 加减速的速率曲线 */
movingEaseFn: TimingFn = t => t ** 2;
@ -103,9 +102,13 @@ export class FloorViewport implements ILayerGroupRenderExtends {
enable() {
this.enabled = true;
const { x, y } = core.status.hero.loc;
const { x: nx, y: ny } = this.transform;
this.nx = nx;
this.ny = ny;
const { x: nx, y: ny } = this.group.camera;
const halfWidth = core._PX_ / 2;
const halfHeight = core._PY_ / 2;
const cell = this.group.cellSize;
const half = cell / 2;
this.nx = -(nx - halfWidth + half) / this.group.cellSize;
this.ny = -(ny - halfHeight + half) / this.group.cellSize;
this.mutateTo(x, y);
}
@ -348,7 +351,6 @@ export class FloorViewport implements ILayerGroupRenderExtends {
awake(group: LayerGroup): void {
this.group = group;
this.transform = group.transform;
const ex1 = group.getLayer('event')?.getExtends('floor-hero');
const ex2 = group.getExtends('floor-binder');
if (

View File

@ -11,7 +11,7 @@ export function disableViewport() {
export function enableViewport() {
const adapter = RenderAdapter.get<FloorViewport>('viewport');
if (!adapter) return;
adapter.sync('disable');
adapter.sync('enable');
}
/**

View File

@ -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, this.moveSpeed * 2);
viewport.all('moveTo', x, y, this.moveSpeed * 1.6);
adapter.sync('setAnimateDir', showDir);
await adapter.all('move', moveDir);
}

View File

@ -46,11 +46,11 @@ export class Chase extends EventEmitter<ChaseEvent> {
private nowFloor?: FloorIds;
/** 开始时刻 */
private startTime: number = 0;
startTime: number = 0;
/** 进入当前楼层的时刻 */
private nowFloorTime: number = 0;
nowFloorTime: number = 0;
/** 是否正在进行追逐战 */
private started: boolean = false;
started: boolean = false;
/** 路径显示的sprite */
private pathSprite?: Sprite;
@ -159,22 +159,33 @@ export class Chase extends EventEmitter<ChaseEvent> {
const canvas = new MotaOffscreenCanvas2D();
const ctx = canvas.ctx;
const cell = 32;
const half = cell / 2;
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);
ctx.moveTo(fx * cell + half, fy * cell + half);
nodes.forEach(([x, y]) => {
ctx.lineTo(x, y);
ctx.lineTo(x * cell + half, y * cell + half);
});
ctx.strokeStyle = '#0ff';
ctx.globalAlpha = 0.6;
ctx.stroke();
this.pathMap.set(floor, canvas);
}
this.pathSprite = new Sprite('absolute', false, true);
this.pathSprite = new Sprite('static', false, true);
this.pathSprite.size(480, 480);
this.pathSprite.pos(0, 0);
this.pathSprite.setZIndex(120);
this.pathSprite.setAntiAliasing(false);
this.layer.appendChild(this.pathSprite);
this.pathSprite.setRenderFn(canvas => {
const ctx = canvas.ctx;
const path = this.pathMap.get(core.status.floorId);
if (!path) return;
ctx.drawImage(path.canvas, 0, 0, path.width, path.height);
});
}
/**

View File

@ -110,6 +110,7 @@ export function initChase() {
const camera = Camera.for(layer);
camera.clearOperation();
camera.transform = layer.camera;
const animation16 = new CameraAnimation(camera);
const animation15 = new CameraAnimation(camera);
const animation14 = new CameraAnimation(camera);
@ -128,9 +129,13 @@ export function initChase() {
const translate = camera.addTranslate();
const rotate = camera.addRotate();
translate.x = 10;
translate.y = 10;
// MT16 摄像机动画
animation16.translate(translate, 10, 10, 1, 0, linear());
animation16.translate(translate, 0, 10, 1600, 0, hyper('sin', 'in'));
// MT15 摄像机动画
animation15.translate(translate, 49, 0, 1, 0, linear());
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'));
@ -140,6 +145,7 @@ export function initChase() {
animation15.translate(translate, 12, 0, 996, 12450, linear());
animation15.translate(translate, 0, 0, 1470, 13446, hyper('sin', 'out'));
// MT14 摄像机动画
animation14.translate(translate, 113, 0, 1, 0, hyper('sin', 'in'));
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'));
@ -151,7 +157,15 @@ export function initChase() {
animation14.translate(translate, 36, 0, 3320, 21580, linear());
animation14.translate(translate, 0, 0, 9960, 24900, linear());
judgeFail1(chase, ani);
chase.on('end', () => {
animation16.destroy();
animation15.destroy();
animation14.destroy();
camera.destroy();
back?.destroy();
});
judgeFail1(chase, ani, camera);
drawBack(chase, ani);
para1(chase);
para2(chase);
@ -176,11 +190,16 @@ async function wolfMove(chase: Chase) {
core.setBlock(508, 23, 23);
}
function judgeFail1(chase: Chase, ani: Animation) {
function judgeFail1(chase: Chase, ani: Animation, camera: Camera) {
chase.on('frame', () => {
if (core.status.hero.loc.x > core.bigmap.offsetX / 32 + 17) {
const now = Date.now();
const time = now - chase.nowFloorTime;
if (time < 500) return;
if (core.status.hero.loc.x > -camera.transform.x / 32 + 22) {
chase.end(false);
if (ani.value.rect !== void 0) {
ani.time(750).apply('rect', 0);
}
core.lose('逃跑失败');
}
});
@ -194,6 +213,7 @@ function drawBack(chase: Chase, ani: Animation) {
const render = MotaRenderer.get('render-main')!;
const layer = render.getElementById('layer-main')! as LayerGroup;
back = new Sprite('absolute', false);
back.setZIndex(100);
back.size(480, 480);
back.pos(0, 0);
back.append(layer);
@ -264,7 +284,6 @@ function para2(chase: Chase) {
});
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);
@ -272,7 +291,6 @@ function para2(chase: Chase) {
}
});
chase.onceLoc(31, 5, 'MT15', () => {
core.vibrate('vertical', 10000, 25, 1);
core.removeBlock(34, 8);
core.removeBlock(33, 8);
core.drawAnimate('explosion1', 34, 8);
@ -438,7 +456,6 @@ function para3(chase: Chase, ani: Animation) {
}
}
core.drawAnimate('explosion2', 79, 7);
core.vibrate('vertical', 4000, 25, 15);
});
chase.onceLoc(68, 5, 'MT14', () => {
core.setBlock(336, 68, 4);

View File

@ -604,8 +604,8 @@ export function init() {
.absolute()
.time(1)
.mode(Animation.linear())
.move(-core.bigmap.offsetX, -core.bigmap.offsetY);
animate.time(animateTime).move(-x * 32, -y * 32);
.move(core.bigmap.offsetX, core.bigmap.offsetY);
animate.time(animateTime).move(x * 32, y * 32);
camera.applyTranslateAnimation(
translate,
@ -614,16 +614,19 @@ export function init() {
);
camera.transform = layer.camera;
const timeout = window.setTimeout(() => {
const end = () => {
core.bigmap.offsetX = x * 32;
core.bigmap.offsetY = y * 32;
camera.destroy();
callback?.();
}, animateTime + 50);
};
const timeout = window.setTimeout(end, animateTime + 50);
const id = fallbackIds++;
core.animateFrame.lastAsyncId = id;
core.animateFrame.asyncId[id] = () => {
callback?.();
end();
clearTimeout(timeout);
};
};