Update drop-and-fusion-engine.ts
This commit is contained in:
parent
14d4ffaa36
commit
17f368e228
1 changed files with 41 additions and 20 deletions
|
@ -45,12 +45,13 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
public readonly DROP_INTERVAL = 500;
|
public readonly DROP_INTERVAL = 500;
|
||||||
public readonly PLAYAREA_MARGIN = 25;
|
public readonly PLAYAREA_MARGIN = 25;
|
||||||
private STOCK_MAX = 4;
|
private STOCK_MAX = 4;
|
||||||
private METTER_ENGINE_UPDATE_DELTA = 1000 / 60; // 60fps
|
private TICK_DELTA = 1000 / 60; // 60fps
|
||||||
private loaded = false;
|
private loaded = false;
|
||||||
private frame = 0;
|
private frame = 0;
|
||||||
private engine: Matter.Engine;
|
private engine: Matter.Engine;
|
||||||
private render: Matter.Render;
|
private render: Matter.Render;
|
||||||
private matterEngineUpdateRaf: ReturnType<typeof requestAnimationFrame> | null = null;
|
private tickRaf: ReturnType<typeof requestAnimationFrame> | null = null;
|
||||||
|
private tickCallbackQueue: { frame: number; callback: () => void; }[] = [];
|
||||||
private overflowCollider: Matter.Body;
|
private overflowCollider: Matter.Body;
|
||||||
private isGameOver = false;
|
private isGameOver = false;
|
||||||
private gameWidth: number;
|
private gameWidth: number;
|
||||||
|
@ -237,9 +238,12 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
Matter.Composite.add(this.engine.world, body);
|
Matter.Composite.add(this.engine.world, body);
|
||||||
|
|
||||||
// 連鎖してfusionした場合の分かりやすさのため少し間を置いてからfusion対象になるようにする
|
// 連鎖してfusionした場合の分かりやすさのため少し間を置いてからfusion対象になるようにする
|
||||||
window.setTimeout(() => {
|
this.tickCallbackQueue.push({
|
||||||
this.activeBodyIds.push(body.id);
|
frame: this.frame + 100,
|
||||||
}, 100);
|
callback: () => {
|
||||||
|
this.activeBodyIds.push(body.id);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const comboBonus = 1 + ((this.combo - 1) / 5);
|
const comboBonus = 1 + ((this.combo - 1) / 5);
|
||||||
const additionalScore = Math.round(currentMono.score * comboBonus);
|
const additionalScore = Math.round(currentMono.score * comboBonus);
|
||||||
|
@ -271,8 +275,8 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
|
|
||||||
private gameOver() {
|
private gameOver() {
|
||||||
this.isGameOver = true;
|
this.isGameOver = true;
|
||||||
if (this.matterEngineUpdateRaf) window.cancelAnimationFrame(this.matterEngineUpdateRaf);
|
if (this.tickRaf) window.cancelAnimationFrame(this.tickRaf);
|
||||||
this.matterEngineUpdateRaf = null;
|
this.tickRaf = null;
|
||||||
this.emit('gameOver');
|
this.emit('gameOver');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,10 +346,13 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
this.fusion(bodyA, bodyB);
|
this.fusion(bodyA, bodyB);
|
||||||
} else {
|
} else {
|
||||||
fusionReservedPairs.push({ bodyA, bodyB });
|
fusionReservedPairs.push({ bodyA, bodyB });
|
||||||
window.setTimeout(() => {
|
this.tickCallbackQueue.push({
|
||||||
fusionReservedPairs = fusionReservedPairs.filter(x => x.bodyA.id !== bodyA.id && x.bodyB.id !== bodyB.id);
|
frame: this.frame + 100,
|
||||||
this.fusion(bodyA, bodyB);
|
callback: () => {
|
||||||
}, 100);
|
fusionReservedPairs = fusionReservedPairs.filter(x => x.bodyA.id !== bodyA.id && x.bodyB.id !== bodyB.id);
|
||||||
|
this.fusion(bodyA, bodyB);
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const energy = pairs.collision.depth;
|
const energy = pairs.collision.depth;
|
||||||
|
@ -371,11 +378,9 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
if (logs) {
|
if (logs) {
|
||||||
let playingFrame = 0;
|
|
||||||
|
|
||||||
const playTick = () => {
|
const playTick = () => {
|
||||||
playingFrame++;
|
this.frame++;
|
||||||
const log = logs.find(x => x.frame === playingFrame - 1);
|
const log = logs.find(x => x.frame === this.frame - 1);
|
||||||
if (log) {
|
if (log) {
|
||||||
switch (log.operation) {
|
switch (log.operation) {
|
||||||
case 'drop': {
|
case 'drop': {
|
||||||
|
@ -390,8 +395,16 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.tickCallbackQueue = this.tickCallbackQueue.filter(x => {
|
||||||
|
if (x.frame === this.frame) {
|
||||||
|
x.callback();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Matter.Engine.update(this.engine, this.METTER_ENGINE_UPDATE_DELTA);
|
Matter.Engine.update(this.engine, this.TICK_DELTA);
|
||||||
|
|
||||||
window.requestAnimationFrame(playTick);
|
window.requestAnimationFrame(playTick);
|
||||||
};
|
};
|
||||||
|
@ -408,8 +421,16 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
|
|
||||||
private tick() {
|
private tick() {
|
||||||
this.frame++;
|
this.frame++;
|
||||||
Matter.Engine.update(this.engine, this.METTER_ENGINE_UPDATE_DELTA);
|
this.tickCallbackQueue = this.tickCallbackQueue.filter(x => {
|
||||||
this.matterEngineUpdateRaf = window.requestAnimationFrame(this.tick);
|
if (x.frame === this.frame) {
|
||||||
|
x.callback();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Matter.Engine.update(this.engine, this.TICK_DELTA);
|
||||||
|
this.tickRaf = window.requestAnimationFrame(this.tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async load() {
|
public async load() {
|
||||||
|
@ -506,8 +527,8 @@ export class DropAndFusionGame extends EventEmitter<{
|
||||||
|
|
||||||
public dispose() {
|
public dispose() {
|
||||||
if (this.comboIntervalId) window.clearInterval(this.comboIntervalId);
|
if (this.comboIntervalId) window.clearInterval(this.comboIntervalId);
|
||||||
if (this.matterEngineUpdateRaf) window.cancelAnimationFrame(this.matterEngineUpdateRaf);
|
if (this.tickRaf) window.cancelAnimationFrame(this.tickRaf);
|
||||||
this.matterEngineUpdateRaf = null;
|
this.tickRaf = null;
|
||||||
Matter.Render.stop(this.render);
|
Matter.Render.stop(this.render);
|
||||||
Matter.World.clear(this.engine.world, false);
|
Matter.World.clear(this.engine.world, false);
|
||||||
Matter.Engine.clear(this.engine);
|
Matter.Engine.clear(this.engine);
|
||||||
|
|
Loading…
Reference in a new issue