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