feat: complete bark battle playable demo

This commit is contained in:
2026-05-12 14:42:58 +08:00
parent 22810245f5
commit 33c9079d3b
16 changed files with 639 additions and 196 deletions

View File

@@ -1,4 +1,4 @@
import { type BarkBattleSession,createBarkBattleSession } from '../domain/BarkBattleSession';
import { type BarkBattleSession, createBarkBattleSession } from '../domain/BarkBattleSession';
import type { MicrophoneFailureReason } from '../domain/BarkBattleTypes';
import { BarkDetector } from '../domain/BarkDetector';
import type { BarkBattleConfig } from './BarkBattleConfig';
@@ -17,6 +17,10 @@ export class BarkBattleController {
return this.session.snapshot;
}
getSampleClockMs() {
return this.sampleClockMs;
}
updateConfig(config: BarkBattleConfig) {
this.config = config;
this.restart();
@@ -38,13 +42,32 @@ export class BarkBattleController {
this.sampleClockMs = 0;
}
submitMockSample(volume: number) {
const events = this.detector.acceptSample({ atMs: this.sampleClockMs, volume });
forcePlayerBark(volume = 0.9) {
if (this.session.snapshot.phase !== 'playing') {
this.session = this.session.startMockRound();
}
if (this.session.snapshot.phase === 'countdown') {
this.session = this.session.tick(this.session.snapshot.countdownMs);
}
this.session = this.session.applyPlayerBark({
side: 'player',
atMs: this.sampleClockMs,
peakVolume: volume,
durationMs: this.config.minBarkDurationMs,
});
}
submitInputSample(volume: number, atMs = this.sampleClockMs) {
const events = this.detector.acceptSample({ atMs, volume });
for (const event of events) {
this.session = this.session.applyPlayerBark(event);
}
}
submitMockSample(volume: number) {
this.submitInputSample(volume);
}
tick(deltaMs: number) {
this.sampleClockMs += deltaMs;
this.session = this.session.tick(deltaMs);
@@ -64,8 +87,6 @@ export class BarkBattleController {
return new BarkDetector({
threshold: this.config.barkThreshold,
minBarkGapMs: this.config.minBarkGapMs,
minBarkDurationMs: this.config.minBarkDurationMs,
maxBarkDurationMs: this.config.maxBarkDurationMs,
});
}
}

View File

@@ -54,4 +54,22 @@ describe('BarkBattleController', () => {
expect(controller.getSnapshot().energy).toBe(0);
expect(controller.getSnapshot().result).toBeNull();
});
it('真实输入采样可使用高精度采样时间戳连续触发 100ms 级别叫声', () => {
const controller = new BarkBattleController({
...DEFAULT_BARK_BATTLE_CONFIG,
countdownMs: 0,
barkThreshold: 0.5,
minBarkDurationMs: 40,
minBarkGapMs: 100,
});
controller.startWithMockInput();
controller.submitInputSample(0.82, 0);
controller.submitInputSample(0.1, 60);
controller.submitInputSample(0.9, 120);
controller.submitInputSample(0.1, 180);
expect(controller.getSnapshot().player.barkCount).toBe(2);
});
});