From e33327809d45bcb89e5fd98e1c0b2be13de16c23 Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Thu, 6 Aug 2026 02:32:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=AA=E7=A9=BA=E5=8E=9F=E7=A7=8D=E6=8C=89?= =?UTF-8?q?=E9=AA=8C=E6=94=B6=E5=8F=8D=E9=A6=88=E4=BF=AE=E6=AD=A3=EF=BC=9A?= =?UTF-8?q?P1=E6=94=B9=E5=B0=8F=E7=BF=85=E8=8A=BD/P2=E9=AA=A8=E8=86=9C?= =?UTF-8?q?=E7=BF=BC=EF=BC=883=E9=AA=A8=E5=88=BA=E6=92=91=E8=86=9C?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=83=8F=E8=82=89=E5=9D=97=EF=BC=89=EF=BC=9B?= =?UTF-8?q?=E5=8E=BB=E5=A4=8D=E7=9C=BC=E6=94=B9=E5=A4=A7=E9=A2=9A+?= =?UTF-8?q?=E6=84=9F=E5=99=A8=E7=BA=A2=E7=BC=9D=EF=BC=88=E8=99=AB=E5=BD=A2?= =?UTF-8?q?=E5=8E=8B=E8=BF=AB=E6=84=9F=EF=BC=89=EF=BC=9BP2=E8=A1=80?= =?UTF-8?q?=E8=82=89=E6=94=B9=E8=A1=80=E7=BA=A2=E4=B8=8D=E7=B2=89=EF=BC=9B?= =?UTF-8?q?=E8=85=B9=E5=B0=BE=E4=B8=8E=E8=BA=AF=E4=BD=93=E5=88=86=E7=A6=BB?= =?UTF-8?q?=E6=82=AC=E7=A9=BA9px=EF=BC=9BeyeQuad=E6=94=B9mawSnipe=E9=A2=9A?= =?UTF-8?q?=E9=83=A8=E7=8B=99=E5=87=BB=E3=80=82=E4=BB=85=E8=AF=AD=E6=B3=95?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E9=80=9A=E8=BF=87=EF=BC=8C=E6=9C=AA=E8=BF=90?= =?UTF-8?q?=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 | 14 +++++----- star-raid/js/render.js | 57 +++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/star-raid/js/enemies.js b/star-raid/js/enemies.js index e0cbb25..a49e57f 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","eyeQuad"],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","mawSnipe"],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}, @@ -354,12 +354,12 @@ function bossMain(b,def,fm){ 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": { // 太空原种:花弹从腹末生殖腔喷出(发射点=生殖腔摆动,与drawProgenitor同源公式);P1三波起手偏左 / P2生殖腔血光柱+翼尖花弹 - if(ph===0){const swx=Math.sin(b.t*0.055+2.8)*4.6; + if(ph===0){const swx=Math.sin(b.t*0.055+2.8)*5.2; 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); + const bb=ebul(b.x+swx,b.y+30,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(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}); + }else{bossBeam(b.x,b.y+30,b.x+clamp(ap2.x-b.x,-50,50)*0.5,H+10,9,"#ff5c8a",30,44,22,{b,ox:0,oy:30}); for(const sd of[-1,1])for(let i=0;i<3;i++){ 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;} @@ -468,9 +468,9 @@ function bossMinor(b,mk,fm){ case "ringBig": for(let i=0;i<18;i++)ebul(b.x,b.y,i/18*TAU-b.t*0.03,1.8,"orbP",15);b.minorT=Math.round(230/fm);break; case "sporeArc": for(let i=0;i<7;i++)ebul(b.x,b.y+14,Math.PI/2+(i-3)*0.26,1.2,"orbG",13);b.minorT=Math.round(210/fm);break; // 原种:慢速孢子幕(绿,与花弹差异化) case "tentBeam": for(const sd of[-1,1])bossBeam(b.x+sd*14,b.y+6,b.x+sd*76,H+8,3,"#ff8fc8",24,26,16,{b,ox:sd*14,oy:6});b.minorT=Math.round(240/fm);break; // 原种:双触手光束外扫 - case "eyeQuad": { // 原种:复眼四联狙击——2大2小复眼齐射快速红点弹(发射点与drawProgenitor复眼同源;击发后复眼逐一点亮余辉) - const EP=[[-6,-34],[6,-34],[-2.5,-30],[2.5,-30]]; - for(let e=0;e<4;e++){const ex2=b.x+EP[e][0],ey2=b.y+EP[e][1]; + case "mawSnipe": { // 原种:颚部四联狙击——双大颚+头侧管囊齐射快速红点弹(发射点与drawProgenitor同源;击发后大颚+感器缝闪白余辉) + const MP=[[-5,-22],[5,-22],[-15,-16],[15,-16]]; + for(let e=0;e<4;e++){const ex2=b.x+MP[e][0],ey2=b.y+MP[e][1]; const ea=Math.atan2(ap2.y-ey2,ap2.x-ex2); ebul(ex2,ey2,ea+(e-1.5)*0.04,3.6,"orbR",14);} b.eyeGlow=20;b.minorT=Math.round(200/fm);break;} diff --git a/star-raid/js/render.js b/star-raid/js/render.js index c54ba4a..56dc153 100644 --- a/star-raid/js/render.js +++ b/star-raid/js/render.js @@ -263,35 +263,36 @@ function drawBoss(){ ctx.fillText(b.transT>0?b.name:(b.name+" "+Math.ceil(pc*100)+"%"),W/2,22); } /* ---- Boss 分体绘制助手 ---- */ -function drawProgenitor(b,t,fl,tf){ // 太空原种·装甲蛾兽(tf 0=装甲态→1=血肉态):大三角翼+蜈蚣腹+四红复眼;同一几何体连续演化,无部件凭空出现 +function drawProgenitor(b,t,fl,tf){ // 太空原种·装甲虫兽(tf 0=装甲态→1=血肉态):P1小翅芽→P2骨膜巨翼;无复眼(大颚+感器红缝=虫形压迫感);摆尾与躯体分离悬空 ctx.rotate(Math.sin(t*0.05)*0.04); // 悬停微摇 - const wS=0.62+0.38*tf; // 翼展:P1半开→P2全展(同一对翼连续缩放) - // —— 大三角翼一对:蓝灰翼面+绿脉络(P2翼膜罩暗红) —— + const wS=0.22+0.78*tf; // 翼展:P1小翅芽→P2全展(同一对翼连续缩放) + // —— 骨膜翼一对:3根骨刺撑起膜面(P1灰甲小翼→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翼膜转红(同一翼面罩色) + poly([0,-4,14,-16,34,-16,54,-10,48,0,34,6,16,4,0,2],"#c9d6e2"); // 膜面主甲 + poly([0,-4,14,-16,34,-16,54,-10,40,-8,18,-8,0,-1],"#e8f0f6"); // 上缘受光 + poly([0,2,16,4,34,6,48,0,36,0,14,2],"#8498ac"); // 下缘暗面 + for(const tp of[[14,-15],[34,-15],[54,-9]])drawSeg(2,-2,tp[0],tp[1],2,"#8498ac",1); // 3根骨刺(辐射) + if(tf>0){ctx.globalAlpha=tf*0.85; + poly([0,-4,14,-16,34,-16,54,-10,48,0,34,6,16,4,0,2],"#c02030"); // P2膜面转血红(同面罩色) + for(const tp of[[14,-15],[34,-15],[54,-9]])drawSeg(2,-2,tp[0],tp[1],2,"#7a1622",tf); // P2骨刺转暗红 + ctx.globalAlpha=1;} 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"); // 腹节甲片 + // —— 摆尾:与躯体分离悬空(9px空隙),5节逐节相位摆动;P2节间血红肉显露+整体伸长 —— + const segH=5.2+tf*1.6,gap=11; + for(let i=4;i>=0;i--){const sw=Math.sin(t*0.055+i*0.7)*(1.2+i),sy=gap+i*segH,hw=9-i*1.5; + if(tf>0&&i<4){ctx.globalAlpha=tf*0.85;px(sw-hw+2,sy+segH-2,(hw-2)*2,2,"#c8202e");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"); + const swT=Math.sin(t*0.055+2.8)*5.2,tipY=gap+4*segH; // 尾末生殖腔(花弹发射口,与enemies.js同源公式) + circ(swT,tipY+2,2.6+Math.sin(t*0.11)*0.6,fl||(tf>0.5?"#ff2a3c":"#ff5566")); 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;} + poly([0,-36,9,-29,11,-14,7,0,0,3,-7,0,-11,-14,-9,-29],"#c8202e"); + px(-2,-30,4,26,"#e8393a");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"); @@ -300,16 +301,16 @@ function drawProgenitor(b,t,fl,tf){ // 太空原种·装甲蛾兽(tf 0=装甲 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");} // 击发余辉逐眼点亮 + poly([sd*10,-44,sd*13,-48,sd*11,-43],"#5a6c80"); // 犄角锯齿棱 + px(sd*9-1,-46,2,4,"#7dff8a");} // 犄角绿纹 + px(-5,-33,10,1.6,t%30<15?"#ff3355":"#7a1622"); // 感器红缝(明灭) + for(const sd of[-1,1]){poly([sd*3,-26,sd*9,-22,sd*8,-14,sd*5,-13,sd*2,-20],"#e8dcc0"); // 下弯大颚(骨白) + px(sd*5,-16,2,3,"#8a6a4a");} // 颚尖暗色 + if(b.eyeGlow>0){ctx.globalAlpha=b.eyeGlow/20; // 击发余辉:大颚+感器缝闪白 + px(-8,-22,4,3,"#fff");px(4,-22,4,3,"#fff");px(-5,-33,10,1.6,"#fff");ctx.globalAlpha=1;} // —— 头侧青色管囊(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");}