From 45017fbd3f0f85e203de189d7ae68e4aba37c9f7 Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Wed, 5 Aug 2026 20:45:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=9F=E7=A7=8D/=E9=AD=94=E7=A2=9F=E5=8F=98?= =?UTF-8?q?=E5=BD=A2=E9=87=8D=E5=86=99=EF=BC=9A=E5=90=8C=E4=B8=80=E5=87=A0?= =?UTF-8?q?=E4=BD=95=E4=BD=93=E8=BF=9E=E7=BB=AD=E6=BC=94=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E6=9D=9C=E7=BB=9D=E9=83=A8=E4=BB=B6=E5=87=AD=E7=A9=BA=E5=87=BA?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 太空原种:蛹体保持同一多边形,翅膀折叠藏于身后逐渐展开,裂纹逐条生长,眼青->红、侧囊青->绿渐变(删除drawPupa/drawManta双套形体切换) - 暗黑魔碟:圆环=左右两个半环,变形为两半环裂口扩张各自收缩成犄角;眼窝常存赤瞳点亮;三阶段爆甲=壳板带轨迹旋飞飞离+铆钉连续伸长成刺+炮台基座伸出炮管 --- js/render.js | 116 ++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/js/render.js b/js/render.js index de76ae0..2328f4f 100644 --- a/js/render.js +++ b/js/render.js @@ -56,9 +56,8 @@ function drawBoss(){ for(let i=-2;i<=2;i++)px(i*8-1,12,2,3,t%40<20?"#ff5566":"#7a1622"); px(-22,-10,44,2,"#8c9ab8"); if(ph2>=1){px(-2,-27,4,8,"#5b6b8c");px(-1,-29,2,3,t%20<10?"#ff5566":"#7a1622");} // 二阶段顶部炮塔 - }else if(b.idx===1){ // 太空原种:虫蛹↔蝠鲼(变身:裂皮→变粉→红眼→展翅) - if(mp!==null){if(mp<0.5)drawPupa(t,fl,mp*2);else drawManta(t,fl,(mp-0.5)*2);} - else if(ph2===0)drawPupa(t,fl,0);else drawManta(t,fl,1); + }else if(b.idx===1){ // 太空原种:同一躯体连续变形——裂皮→粉化→红眼→身后展翅(无部件凭空出现) + drawProgenitor(t,fl,mp!==null?mp:(ph2===0?0:1)); }else if(b.idx===2){ // 歼灭者 for(let i=0;i<6;i++){const a=i/6*TAU+t*0.01; px(Math.cos(a)*19-3,Math.sin(a)*19-3,6,6,"#5b3a8c");} @@ -110,36 +109,44 @@ function drawBoss(){ circ(0,-14,8,fl||"#43b8ff");circ(0,-14,4,"#bfefff"); px(-2,-36,4,18,"#43b8ff");px(-2,0,4,34,"#43b8ff"); ctx.restore();ctx.globalAlpha=1;} - }else{ // 暗黑魔碟:核心+圆环;二阶段圆环前段裂成犄角+赤瞳激光;三阶段爆甲出刺+炮台 + }else{ // 暗黑魔碟:核心+圆环;变形=圆环前后裂开、两半各自收缩成犄角(同一几何体连续演化);爆甲=壳板飞离、铆钉伸长成刺 + let open,fo,eyeG; + if(b.phase===0){open=0;fo=0;eyeG=0;} + else if(b.phase===1){open=mp!==null?mp:1;fo=0;eyeG=mp!==null?mp:1;} + else{open=1;fo=mp!==null?mp:1;eyeG=1;} + const R=30+open*3; // 外径微扩 circ(0,0,20,"#1a1030");circ(0,0,15,"#12081c"); - if(ph2===0&&mp===null){ // 一阶段:完整圆环绕核心缓转 + px(-11,-5,7,6,"#241430");px(4,-5,7,6,"#241430"); // 眼窝常存 + if(eyeG>0){ctx.globalAlpha=eyeG; // 赤瞳点亮(非凭空出现) + px(-10,-4,5,4,fl||"#ff3355");px(5,-4,5,4,fl||"#ff3355"); + px(-9,-3,2,1,"#ffdfe5");px(6,-3,2,1,"#ffdfe5"); + ctx.globalAlpha=1;} + const sB=Math.PI/2-open*0.55,sT=Math.PI/2-open*0.35; // 半环跨幅:前端裂口扩得更快 + for(const sd of[-1,1]){ + const a0=sd<0?Math.PI-sB:-sT,a1=sd<0?Math.PI+sT:sB; // 左半环[π-sB,π+sT] 右半环[-sT,sB] ctx.strokeStyle="#55336e";ctx.lineWidth=13; - ctx.beginPath();ctx.arc(0,0,30,0,TAU);ctx.stroke(); + ctx.beginPath();ctx.arc(0,0,R,a0,a1);ctx.stroke(); ctx.strokeStyle="#6e4490";ctx.lineWidth=5; - ctx.beginPath();ctx.arc(0,0,30,0,TAU);ctx.stroke(); - for(let i=0;i<4;i++){const a=i*Math.PI/2+t*0.012; - px(Math.cos(a)*30-2,Math.sin(a)*30-2,4,4,"#c86bff");} - px(-6,-4,12,8,"#2a1a3a"); - }else{ - if(mp!==null&&b.phase===1){ // 变形中:圆环残留快速淡出 - const ra=1-clamp(mp/0.35,0,1); - if(ra>0){ctx.globalAlpha=ra;ctx.strokeStyle="#55336e";ctx.lineWidth=13; - ctx.beginPath();ctx.arc(0,0,30,0,TAU);ctx.stroke();ctx.globalAlpha=1;}} - const ha=mp!==null?clamp((mp-0.25)/0.6,0,1):1; // 犄角展开度 - if(ha>0){ctx.globalAlpha=ha; - for(const sd of[-1,1]){ctx.save();ctx.rotate((1-ha)*sd*1.1); - poly([sd*10,4,sd*30,-26,sd*46,-32,sd*40,-6,sd*20,12],"#55336e"); - poly([sd*16,2,sd*32,-20,sd*40,-24,sd*34,-4,sd*20,8],"#6e4490"); - if(ph2>=2){ // 三阶段爆甲:犄角外壳小刺+红色炮台 - for(let k=0;k<3;k++)poly([sd*(25+k*7),-13-k*6,sd*(29+k*7),-22-k*6,sd*(33+k*7),-12-k*6],"#2a1a3a"); - px(sd*41-3,-36,7,6,fl||"#ff3355");} - ctx.restore();} - ctx.globalAlpha=1;} - const eyeA=mp!==null?clamp((mp-0.45)/0.5,0,1):1; // 核心赤瞳 - if(eyeA>0){ctx.globalAlpha=eyeA; - px(-11,-5,7,6,fl||"#ff3355");px(4,-5,7,6,fl||"#ff3355"); - px(-9,-3,3,2,"#ffdfe5");px(6,-3,3,2,"#ffdfe5"); - ctx.globalAlpha=1;} + ctx.beginPath();ctx.arc(0,0,R,a0,a1);ctx.stroke(); + for(const ea of[a0,a1]){ctx.save(); // 裂口断茬(随弧端移动) + ctx.translate(Math.cos(ea)*R,Math.sin(ea)*R);ctx.rotate(ea+Math.PI/2); + px(-6,-8,12,4,"#2a1a3a");px(-3,-11,6,3,"#2a1a3a");ctx.restore();} + for(let k=0;k<3;k++){const aa=a0+(0.32+k*0.18)*(a1-a0); + const rx=Math.cos(aa),ry=Math.sin(aa),tx2=-ry,ty2=rx; + const bl=2+9*fo; // 铆钉→尖刺连续伸长 + poly([rx*(R+5)+tx2*2.5,ry*(R+5)+ty2*2.5, rx*(R+5)-tx2*2.5,ry*(R+5)-ty2*2.5, rx*(R+5+bl),ry*(R+5+bl)],fo>0.6?"#c86bff":"#2a1a3a"); + if(fo<0.99){ctx.save(); // 外壳板:爆甲时旋转飞离(有运动轨迹,非消失) + ctx.translate(rx*(R+9+fo*22)+tx2*fo*sd*9,ry*(R+9+fo*22)+ty2*fo*sd*9); + ctx.rotate(aa+Math.PI/2+fo*sd*1.7);ctx.globalAlpha=1-fo; + px(-5,-3,10,6,"#55336e");px(-5,-3,10,2,"#6e4490"); + ctx.restore();ctx.globalAlpha=1;}} + {const ta=a0+0.5*(a1-a0),bl2=2+6*fo; // 红色炮台:基座常存,爆甲后炮管伸出点亮 + ctx.save();ctx.translate(Math.cos(ta)*(R+2),Math.sin(ta)*(R+2));ctx.rotate(ta+Math.PI/2); + px(-2.5,-3,5,4,"#2a1a3a"); + px(-1.5,-3-bl2,3,bl2,fo>0.4?(fl||"#ff3355"):"#3a2248"); + ctx.restore();} + for(let k=0;k<2;k++){const aa2=a0+(0.32+k*0.36)*(a1-a0)+Math.sin(t*0.012+k*2)*0.05; // 环面光点 + px(Math.cos(aa2)*R-2,Math.sin(aa2)*R-2,4,4,"#c86bff");} } } if(flashA>0){ctx.globalAlpha=flashA;ctx.strokeStyle="#fff"; @@ -167,39 +174,34 @@ function drawBoss(){ ctx.fillText(b.transT>0?b.name:(b.name+" "+Math.ceil(pc*100)+"%"),W/2,22); } /* ---- Boss 分体绘制助手 ---- */ -function drawPupa(t,fl,cr){ // 太空原种·虫蛹(cr=裂变粉化进度0~1) +function drawProgenitor(t,fl,tf){ // 太空原种:同一躯体连续演化(tf 0=虫蛹→1=完全体),无部件凭空出现 ctx.rotate(Math.sin(t*0.05)*0.05); - const body=[0,-40,11,-37,15,-28,13,-14,11,0,8,14,5,26,2,34,0,36,-2,34,-5,26,-8,14,-11,0,-13,-14,-15,-28,-11,-37]; - poly(body,"#c9d6e2"); - poly([0,-40,11,-37,15,-28,13,-14,11,0,8,14,5,26,2,34,0,36],"#9fb0c2"); - if(cr>0){ctx.globalAlpha=cr*0.85;poly(body,"#f0a0c0");ctx.globalAlpha=1;} // 身体变粉 - for(let i=0;i<5;i++){const wy=-24+i*11,ww=13-i*1.8;px(-ww,wy,ww*2,2,"#8498ac");} - if(cr>0.25){px(-10,-18,3,14,"#8a2a3a");px(7,-8,3,12,"#8a2a3a");} // 表皮裂开 - if(cr>0.55){px(-4,-30,3,10,"#8a2a3a");px(-13,-2,3,9,"#8a2a3a");} - circ(0,-34,10,"#dde7f0");px(-9,-37,18,3,"#9fb0c2"); - px(-6,-35,4,4,fl||"#43e8ff");px(2,-35,4,4,fl||"#43e8ff"); // 青眼 - if(cr>0.3){ctx.globalAlpha=Math.min(1,(cr-0.3)/0.5); // 眼睛变红 - px(-6,-35,4,4,"#ff3355");px(2,-35,4,4,"#ff3355");ctx.globalAlpha=1;} - px(-12,-44,3,7,"#9fb0c2");px(9,-44,3,7,"#9fb0c2"); - px(-19,-16,5,12,"#7fd8ff");px(14,-16,5,12,"#7fd8ff"); -} -function drawManta(t,fl,un){ // 太空原种·蝠鲼(un=展翅进度0~1) - const ws=0.15+0.85*un; - ctx.save();ctx.scale(ws,1+Math.sin(t*0.07)*0.04*un); // 翅膀自背后展开 + const wE=Math.min(1,tf*1.2); // 展翅进度 + // —— 翅膀:折叠时收在躯体正后方(被身体完全遮住),自背后向两侧展开 —— + ctx.save(); + ctx.scale(0.05+0.95*wE,(0.55+0.45*wE)*(1+Math.sin(t*0.07)*0.04*wE)); poly([0,-20,-26,-14,-52,-4,-76,6,-58,12,-34,10,-16,16,0,20],"#c86aa8"); poly([0,-20,26,-14,52,-4,76,6,58,12,34,10,16,16,0,20],"#c86aa8"); poly([0,-18,-24,-12,-50,-3,-72,7,-56,9,-30,2,0,-8],"#e89cc4"); poly([0,-18,24,-12,50,-3,72,7,56,9,30,2,0,-8],"#e89cc4"); - if(un>0.6)for(const sd of[-1,1])for(let i=0;i<3;i++)px(sd*(44+i*10)-1,6+i*2,2,2,"#7dff8a"); + for(const sd of[-1,1])for(let i=0;i<3;i++)px(sd*(44+i*10)-1,6+i*2,2,2,"#7dff8a"); // 翼面斑纹随翼展开 ctx.restore(); - ctx.globalAlpha=Math.min(1,un*1.6); - poly([0,28,-7,8,-8,-8,-5,-18,5,-18,8,-8,7,8],"#8a3a70"); - circ(0,-18,9,"#e8d5e0"); - px(-5,-19,3,4,"#3a1030");px(2,-19,3,4,"#3a1030"); - px(-5,-18,3,3,fl||"#ff3355");px(2,-18,3,3,fl||"#ff3355"); // 红瞳 - px(-13,-26,3,8,"#7dff8a");px(10,-26,3,8,"#7dff8a"); - for(let i=0;i<4;i++)px(-9+i*5,0,3,5,fl||"#ff3355"); - ctx.globalAlpha=1; + // —— 躯体:蛹壳保持同一多边形,粉色血肉晕染全身 —— + const body=[0,-40,11,-37,15,-28,13,-14,11,0,8,14,5,26,2,34,0,36,-2,34,-5,26,-8,14,-11,0,-13,-14,-15,-28,-11,-37]; + poly(body,"#c9d6e2"); + poly([0,-40,11,-37,15,-28,13,-14,11,0,8,14,5,26,2,34,0,36],"#9fb0c2"); + if(tf>0){ctx.globalAlpha=tf*0.85;poly(body,"#f0a0c0");ctx.globalAlpha=1;} // 粉化 + for(let i=0;i<5;i++){const wy=-24+i*11,ww=13-i*1.8;px(-ww,wy,ww*2,2,"#8498ac");} + const crks=[[-10,-18,14,0.12],[7,-8,12,0.28],[-4,-30,10,0.44],[-13,-2,9,0.58]]; // 裂纹逐条生长(延长,非新增) + for(const ck of crks){const cl=Math.max(0,Math.min(1,(tf-ck[3])/0.3))*ck[2]; + if(cl>0.5)px(ck[0],ck[1],3,cl,"#8a2a3a");} + circ(0,-34,10,"#dde7f0");px(-9,-37,18,3,"#9fb0c2"); + px(-6,-35,4,4,fl||"#43e8ff");px(2,-35,4,4,fl||"#43e8ff"); // 眼:青→红渐变 + if(tf>0.3){ctx.globalAlpha=Math.min(1,(tf-0.3)/0.5); + px(-6,-35,4,4,"#ff3355");px(2,-35,4,4,"#ff3355");ctx.globalAlpha=1;} + px(-12,-44,3,7,"#9fb0c2");px(9,-44,3,7,"#9fb0c2"); + px(-19,-16,5,12,"#7fd8ff");px(14,-16,5,12,"#7fd8ff"); // 侧囊:青→荧绿渐变 + if(tf>0.5){ctx.globalAlpha=(tf-0.5)*2;px(-19,-16,5,12,"#7dff8a");px(14,-16,5,12,"#7dff8a");ctx.globalAlpha=1;} } function drawAssault(t,fl,swp,ph,mp){ // 暗黑突击(swp=翼展角;炮管/推进器随阶段增多) const sw=swp*Math.PI/180;