mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-31 23:29:27 +08:00
feat: 帧动画 & fix: 勇士移动
This commit is contained in:
parent
fdc08406b9
commit
5e54cc9424
@ -25,6 +25,9 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
|
||||
|
||||
scale: number = 1;
|
||||
|
||||
/** 更新标识符,如果发生变化则说明画布被动清空 */
|
||||
symbol: number = 0;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@ -248,6 +251,7 @@ window.addEventListener('resize', () => {
|
||||
MotaOffscreenCanvas2D.list.forEach(v => {
|
||||
if (v.autoScale) {
|
||||
v.size(v.width, v.height);
|
||||
v.symbol++;
|
||||
v.emit('resize');
|
||||
}
|
||||
});
|
||||
|
@ -62,7 +62,6 @@ import { Danmaku } from './main/custom/danmaku';
|
||||
import * as Shadow from './fx/shadow';
|
||||
import { MotaCanvas2D } from './fx/canvas2d';
|
||||
import * as portal from './fx/portal';
|
||||
import { heroRender } from './render/hero';
|
||||
import { MotaRenderer } from './render/render';
|
||||
import { Container } from './render/container';
|
||||
import { Sprite } from './render/sprite';
|
||||
@ -148,7 +147,6 @@ Mota.register('module', 'Effect', {
|
||||
Portal: portal
|
||||
});
|
||||
Mota.register('module', 'Render', {
|
||||
heroRender,
|
||||
texture,
|
||||
MotaRenderer,
|
||||
Container,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { isNil } from 'lodash-es';
|
||||
import { EventEmitter } from '../common/eventEmitter';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { MotaOffscreenCanvas2D } from '../fx/canvas2d';
|
||||
import { Camera } from './camera';
|
||||
import { Ticker, TickerFn } from 'mutate-animate';
|
||||
@ -379,11 +379,43 @@ RenderItem.ticker.add(() => {
|
||||
}
|
||||
});
|
||||
|
||||
interface RenderEvent {
|
||||
animateFrame: (frame: number, time: number) => void;
|
||||
export interface IAnimateFrame {
|
||||
updateFrameAnimate(frame: number, time: number): void;
|
||||
}
|
||||
|
||||
export const renderEmits = new EventEmitter<RenderEvent>();
|
||||
interface RenderEvent {
|
||||
animateFrame: [frame: number, time: number];
|
||||
}
|
||||
|
||||
class RenderEmits extends EventEmitter<RenderEvent> {
|
||||
private framer: Set<IAnimateFrame> = new Set();
|
||||
|
||||
/**
|
||||
* 添加一个可更新帧动画的对象
|
||||
*/
|
||||
addFramer(framer: IAnimateFrame) {
|
||||
this.framer.add(framer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除一个可更新帧动画的对象
|
||||
*/
|
||||
removeFramer(framer: IAnimateFrame) {
|
||||
this.framer.delete(framer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有帧动画
|
||||
* @param frame 帧数
|
||||
* @param time 帧动画时刻
|
||||
*/
|
||||
emitAnimateFrame(frame: number, time: number) {
|
||||
this.framer.forEach(v => v.updateFrameAnimate(frame, time));
|
||||
this.emit('animateFrame', frame, time);
|
||||
}
|
||||
}
|
||||
|
||||
export const renderEmits = new RenderEmits();
|
||||
|
||||
Mota.require('var', 'hook').once('reset', () => {
|
||||
let lastTime = 0;
|
||||
@ -392,7 +424,7 @@ Mota.require('var', 'hook').once('reset', () => {
|
||||
if (time - lastTime > core.values.animateSpeed) {
|
||||
RenderItem.animatedFrame++;
|
||||
lastTime = time;
|
||||
renderEmits.emit('animateFrame', RenderItem.animatedFrame, time);
|
||||
renderEmits.emitAnimateFrame(RenderItem.animatedFrame, time);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -104,11 +104,16 @@ interface DamageRenderable {
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
interface DamageCache {
|
||||
canvas: MotaOffscreenCanvas2D;
|
||||
symbol: number;
|
||||
}
|
||||
|
||||
export class Damage extends Sprite {
|
||||
mapWidth: number = 0;
|
||||
mapHeight: number = 0;
|
||||
|
||||
block: BlockCacher<HTMLCanvasElement>;
|
||||
block: BlockCacher<DamageCache>;
|
||||
/** 键表示分块索引,值表示在这个分块上的渲染信息(当然实际渲染位置可以不在这个分块上) */
|
||||
renderable: Map<number, Set<DamageRenderable>> = new Map();
|
||||
|
||||
@ -404,13 +409,14 @@ export class Damage extends Sprite {
|
||||
// todo: 是否真的需要缓存
|
||||
// 检查有没有缓存
|
||||
const cache = block.cache.get(v * block.cacheDepth);
|
||||
if (cache) {
|
||||
ctx.drawImage(cache, px, py, size, size);
|
||||
if (cache && cache.symbol === cache.canvas.symbol) {
|
||||
ctx.drawImage(cache.canvas.canvas, px, py, size, size);
|
||||
return;
|
||||
}
|
||||
|
||||
// 否则依次渲染并写入缓存
|
||||
const temp = new MotaOffscreenCanvas2D();
|
||||
const temp = cache?.canvas ?? new MotaOffscreenCanvas2D();
|
||||
temp.clear();
|
||||
temp.setHD(true);
|
||||
temp.setAntiAliasing(true);
|
||||
temp.withGameScale(true);
|
||||
@ -431,7 +437,10 @@ export class Damage extends Sprite {
|
||||
});
|
||||
|
||||
ctx.drawImage(temp.canvas, px, py, size, size);
|
||||
block.cache.set(v, temp.canvas);
|
||||
block.cache.set(v, {
|
||||
canvas: temp,
|
||||
symbol: temp.symbol
|
||||
});
|
||||
});
|
||||
ctx.restore();
|
||||
// console.timeEnd('damage');
|
||||
|
@ -140,6 +140,7 @@ export class HeroRenderer
|
||||
}
|
||||
|
||||
const progress = (time - this.lastStepTime) / this.speed;
|
||||
|
||||
const { x: dx, y: dy } = this.stepDelta;
|
||||
const { x, y } = core.status.hero.loc;
|
||||
if (progress >= 1) {
|
||||
@ -184,8 +185,10 @@ export class HeroRenderer
|
||||
else {
|
||||
this.step();
|
||||
return (this.moveDetached = new Promise<void>(resolve => {
|
||||
this.once('stepEnd', () => {
|
||||
this.moveDetached = void 0;
|
||||
this.once('stepEnd', resolve);
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,12 @@ import { Container } from '../container';
|
||||
import { Sprite } from '../sprite';
|
||||
import { Camera } from '../camera';
|
||||
import { TimingFn } from 'mutate-animate';
|
||||
import { RenderItem, renderEmits, transformCanvas } from '../item';
|
||||
import {
|
||||
IAnimateFrame,
|
||||
renderEmits,
|
||||
RenderItem,
|
||||
transformCanvas
|
||||
} from '../item';
|
||||
import { logger } from '@/core/common/logger';
|
||||
import { AutotileRenderable, RenderableData, texture } from '../cache';
|
||||
import { glMatrix } from 'gl-matrix';
|
||||
@ -83,7 +88,7 @@ export interface ILayerGroupRenderExtends {
|
||||
|
||||
export type FloorLayer = 'bg' | 'bg2' | 'event' | 'fg' | 'fg2';
|
||||
|
||||
export class LayerGroup extends Container {
|
||||
export class LayerGroup extends Container implements IAnimateFrame {
|
||||
/** 地图组列表 */
|
||||
// static list: Set<LayerGroup> = new Set();
|
||||
|
||||
@ -113,9 +118,7 @@ export class LayerGroup extends Container {
|
||||
this.releaseNeedRender();
|
||||
});
|
||||
|
||||
// this.usePreset('defaults');
|
||||
// LayerGroup.list.add(this);
|
||||
// this.bindFloor(floor);
|
||||
renderEmits.addFramer(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,7 +160,6 @@ export class LayerGroup extends Container {
|
||||
this.layers.forEach(v => {
|
||||
v.block.setBlockSize(size);
|
||||
});
|
||||
// this.damage?.block.setBlockSize(size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,11 +175,8 @@ export class LayerGroup extends Container {
|
||||
*/
|
||||
emptyLayer() {
|
||||
this.removeChild(...this.layers.values());
|
||||
// if (this.damage) this.removeChild(this.damage);
|
||||
// this.damage?.destroy();
|
||||
this.layers.forEach(v => v.destroy());
|
||||
this.layers.clear();
|
||||
// this.damage = void 0;
|
||||
|
||||
for (const ex of this.extend.values()) {
|
||||
ex.onEmptyLayer?.(this);
|
||||
@ -190,7 +189,6 @@ export class LayerGroup extends Container {
|
||||
*/
|
||||
addLayer(layer: FloorLayer) {
|
||||
const l = new Layer();
|
||||
// l.bindLayer(layer);
|
||||
l.layer = layer;
|
||||
if (l.layer) this.layers.set(l.layer, l);
|
||||
this.appendChild(l);
|
||||
@ -293,7 +291,6 @@ export class LayerGroup extends Container {
|
||||
this.layers.forEach(v => {
|
||||
v.cache(v.using);
|
||||
});
|
||||
// this.damage?.cache(this.damage.using);
|
||||
this.update(this);
|
||||
|
||||
for (const ex of this.extend.values()) {
|
||||
@ -306,19 +303,10 @@ export class LayerGroup extends Container {
|
||||
ex.onDestroy?.(this);
|
||||
}
|
||||
super.destroy();
|
||||
// LayerGroup.list.delete(this);
|
||||
renderEmits.removeFramer(this);
|
||||
}
|
||||
}
|
||||
|
||||
const hook = Mota.require('var', 'hook');
|
||||
|
||||
// todo: animate frame.
|
||||
// renderEmits.on('animateFrame', () => {
|
||||
// LayerGroup.list.forEach(v => {
|
||||
// v.updateFrameAnimate();
|
||||
// });
|
||||
// });
|
||||
|
||||
export function calNeedRenderOf(
|
||||
camera: Camera,
|
||||
cell: number,
|
||||
@ -601,8 +589,8 @@ export interface ILayerRenderExtends {
|
||||
}
|
||||
|
||||
interface LayerCacheItem {
|
||||
// todo: 删掉这个属性
|
||||
canvas: HTMLCanvasElement;
|
||||
symbol: number;
|
||||
canvas: MotaOffscreenCanvas2D;
|
||||
}
|
||||
|
||||
export interface LayerMovingRenderable extends RenderableData {
|
||||
@ -1227,7 +1215,7 @@ export class Layer extends Container {
|
||||
const cache = this.block.cache.get(index);
|
||||
if (cache) {
|
||||
ctx.drawImage(
|
||||
cache.canvas,
|
||||
cache.canvas.canvas,
|
||||
sx * cell,
|
||||
sy * cell,
|
||||
blockSize * cell,
|
||||
@ -1276,7 +1264,8 @@ export class Layer extends Container {
|
||||
blockSize * cell
|
||||
);
|
||||
this.block.cache.set(index, {
|
||||
canvas: temp.canvas
|
||||
canvas: temp,
|
||||
symbol: temp.symbol
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -163,9 +163,16 @@ Mota.require('var', 'hook').once('reset', () => {
|
||||
layer.requestAfterFrame(() => {
|
||||
hero.setImage(core.material.images.images['hero2.png']);
|
||||
});
|
||||
layer.delegateTicker(() => {
|
||||
hero.turn();
|
||||
}, 10000);
|
||||
hero.readyMove();
|
||||
layer.delegateTicker(
|
||||
() => {
|
||||
hero.move('right');
|
||||
},
|
||||
10000,
|
||||
() => {
|
||||
hero.endMove();
|
||||
}
|
||||
);
|
||||
|
||||
camera.move(240, 240);
|
||||
render.update();
|
||||
|
Loading…
Reference in New Issue
Block a user