太空原种重设计(试点):美术大改=装甲蛾兽(三角翼+蜈蚣腹+四红复眼+背甲滑开裂粉肉),攻击小改=花弹改从腹末生殖腔喷出(同源摆动)/P1起手偏左/新增复眼四联狙击eyeQuad/P2生殖腔血光柱;判定数值未动。仅语法检查通过,未运行验证

This commit is contained in:
JOJO 2026-08-06 02:22:21 +08:00
parent 3b4e9d35a0
commit 038f6c5b99
2 changed files with 68 additions and 40 deletions

View File

@ -189,7 +189,7 @@ function updateSpawner(){
/* 8大Boss1种主攻击模式 + 同时1~2种随机小攻击血量阈值触发二/三阶段变形 */ /* 8大Boss1种主攻击模式 + 同时1~2种随机小攻击血量阈值触发二/三阶段变形 */
const BOSSES=[ const BOSSES=[
{name:"巡逻巡洋舰",sub:"PATROL CRUISER",hp:950,col:"#e0393e",r:22,main:"cruiser",minors:["snipe","ring"],phases:2}, {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:"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:"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}, {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);} // 通用游走提速+上下浮动(钢琴站桩除外) 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++; b.mt++;
const fm=b.fireM*(1+0.22*b.phase); 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.idx===8){ // 黑石要塞亚空间主炮序列纹路充能52帧→巨柱扫动80帧
if(!b.plT||b.plT<=0)b.plT=Math.round((b.phase>=1?380:460)/fm); if(!b.plT||b.plT<=0)b.plT=Math.round((b.phase>=1?380:460)/fm);
else{ else{
@ -353,17 +353,18 @@ function bossMain(b,def,fm){
case "cruiser": // 巡洋舰:扇形主炮 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"); 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; b.mainT=Math.round((ph?52:70)/fm);break;
case "spawn": // 太空原种花弹圆形八刺越变越大P1三波瞄准 / P2腹柱+翼尖花弹 case "spawn": { // 太空原种:花弹从腹末生殖腔喷出(发射点=生殖腔摆动与drawProgenitor同源公式P1三波起手偏左 / P2生殖腔血光柱+翼尖花弹
if(ph===0){for(let k=0;k<3;k++)for(let i=-2;i<=2;i++){ if(ph===0){const swx=Math.sin(b.t*0.055+2.8)*4.6;
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); 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;} bb.grow=0.007;bb.maxS=2.8;bb.scale=0.9;}
b.mainT=Math.round(76/fm); b.mainT=Math.round(84/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}); }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++){ 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;} bb.grow=0.008;bb.maxS=3;bb.scale=0.9;}
b.mainT=Math.round(130/fm);} b.mainT=Math.round(130/fm);}
break; break;}
case "annihilate": { // 歼灭者:螺旋臂 case "annihilate": { // 歼灭者:螺旋臂
const arms=2+ph; const arms=2+ph;
for(let arm=0;arm<arms;arm++)for(let i=0;i<2;i++)ebul(b.x,b.y,b.t*0.06+arm*(TAU/arms)+i*0.14,2+0.2*ph,"orbP"); for(let arm=0;arm<arms;arm++)for(let i=0;i<2;i++)ebul(b.x,b.y,b.t*0.06+arm*(TAU/arms)+i*0.14,2+0.2*ph,"orbP");
@ -467,6 +468,12 @@ 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 "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 "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 "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];
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;}
case "coneFan": for(let i=-2;i<=2;i++)ebul(b.x,b.y+8,a0+i*0.15,2.9,"dartP",14);b.minorT=Math.round(150/fm);break; // 魔碟:瞄准锥扇 case "coneFan": for(let i=-2;i<=2;i++)ebul(b.x,b.y+8,a0+i*0.15,2.9,"dartP",14);b.minorT=Math.round(150/fm);break; // 魔碟:瞄准锥扇
case "crossEye": for(const sd of[-1,1])bossBeam(b.x+sd*9,b.y-3,ap2.x-sd*26,H+8,3.5,"#ff3355",22,24,18,{b,ox:sd*9,oy:-3});b.minorT=Math.round(230/fm);break; // 魔碟交叉赤瞳斜线X case "crossEye": for(const sd of[-1,1])bossBeam(b.x+sd*9,b.y-3,ap2.x-sd*26,H+8,3.5,"#ff3355",22,24,18,{b,ox:sd*9,oy:-3});b.minorT=Math.round(230/fm);break; // 魔碟交叉赤瞳斜线X
case "dartSpiral": for(let arm=0;arm<3;arm++)ebul(b.x,b.y,b.t*0.11+arm*TAU/3,2.0,"dartP",13);b.minorT=Math.round(46/fm);break; // 魔碟:三臂锥弹螺旋 case "dartSpiral": for(let arm=0;arm<3;arm++)ebul(b.x,b.y,b.t*0.11+arm*TAU/3,2.0,"dartP",13);b.minorT=Math.round(46/fm);break; // 魔碟:三臂锥弹螺旋

View File

@ -56,8 +56,8 @@ function drawBoss(){
for(let i=-2;i<=2;i++)px(i*8-1,12,2,3,t%40<20?"#ff5566":"#7a1622"); 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"); 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");} // 二阶段顶部炮塔 if(ph2>=1){px(-2,-27,4,8,"#5b6b8c");px(-1,-29,2,3,t%20<10?"#ff5566":"#7a1622");} // 二阶段顶部炮塔
}else if(b.idx===1){ // 太空原种:同一躯体连续变形——裂皮→粉化→红眼→身后展翅(无部件凭空出现 }else if(b.idx===1){ // 太空原种·装甲蛾兽:三角翼+蜈蚣腹+四红复眼(变形=背甲滑开裂粉肉/腹节伸长/翼膜转红
drawProgenitor(t,fl,mp!==null?mp:(ph2===0?0:1)); drawProgenitor(b,t,fl,mp!==null?mp:(ph2===0?0:1));
}else if(b.idx===2){ // 歼灭者 }else if(b.idx===2){ // 歼灭者
for(let i=0;i<6;i++){const a=i/6*TAU+t*0.01; 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");} 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); ctx.fillText(b.transT>0?b.name:(b.name+" "+Math.ceil(pc*100)+"%"),W/2,22);
} }
/* ---- Boss 分体绘制助手 ---- */ /* ---- Boss 分体绘制助手 ---- */
function drawProgenitor(t,fl,tf){ // 太空原种同一躯体连续演化tf 0=虫蛹→1=完全体),无部件凭空出现 function drawProgenitor(b,t,fl,tf){ // 太空原种·装甲蛾兽tf 0=装甲态→1=血肉态):大三角翼+蜈蚣腹+四红复眼;同一几何体连续演化,无部件凭空出现
ctx.rotate(Math.sin(t*0.05)*0.05); ctx.rotate(Math.sin(t*0.05)*0.04); // 悬停微摇
const wE=Math.min(1,tf*1.2); // 展翅进度 const wS=0.62+0.38*tf; // 翼展P1半开→P2全展同一对翼连续缩放
// —— 翅膀:折叠时收在躯体后方偏上(被身体完全遮住),自背后向两侧展开 —— // —— 大三角翼一对:蓝灰翼面+绿脉络P2翼膜罩暗红 ——
ctx.save(); for(const sd of[-1,1]){ctx.save();
ctx.translate(0,-12); ctx.translate(sd*7,-8);ctx.scale(sd*wS,1+Math.sin(t*0.07)*0.03); // 呼吸+镜像
ctx.scale(0.05+0.95*wE,(0.55+0.45*wE)*(1+Math.sin(t*0.07)*0.04*wE)); poly([0,-10,22,-18,48,-10,52,2,36,9,14,6,0,2],"#c9d6e2"); // 翼面主甲
poly([0,-20,-26,-14,-52,-4,-76,6,-58,12,-34,10,-16,16,0,20],"#c86aa8"); poly([0,-10,22,-18,48,-10,36,-6,20,-8,0,-4],"#e8f0f6"); // 前缘受光(左亮)
poly([0,-20,26,-14,52,-4,76,6,58,12,34,10,16,16,0,20],"#c86aa8"); poly([0,2,14,6,36,9,52,2,40,0,18,3],"#8498ac"); // 后缘暗面(右暗)
poly([0,-18,-24,-12,-50,-3,-72,7,-56,9,-30,2,0,-8],"#e89cc4"); for(let i=0;i<3;i++){ctx.globalAlpha=0.45+0.35*Math.sin(t*0.09+i*1.3);
poly([0,-18,24,-12,50,-3,72,7,56,9,30,2,0,-8],"#e89cc4"); px(12+i*12,-6+i*3,2,9,"#7dff8a");ctx.globalAlpha=1;} // 翼面绿脉络搏动
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"); // 翼面斑纹随翼展开 if(tf>0){ctx.globalAlpha=tf*0.7;
ctx.restore(); poly([0,-10,22,-18,48,-10,52,2,36,9,14,6,0,2],"#c85a78");ctx.globalAlpha=1;} // P2翼膜转红同一翼面罩色
// —— 躯体:蛹壳保持同一多边形,粉色血肉晕染全身 —— 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]; // —— 蜈蚣腹5节垂挂逐节相位摆动P2节间粉肉显露+整体伸长 ——
poly(body,"#c9d6e2"); const segH=5.2+tf*1.6;
poly([0,-40,11,-37,15,-28,13,-14,11,0,8,14,5,26,2,34,0,36],"#9fb0c2"); 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){ctx.globalAlpha=tf*0.85;poly(body,"#f0a0c0");ctx.globalAlpha=1;} // 粉化 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;} // 节间粉肉环
for(let i=0;i<5;i++){const wy=-24+i*11,ww=13-i*1.8;px(-ww,wy,ww*2,2,"#8498ac");} poly([sw-hw,sy,sw+hw,sy,sw+hw-2,sy+segH,sw-hw+2,sy+segH],i%2?"#b8c8d8":"#c9d6e2"); // 腹节甲片
const crks=[[-10,-18,14,0.12],[7,-8,12,0.28],[-4,-30,10,0.44],[-13,-2,9,0.58]]; // 裂纹逐条生长(延长,非新增) px(sw-hw,sy,3,segH,"#e8f0f6");px(sw+hw-3,sy,3,segH,"#8498ac"); // 左亮右暗
for(const ck of crks){const cl=Math.max(0,Math.min(1,(tf-ck[3])/0.3))*ck[2]; 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"); // 节侧骨刺
if(cl>0.5)px(ck[0],ck[1],3,cl,"#8a2a3a");} }
circ(0,-34,10,"#dde7f0");px(-9,-37,18,3,"#9fb0c2"); const swT=Math.sin(t*0.055+2.8)*4.6,tipY=4+4*segH; // 腹末生殖腔花弹发射口与enemies.js同源公式
px(-6,-35,4,4,fl||"#43e8ff");px(2,-35,4,4,fl||"#43e8ff"); // 眼:青→红渐变 circ(swT,tipY+2,2.6+Math.sin(t*0.11)*0.6,tf>0.5?"#ff5c8a":"#ff8fc8");
if(tf>0.3){ctx.globalAlpha=Math.min(1,(tf-0.3)/0.5); circ(swT,tipY+2,1.1,"#ffdfe5");
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"); if(tf>0){ctx.globalAlpha=tf*0.9;
px(-19,-16,5,12,"#7fd8ff");px(14,-16,5,12,"#7fd8ff"); // 侧囊:青→荧绿渐变 poly([0,-36,9,-29,11,-14,7,0,0,3,-7,0,-11,-14,-9,-29],"#f0a0c0");
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;} 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=翼展角;炮管/推进器随阶段增多) function drawAssault(t,fl,swp,ph,mp){ // 暗黑突击swp=翼展角;炮管/推进器随阶段增多)
const sw=swp*Math.PI/180; const sw=swp*Math.PI/180;