From 038f6c5b99a5973c13eecd82a65424694ca586c2 Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Thu, 6 Aug 2026 02:22:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=AA=E7=A9=BA=E5=8E=9F=E7=A7=8D=E9=87=8D?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=EF=BC=88=E8=AF=95=E7=82=B9=EF=BC=89=EF=BC=9A?= =?UTF-8?q?=E7=BE=8E=E6=9C=AF=E5=A4=A7=E6=94=B9=3D=E8=A3=85=E7=94=B2?= =?UTF-8?q?=E8=9B=BE=E5=85=BD=EF=BC=88=E4=B8=89=E8=A7=92=E7=BF=BC+?= =?UTF-8?q?=E8=9C=88=E8=9A=A3=E8=85=B9+=E5=9B=9B=E7=BA=A2=E5=A4=8D?= =?UTF-8?q?=E7=9C=BC+=E8=83=8C=E7=94=B2=E6=BB=91=E5=BC=80=E8=A3=82?= =?UTF-8?q?=E7=B2=89=E8=82=89=EF=BC=89=EF=BC=8C=E6=94=BB=E5=87=BB=E5=B0=8F?= =?UTF-8?q?=E6=94=B9=3D=E8=8A=B1=E5=BC=B9=E6=94=B9=E4=BB=8E=E8=85=B9?= =?UTF-8?q?=E6=9C=AB=E7=94=9F=E6=AE=96=E8=85=94=E5=96=B7=E5=87=BA=EF=BC=88?= =?UTF-8?q?=E5=90=8C=E6=BA=90=E6=91=86=E5=8A=A8=EF=BC=89/P1=E8=B5=B7?= =?UTF-8?q?=E6=89=8B=E5=81=8F=E5=B7=A6/=E6=96=B0=E5=A2=9E=E5=A4=8D?= =?UTF-8?q?=E7=9C=BC=E5=9B=9B=E8=81=94=E7=8B=99=E5=87=BBeyeQuad/P2?= =?UTF-8?q?=E7=94=9F=E6=AE=96=E8=85=94=E8=A1=80=E5=85=89=E6=9F=B1=EF=BC=9B?= =?UTF-8?q?=E5=88=A4=E5=AE=9A=E6=95=B0=E5=80=BC=E6=9C=AA=E5=8A=A8=E3=80=82?= =?UTF-8?q?=E4=BB=85=E8=AF=AD=E6=B3=95=E6=A3=80=E6=9F=A5=E9=80=9A=E8=BF=87?= =?UTF-8?q?=EF=BC=8C=E6=9C=AA=E8=BF=90=E8=A1=8C=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- star-raid/js/enemies.js | 25 ++++++++----- star-raid/js/render.js | 83 ++++++++++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 40 deletions(-) diff --git a/star-raid/js/enemies.js b/star-raid/js/enemies.js index 6c68eeb..e0cbb25 100644 --- a/star-raid/js/enemies.js +++ b/star-raid/js/enemies.js @@ -189,7 +189,7 @@ function updateSpawner(){ /* 8大Boss:1种主攻击模式 + 同时1~2种随机小攻击;血量阈值触发二/三阶段变形 */ const BOSSES=[ {name:"巡逻巡洋舰",sub:"PATROL CRUISER",hp:950,col:"#e0393e",r:22,main:"cruiser",minors:["snipe","ring"],phases:2}, - {name:"太空原种",sub:"SPACE SPAWN",hp:1350,col:"#ff8fc8",r:20,rr:[20,34],ryy:[26,18],wide:1,main:"spawn",minors:["wiggle","flowerSnipe","sporeArc","tentBeam","spawnMini"],phases:2}, + {name:"太空原种",sub:"SPACE SPAWN",hp:1350,col:"#ff8fc8",r:20,rr:[20,34],ryy:[26,18],wide:1,main:"spawn",minors:["wiggle","flowerSnipe","sporeArc","tentBeam","eyeQuad"],phases:2}, {name:"歼灭者",sub:"ANNIHILATOR",hp:1700,col:"#b05ce8",r:22,main:"annihilate",minors:["aimSpread","spawnMine"],phases:3}, {name:"暗黑突击",sub:"DARK ASSAULT",hp:2100,col:"#ff3355",r:9,rr:[9,10,11],ryy:[5,6,7],main:"assault",minors:["rain","aimSpread"],phases:3}, {name:"激光钢琴",sub:"LASER PIANO",hp:2500,col:"#43e8ff",r:26,rr:[100,100],ryy:[30,30],main:"piano",minors:["topRain","ring"],phases:2,static:1}, @@ -302,7 +302,7 @@ function updateBoss(){ else{b.x=W/2+Math.sin(b.mt*0.013)*(def.wide?44:70);b.y=b.ty+Math.sin(b.mt*0.011)*(def.wide?8:12);} // 通用游走提速+上下浮动(钢琴站桩除外) b.mt++; const fm=b.fireM*(1+0.22*b.phase); - if(b.fnT>0)b.fnT--;if(b.plT>0)b.plT--;if(b.eyeT>0)b.eyeT--;if(b.hornT>0)b.hornT--;if(b.laserT>0)b.laserT--; // 帧级技能计时器 + if(b.fnT>0)b.fnT--;if(b.plT>0)b.plT--;if(b.eyeT>0)b.eyeT--;if(b.hornT>0)b.hornT--;if(b.laserT>0)b.laserT--;if(b.eyeGlow>0)b.eyeGlow--; // 帧级技能计时器 if(b.idx===8){ // 黑石要塞:亚空间主炮序列(纹路充能52帧→巨柱扫动80帧) if(!b.plT||b.plT<=0)b.plT=Math.round((b.phase>=1?380:460)/fm); else{ @@ -353,17 +353,18 @@ function bossMain(b,def,fm){ case "cruiser": // 巡洋舰:扇形主炮 for(let i=-2;i<=2;i++)ebul(b.x+i*12,b.y+16,a0+i*0.13,2.2+0.2*ph,"orbR"); b.mainT=Math.round((ph?52:70)/fm);break; - case "spawn": // 太空原种:花弹(圆形八刺,越变越大)P1三波瞄准 / P2腹柱+翼尖花弹 - if(ph===0){for(let k=0;k<3;k++)for(let i=-2;i<=2;i++){ - const bb=ebul(b.x,b.y+8+k*4,a0+i*0.16+(k-1)*0.09,1.5+k*0.2,"flowr",14); + case "spawn": { // 太空原种:花弹从腹末生殖腔喷出(发射点=生殖腔摆动,与drawProgenitor同源公式);P1三波起手偏左 / P2生殖腔血光柱+翼尖花弹 + if(ph===0){const swx=Math.sin(b.t*0.055+2.8)*4.6; + for(let k=0;k<3;k++)for(let i=-2;i<=2;i++){ + const bb=ebul(b.x+swx,b.y+26,a0+i*0.16+(k-1)*0.09+[0.2,0.1,0][k],1.5+k*0.2,"flowr",14); bb.grow=0.007;bb.maxS=2.8;bb.scale=0.9;} - b.mainT=Math.round(76/fm); - }else{bossBeam(b.x,b.y+10,b.x+clamp(ap2.x-b.x,-50,50)*0.5,H+10,7,"#ff8fc8",30,44,22,{b,ox:0,oy:10}); + b.mainT=Math.round(84/fm); + }else{bossBeam(b.x,b.y+24,b.x+clamp(ap2.x-b.x,-50,50)*0.5,H+10,9,"#ff5c8a",30,44,22,{b,ox:0,oy:24}); for(const sd of[-1,1])for(let i=0;i<3;i++){ - const bb=ebul(b.x+sd*52,b.y+2,Math.PI/2+sd*(0.35+i*0.2),1.6,"flowr",13); + const bb=ebul(b.x+sd*50,b.y-2,Math.PI/2+sd*(0.35+i*0.2),1.6,"flowr",13); bb.grow=0.008;bb.maxS=3;bb.scale=0.9;} b.mainT=Math.round(130/fm);} - break; + break;} case "annihilate": { // 歼灭者:螺旋臂 const arms=2+ph; for(let arm=0;arm=1){px(-2,-27,4,8,"#5b6b8c");px(-1,-29,2,3,t%20<10?"#ff5566":"#7a1622");} // 二阶段顶部炮塔 - }else if(b.idx===1){ // 太空原种:同一躯体连续变形——裂皮→粉化→红眼→身后展翅(无部件凭空出现) - drawProgenitor(t,fl,mp!==null?mp:(ph2===0?0:1)); + }else if(b.idx===1){ // 太空原种·装甲蛾兽:三角翼+蜈蚣腹+四红复眼(变形=背甲滑开裂粉肉/腹节伸长/翼膜转红) + drawProgenitor(b,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");} @@ -263,35 +263,56 @@ function drawBoss(){ ctx.fillText(b.transT>0?b.name:(b.name+" "+Math.ceil(pc*100)+"%"),W/2,22); } /* ---- Boss 分体绘制助手 ---- */ -function drawProgenitor(t,fl,tf){ // 太空原种:同一躯体连续演化(tf 0=虫蛹→1=完全体),无部件凭空出现 - ctx.rotate(Math.sin(t*0.05)*0.05); - const wE=Math.min(1,tf*1.2); // 展翅进度 - // —— 翅膀:折叠时收在躯体后方偏上(被身体完全遮住),自背后向两侧展开 —— - ctx.save(); - ctx.translate(0,-12); - 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"); - 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(); - // —— 躯体:蛹壳保持同一多边形,粉色血肉晕染全身 —— - 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 drawProgenitor(b,t,fl,tf){ // 太空原种·装甲蛾兽(tf 0=装甲态→1=血肉态):大三角翼+蜈蚣腹+四红复眼;同一几何体连续演化,无部件凭空出现 + ctx.rotate(Math.sin(t*0.05)*0.04); // 悬停微摇 + const wS=0.62+0.38*tf; // 翼展:P1半开→P2全展(同一对翼连续缩放) + // —— 大三角翼一对:蓝灰翼面+绿脉络(P2翼膜罩暗红) —— + for(const sd of[-1,1]){ctx.save(); + ctx.translate(sd*7,-8);ctx.scale(sd*wS,1+Math.sin(t*0.07)*0.03); // 呼吸+镜像 + poly([0,-10,22,-18,48,-10,52,2,36,9,14,6,0,2],"#c9d6e2"); // 翼面主甲 + poly([0,-10,22,-18,48,-10,36,-6,20,-8,0,-4],"#e8f0f6"); // 前缘受光(左亮) + poly([0,2,14,6,36,9,52,2,40,0,18,3],"#8498ac"); // 后缘暗面(右暗) + for(let i=0;i<3;i++){ctx.globalAlpha=0.45+0.35*Math.sin(t*0.09+i*1.3); + px(12+i*12,-6+i*3,2,9,"#7dff8a");ctx.globalAlpha=1;} // 翼面绿脉络搏动 + if(tf>0){ctx.globalAlpha=tf*0.7; + poly([0,-10,22,-18,48,-10,52,2,36,9,14,6,0,2],"#c85a78");ctx.globalAlpha=1;} // P2翼膜转红(同一翼面罩色) + ctx.restore();} + // —— 蜈蚣腹:5节垂挂,逐节相位摆动;P2节间粉肉显露+整体伸长 —— + const segH=5.2+tf*1.6; + for(let i=4;i>=0;i--){const sw=Math.sin(t*0.055+i*0.7)*(1+i*0.9),sy=4+i*segH,hw=11-i*1.7; + if(tf>0&&i<4){ctx.globalAlpha=tf*0.85;px(sw-hw+2,sy+segH-2,(hw-2)*2,2,"#f0a0c0");ctx.globalAlpha=1;} // 节间粉肉环 + poly([sw-hw,sy,sw+hw,sy,sw+hw-2,sy+segH,sw-hw+2,sy+segH],i%2?"#b8c8d8":"#c9d6e2"); // 腹节甲片 + px(sw-hw,sy,3,segH,"#e8f0f6");px(sw+hw-3,sy,3,segH,"#8498ac"); // 左亮右暗 + for(const sd of[-1,1])poly([sw+sd*(hw+1),sy+1,sw+sd*(hw+4),sy+2.5,sw+sd*(hw+1),sy+4],"#e8dcc0"); // 节侧骨刺 + } + const swT=Math.sin(t*0.055+2.8)*4.6,tipY=4+4*segH; // 腹末生殖腔(花弹发射口,与enemies.js同源公式) + circ(swT,tipY+2,2.6+Math.sin(t*0.11)*0.6,tf>0.5?"#ff5c8a":"#ff8fc8"); + circ(swT,tipY+2,1.1,"#ffdfe5"); + // —— 壳下粉肉(常存于背甲之下,滑开才见) —— + if(tf>0){ctx.globalAlpha=tf*0.9; + poly([0,-36,9,-29,11,-14,7,0,0,3,-7,0,-11,-14,-9,-29],"#f0a0c0"); + px(-2,-30,4,26,"#e85c7a");ctx.globalAlpha=1;} + // —— 背甲两瓣:沿背脊中线裂开,P2向外滑开(同一多边形平移) —— + for(const sd of[-1,1]){ctx.save();ctx.translate(sd*tf*7,0); + poly([0,-40,sd*11,-37,sd*15,-28,sd*13,-12,sd*9,0,0,2],sd<0?"#c9d6e2":"#9fb0c2"); + poly([0,-40,sd*11,-37,sd*15,-28,sd*7,-26,sd*5,-36],"#e8f0f6"); // 受光斜面 + for(let i=0;i<3;i++)px(sd*(4+i*3.4)-1,-24+i*8,2,5,"#5a6c80"); // 甲片板缝 + const crk=Math.max(0,Math.min(1,(tf-0.15)/0.4))*10; // 裂纹随tf生长(延长,非新增) + if(crk>0.5)px(sd*6-1,-18,2,crk,"#8a2a3a"); + ctx.restore();} + // —— 头部:圆顶甲+双犄角(绿纹)+四红复眼(瞳孔追踪玩家,击发后逐一点亮余辉) —— + circ(0,-34,10,"#dde7f0");px(-9,-36,18,3,"#9fb0c2"); + for(const sd of[-1,1]){poly([sd*6,-40,sd*15,-49,sd*12,-51,sd*4,-43],"#8498ac"); + px(sd*9-1,-46,2,4,"#7dff8a");} // 犄角绿纹 + const puX=clamp((G.p.x-b.x)*0.02,-1.2,1.2),puY=clamp((G.p.y-b.y)*0.015,-0.8,1.2); + const EP=[[-6,-34,4],[6,-34,4],[-2.5,-30,3],[2.5,-30,3]]; // 2大2小梯形复眼(与eyeQuad发射点同源) + for(let e=0;e<4;e++){const ex=EP[e][0],ey=EP[e][1],es=EP[e][2]; + px(ex-es/2,ey-es/2,es,es,fl||"#ff3355"); + px(ex-es/2+1+puX,ey-es/2+1+puY,es-2,es-2,"#7a1622"); // 瞳孔追玩家 + if(b.eyeGlow>0&&(20-b.eyeGlow)/5>=e)px(ex-es/2,ey-es/2,es,es,"#fff");} // 击发余辉逐眼点亮 + // —— 头侧青色管囊(P2转荧绿) —— + for(const sd of[-1,1]){px(sd*15-2.5,-18,5,12,tf>0.5?"#7dff8a":(t%40<20?"#7fd8ff":"#43b8ff")); + px(sd*15-1.5,-20,3,3,"#55648a");} } function drawAssault(t,fl,swp,ph,mp){ // 暗黑突击(swp=翼展角;炮管/推进器随阶段增多) const sw=swp*Math.PI/180;