保存强化版提升前的主版本工作区

This commit is contained in:
toshiocn
2026-10-23 11:02:33 +08:00
parent 66b3ca4ea0
commit 83e2e40269
26 changed files with 452 additions and 142 deletions
@@ -0,0 +1,32 @@
<!doctype html><meta charset="utf-8"><title>提示动画对比检查</title>
<style>body{font:16px sans-serif;line-height:1.6;padding:24px;background:#fff6df;color:#43382f}pre{white-space:pre-wrap}</style>
<h1>提示动画对比检查</h1><p id="result">检查中…</p><pre id="details"></pre>
<script type="module">
const lessonMode=new URL(location.href).searchParams.get('mode')==='lesson';document.querySelector('h1').textContent=lessonMode?'新机制教学动画对比检查':'提示动画对比检查';
const source=await(await fetch('../game.js')).text(),baseline=await(await fetch('baseline-game.js')).text();
function boot(bundle){
const handlers={},frames=new Map();let id=0,now=100000;
class Clock extends Date{static now(){return now;}}
const wx={createCanvas:()=>document.createElement('canvas'),loadFont:()=>'',getWindowInfo:()=>({windowWidth:375,windowHeight:812,pixelRatio:2,safeArea:{top:44,bottom:778}}),getMenuButtonBoundingClientRect:()=>({bottom:80}),getPerformance:()=>({now:()=>now}),getStorageSync:()=>'',setStorageSync(){},removeStorageSync(){},setInnerAudioOption(){},createInnerAudioContext:()=>({stop(){},onError(){},play(){}}),showModal(){},env:{USER_DATA_PATH:'/qa'}};
for(const n of ['TouchStart','TouchMove','TouchEnd','TouchCancel','Hide','Show','WindowResize'])wx['on'+n]=f=>handlers[n]=f;
const global={};new Function('wx','GameGlobal','requestAnimationFrame','cancelAnimationFrame','setTimeout','clearTimeout','Date',bundle)(wx,global,fn=>{frames.set(++id,fn);return id;},i=>frames.delete(i),()=>1,()=>{},Clock);
const api=global.numberSwipeR2;
const tick=(ms=16)=>{now+=ms;const entry=frames.entries().next().value;if(entry){frames.delete(entry[0]);entry[1]();}};
const button=name=>{const b=api.buttons().find(b=>b.label===name&&b.enabled);if(!b)throw Error(name);const p={identifier:1,clientX:b.x+b.w/2,clientY:b.y+b.h/2},e={changedTouches:[p],touches:[p]};handlers.TouchStart(e);handlers.TouchEnd(e);tick();};
tick();if(api.buttons().some(b=>b.label==='返回游戏'))button('返回游戏');if(api.snapshot().screen!=='select')button('选关');if(lessonMode){button('5');tick(200);}else{button('4');button('指路');tick(2000);}
for(let i=0;i<12;i++)tick();
return {tick,api};
}
const result={device:'browser Canvas, 375×812, DPR 2',framesPerTrial:120,trials:3,baselineMs:[],optimizedMs:[],staticReuseFrames:0};
try{
for(let trial=0;trial<3;trial++){
for(const [kind,bundle] of [['baselineMs',baseline],['optimizedMs',source]]){
const ui=boot(bundle),before=lessonMode?(ui.api.snapshot().lessonBoardRenders||0):(ui.api.snapshot().hintBaseHits||0),start=performance.now();for(let i=0;i<120;i++)ui.tick();result[kind].push((performance.now()-start)/120);if(kind==='optimizedMs')result.staticReuseFrames+=lessonMode?120-(ui.api.snapshot().lessonBoardRenders-before):ui.api.snapshot().hintBaseHits-before;
document.querySelector('#details').textContent=JSON.stringify(result,null,2);await new Promise(requestAnimationFrame);
}
}
const mean=a=>a.reduce((n,x)=>n+x,0)/a.length;result.baselineMeanMs=mean(result.baselineMs);result.optimizedMeanMs=mean(result.optimizedMs);result.reduction=1-result.optimizedMeanMs/result.baselineMeanMs;
document.querySelector('#result').textContent=`完成:${lessonMode?'教学':'指路'}帧平均绘制耗时 ${result.baselineMeanMs.toFixed(2)} → ${result.optimizedMeanMs.toFixed(2)} ms/frame;${lessonMode?'示范棋盘':'静态界面'}复用 ${result.staticReuseFrames}/360 帧。浏览器对比不代表微信真机帧率。`;
document.querySelector('#details').textContent=JSON.stringify(result,null,2);
}catch(e){document.querySelector('#result').textContent='FAIL:'+e.message;}
</script>