将关卡BGM改为温暖无节拍氛围循环
This commit is contained in:
@@ -5,3 +5,6 @@ test('old arrows retain distance, rush to endpoint and fresh arrows move at base
|
||||
test('settings have exactly three independent preferences, and hint has its own cue',()=>{const ui=boot();ui.select(3);ui.button('设置');assert.deepEqual(Array.from(ui.api.buttons(),b=>b.label),['音乐:开','音效开','振动:开','完成']);ui.button('完成');ui.button('指路');assert.equal(ui.played.at(-1),'audio/hint.wav');ui.button('选关');assert.ok(ui.played.includes('music/select.wav'));ui.button('下一页');assert.equal(ui.played.at(-1),'audio/ui.wav');});
|
||||
test('actual fixed numeric node uses checkpoint pitch, final cell uses complete chord',()=>{const pack=JSON.parse(fs.readFileSync(new URL('./src/upstream/levels.json',import.meta.url)));const levels=pack.playOrder.map(id=>pack.levels.find(l=>l.id===id));const i=levels.findIndex(l=>l.cells.some(c=>c.clue>1&&c.clue<l.cells.length));const l=levels[i],ui=boot();ui.select(i);const route=solve(l)[0];for(const id of route){ui.advance(80);ui.cell(id);const e=ui.api.snapshot().feedback.events.at(-1);if(e.kind==='checkpoint')assert.equal(ui.played.at(-1),'audio/checkpoint-'+e.step+'.wav');}assert.equal(ui.played.at(-1),'audio/complete.wav');assert.ok(ui.api.snapshot().feedback.events.some(e=>e.kind==='checkpoint'));});
|
||||
test('two original music loops are quiet, nonempty and have a smooth loop seam',()=>{for(const name of ['select','play']){const b=fs.readFileSync(new URL('./music/'+name+'.wav',import.meta.url));assert.equal(b.readUInt32LE(24),22050);assert.ok(b.length>600000);assert.ok(Math.abs(b.readInt16LE(44)-b.readInt16LE(b.length-2))<100);}});
|
||||
|
||||
test('warm gameplay ambient is 32 seconds, softly leveled and free from percussive envelope jumps',()=>{const b=fs.readFileSync(new URL('./music/play.wav',import.meta.url)),n=(b.length-44)/2,frames=[];assert.equal(n/22050,32);let sum=0,peak=0;for(let i=0;i<n;i++){const v=b.readInt16LE(44+i*2)/32767;sum+=v*v;peak=Math.max(peak,Math.abs(v));}assert.ok(Math.sqrt(sum/n)>.03&&Math.sqrt(sum/n)<.04);assert.ok(peak<.17);for(let i=0;i<n;i+=2205){let energy=0,count=0;for(let j=i;j<Math.min(i+2205,n);j++){const v=b.readInt16LE(44+j*2)/32767;energy+=v*v;count++;}frames.push(Math.sqrt(energy/count));}assert.ok(frames.every((v,i)=>!i||Math.abs(v-frames[i-1])<.006));assert.ok(Math.abs(b.readInt16LE(44)-b.readInt16LE(b.length-2))<50);});
|
||||
test('gameplay ambient uses lower scene volume and keeps independent mute and resume behavior',()=>{const store=new Map(),api={getStorageSync:k=>store.get(k),setStorageSync:(k,v)=>store.set(k,v),createInnerAudioContext:()=>({stop(){},play(){this.plays=(this.plays||0)+1;},onError(){}})},m=new Music(api);m.scene('select');assert.equal(m.audio.volume,.16);m.scene('play');assert.equal(m.audio.volume,.14);assert.equal(m.audio.loop,true);const plays=m.audio.plays;m.scene('play');assert.equal(m.audio.plays,plays);m.suspend();m.resume();assert.equal(m.audio.src,'music/play.wav');assert.equal(m.audio.volume,.14);m.toggle();assert.equal(new Music(api).enabled,false);});
|
||||
|
||||
Reference in New Issue
Block a user