From a9610dfed159fd486c5334d1b66cb203453eb53d Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Thu, 6 Aug 2026 03:28:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=BA=E6=9D=83=E8=80=85X=E9=87=8D=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=EF=BC=9A=E7=BE=8E=E6=9C=AF=E5=A4=A7=E6=94=B9=3DP1?= =?UTF-8?q?=E4=B8=89=E5=B1=82=E9=98=B6=E6=A2=AF=E7=94=B2=E6=9D=BF=E6=AF=8D?= =?UTF-8?q?=E8=88=B0=EF=BC=88=E6=9D=BF=E7=BC=98=E8=93=9D=E7=81=AF=E5=B8=A6?= =?UTF-8?q?/=E6=A9=99=E6=A0=87=E8=AF=86/=E7=BA=A2=E7=82=AE=E5=8F=A3/?= =?UTF-8?q?=E5=8F=8C=E8=81=94=E5=89=AF=E7=82=AE=E5=A1=94/=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E5=88=97/=E8=93=9D=E8=89=B2=E5=A4=A7=E7=9C=BC?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E7=9E=B3=E5=AD=94=E8=BF=BD=E8=B8=AA=EF=BC=89?= =?UTF-8?q?=E2=86=92P2=E7=94=B2=E6=9D=BF=E6=95=B4=E4=BD=93=E6=8A=9B?= =?UTF-8?q?=E7=A6=BB=E6=97=8B=E8=BD=AC=E9=A3=9E=E8=B5=B0=E9=9C=B2=E7=B4=A7?= =?UTF-8?q?=E5=87=91=E9=92=BB=E7=9F=B3=E6=9C=BA=E8=BA=AB=EF=BC=88=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E5=B0=BE=E7=84=B0=EF=BC=89=EF=BC=9B=E6=97=A0=E4=BA=BA?= =?UTF-8?q?=E6=9C=BA=E5=8A=A0=E5=85=89=E7=8E=AF=EF=BC=88=E5=8F=82=E8=80=83?= =?UTF-8?q?=E5=9B=BE=E7=89=B9=E5=BE=81=EF=BC=89=EF=BC=9B=E6=94=BB=E5=87=BB?= =?UTF-8?q?=E5=B0=8F=E6=94=B9=3DP1=E5=8F=91=E5=B0=84=E7=82=B9=E6=94=B9?= =?UTF-8?q?=E6=9C=80=E4=B8=8B=E7=94=B2=E6=9D=BF=E7=82=AE=E5=8F=A3/P2?= =?UTF-8?q?=E6=9C=BA=E5=8A=A8=E6=80=A7=E6=8F=90=E5=8D=87=EF=BC=880.008?= =?UTF-8?q?=E2=86=920.028=E5=B7=A6=E5=8F=B3=E7=A9=BF=E6=A2=AD=EF=BC=89/?= =?UTF-8?q?=E6=97=A0=E4=BA=BA=E6=9C=BA=E9=9B=86=E7=81=AB=E9=98=B5=E5=9E=8B?= =?UTF-8?q?=E6=94=B9=E7=BB=86=E5=85=89=E6=9D=9F/chain=E5=88=A0=E6=94=B9dec?= =?UTF-8?q?kVolley=E7=94=B2=E6=9D=BF=E9=BD=90=E5=B0=84=EF=BC=88=E7=82=AE?= =?UTF-8?q?=E5=8F=A3=E9=80=90=E7=82=B9=E4=BA=AE=E5=89=8D=E6=91=87+6?= =?UTF-8?q?=E5=8F=91=E5=9E=82=E7=9B=B4=E5=BC=B9=E9=9B=A8=EF=BC=8CP1?= =?UTF-8?q?=E9=99=90=E5=AE=9A=EF=BC=89=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/boss_art.js | 52 ++++++++++++++++++++++++++++++++++++++++ star-raid/js/enemies.js | 15 ++++++++---- star-raid/js/render.js | 33 ++++--------------------- 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/star-raid/js/boss_art.js b/star-raid/js/boss_art.js index 35e5e17..c74353f 100644 --- a/star-raid/js/boss_art.js +++ b/star-raid/js/boss_art.js @@ -76,3 +76,55 @@ function drawPiano(b,t,fl,split){ ctx.beginPath();ctx.arc(kx,28,2+3.5*pr,0,TAU);ctx.fill(); ctx.globalAlpha=1;}} } +/* ---- 夺权者X:P1三层阶梯甲板母舰(巨大笨重)→ P2抛甲板露紧凑钻石机身(小巧灵活) ---- + 变形=甲板整体抛离旋转飞走(带轨迹,爆甲原则)+紧凑机身渐显(壳下常存);参考血条观察:P1大→P2小 */ +function drawUsurper(b,t,fl,ph2,mp){ + const jt=mp||0; + // —— P2紧凑钻石机身(壳下常存,mp渐显;瞳孔追玩家;双引擎尾焰=灵活感) —— + if(ph2>=1){const di=mp!==null?mp:1; + ctx.save();ctx.globalAlpha=di;const ds=0.7+0.3*di;ctx.scale(ds,ds); + poly([0,46,-11,6,-7,-30,0,-40,7,-30,11,6],"#e8f4ff"); + poly([0,46,11,6,7,-30,0,-40],"#9fb0c6"); + poly([-7,-28,-26,-38,-20,-22,-7,-25],"#c0cddd");poly([7,-28,26,-38,20,-22,7,-25],"#c0cddd"); + circ(0,-12,6.5,fl||"#43b8ff");circ(0,-12,3.5,"#bfefff"); + circ(clamp((G.p.x-b.x)*0.03,-2,2),-12,1.6,"#0a2a44"); // 瞳孔追玩家 + px(-1.5,-30,3,14,"#43b8ff");px(-1.5,-2,3,26,"#43b8ff"); + for(const sd of[-1,1])px(sd*5-1.5,-44-(t%4),3,3+(t%4),t%6<3?"#7fd8ff":"#43b8ff"); // 引擎尾焰抖动 + ctx.restore();ctx.globalAlpha=1;} + // —— P1巨舰(变形=甲板抛离飞走+舰体淡出) —— + if(ph2===0||mp!==null){const hullA=1-jt; + if(hullA>0.02){ctx.save();ctx.globalAlpha=hullA; + // 主舰体:三段层叠塔 + poly([0,34,-16,10,-13,-24,-7,-38,7,-38,13,-24,16,10],"#d8e4f0"); + poly([0,34,16,10,13,-24,7,-38,0,-38],"#9fb0c6"); + px(-13,-24,26,2,"#5a6c80");px(-11,-8,22,2,"#5a6c80"); // 层间板缝 + px(-16,10,32,3,"#e8f4ff"); // 底缘受光 + // 蓝色大眼核心(同心3层+瞳孔追踪;巨宽激光期高亮) + circ(0,-14,8,"#0d2244");circ(0,-14,6.5,fl||"#43b8ff");circ(0,-14,3.2,"#bfefff"); + circ(clamp((G.p.x-b.x)*0.03,-2.5,2.5),-14,1.5,"#0a2a44"); + if(b.laserT>0){ctx.globalAlpha=hullA*0.5;circ(0,-14,10,"#7ce9ff");ctx.globalAlpha=hullA;} + // 引擎列(顶部4喷口,焰长抖动) + for(let e=0;e<4;e++){const ex2=-12+e*8; + px(ex2-2,-40,4,3,"#5a6c80"); + px(ex2-1.5,-44-(t+e*2)%4,3,3+(t+e*2)%4,e%2?"#7fd8ff":"#43b8ff");} + ctx.restore();ctx.globalAlpha=1;} + // —— 三层阶梯甲板(左右各3层;变形=整体抛离旋转飞走,带运动轨迹) —— + for(const sd of[-1,1])for(let L=0;L<3;L++){ + const ja=(1-jt)*(1-jt*0.85); + if(ja<=0.02)continue; + ctx.save();ctx.translate(sd*jt*(70+L*30),jt*(30+L*14));ctx.rotate(sd*jt*(0.4+L*0.25));ctx.globalAlpha=ja; + const dw=34+L*9,dy=-26+L*13; // 阶梯向下外扩 + poly([sd*8,dy-5,sd*(dw+8),dy,sd*(dw+4),dy+9,sd*8,dy+7],"#c9d6e2"); + poly([sd*8,dy-5,sd*(dw+8),dy,sd*(dw+4),dy+3,sd*8,dy+1],"#e8f4ff"); // 甲板面受光 + px(sd*(dw+2)-2,dy+2,4,2,t%50<25?"#7fd8ff":"#2a5a78"); // 板缘蓝灯带(明灭) + px(sd*(dw-8)-2,dy+4,4,3,"#ff9a3d"); // 橙色标识块 + for(let g=0;g<2+L;g++){const gx=sd*(14+g*10); // 红色炮口(deckVolley前摇:最下层逐个点亮) + const glow=b.deckT>0&&L===2&&(26-b.deckT)>g*6; + px(gx-1,dy+7,3,3,glow?"#ffffff":"#ff3355");} + if(L===1){const tx3=sd*(dw+2); // 侧舷双联副炮塔(随甲板抛离) + px(tx3-2,dy-8,5,10,"#9fb0c6"); + px(tx3-1,dy-12,1.5,5,"#5a6c80");px(tx3+1,dy-12,1.5,5,"#5a6c80"); + px(tx3-1.5,dy-14,2,2,"#ff3355");px(tx3+0.5,dy-14,2,2,"#ff3355");} + ctx.restore();ctx.globalAlpha=1;} + } +} diff --git a/star-raid/js/enemies.js b/star-raid/js/enemies.js index 75ea5ac..0da68dd 100644 --- a/star-raid/js/enemies.js +++ b/star-raid/js/enemies.js @@ -194,7 +194,7 @@ const BOSSES=[ {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","pedal"],phases:2,static:1}, {name:"母巢核心",sub:"HIVE CORE",hp:2800,col:"#ff9a3d",r:22,main:"hive",minors:["spawnMini","aimSpread","ring"],phases:3}, - {name:"夺权者X",sub:"USURPER X",hp:3700,col:"#e8f4ff",r:24,rr:[52,26],ryy:[34,40],wide:1,main:"usurper",minors:["chain","pillar","aimSpread"],phases:2}, + {name:"夺权者X",sub:"USURPER X",hp:3700,col:"#e8f4ff",r:24,rr:[52,26],ryy:[34,40],wide:1,main:"usurper",minors:["deckVolley","pillar","aimSpread"],phases:2}, {name:"暗黑魔碟",sub:"DARK SAUCER",hp:4500,col:"#8a5cff",r:24,rr:[30,32,34],main:"saucer",minors:["ringBig","coneFan","crossEye","dartSpiral"],phases:3}, {name:"黑石要塞",sub:"BLACKSTONE",hp:3400,col:"#5cff9d",r:30,rr:[34,37],ryy:[26,28],wide:1,main:"blackstone",minors:["deckGuns","crackRift","starLine"],phases:2}, {name:"泰伦虫族母舰",sub:"TYRANID HIVESHIP",hp:3200,col:"#7dff8a",r:26,rr:[26,29,32],ryy:[36,38,40],main:"hivespawn",minors:["sporeBloom","tentSweep","acidGas"],phases:3} @@ -240,8 +240,9 @@ function updateFunnels(){ else{f.x+=(ringX-f.x)*0.09;f.y+=(ringY-f.y)*0.09;} // 归位回环绕 if((b.laserT||0)>0)continue; if(fm2.t>=40&&fm2.t<140&&fm2.t%26===0){ - const a2=fa===null?Math.atan2(aimPt().y-f.y,aimPt().x-f.x):fa; - ebul(f.x,f.y,a2,4.6,"dartS",14);f.flashT=5;} + if(fm2.pat===2){const ap4=aimPt();bossBeam(f.x,f.y,ap4.x,ap4.y,2.5,"#7ce9ff",18,14,10);} // 集火阵型改细光束 + else{const a2=fa===null?Math.atan2(aimPt().y-f.y,aimPt().x-f.x):fa; + ebul(f.x,f.y,a2,4.6,"dartS",14);}f.flashT=5;} }else{ f.x+=(ringX-f.x)*0.09;f.y+=(ringY-f.y)*0.09; if((b.laserT||0)>0)continue; // 巨宽核心激光期间停火(仍环绕) @@ -299,6 +300,7 @@ function updateBoss(){ // —— 常规移动 —— if(def.static){b.x+=(W/2-b.x)*0.05;b.y+=(52-b.y)*0.02;} else if(b.idx===3){b.x=W/2+Math.sin(b.mt*0.034)*62;b.y=b.ty+Math.sin(b.mt*0.021)*18;} // 暗黑突击:小体型高机动(空闲大幅提速) + else if(b.idx===6){const usp=b.phase>=1?0.028:0.008;b.x=W/2+Math.sin(b.mt*usp)*(b.phase>=1?70:44);b.y=b.ty+Math.sin(b.mt*0.011)*(b.phase>=1?12:8);} // 夺权者X:P1巨大笨重→P2紧凑灵活 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); @@ -306,6 +308,8 @@ function updateBoss(){ if(b.idx===1&&b.rainT>0&&b.rainT<94&&b.rainT%3===0){ // 原种红雨:前摇16帧双翼高频抖动后,翼展范围内红光点随机洒落 const span=46*(0.22+0.78*(b.phase>=1?1:0.62)); ebul(b.x+rnd(-span,span),b.y+rnd(-10,2),Math.PI/2+rnd(-0.08,0.08),rnd(2.2,3.4),"orbR",12);} + if(b.idx===6&&b.deckT>0){b.deckT--; // 夺权者X:甲板齐射——炮口逐个点亮(前摇26帧)后6发垂直弹雨 + if(b.deckT===0)for(const sd of[-1,1])for(const gx of[14,24,44])ebul(b.x+sd*gx,b.y+6,Math.PI/2,2.6,"dartB",14);} if(b.idx===8){ // 黑石要塞:亚空间主炮序列(纹路充能52帧→巨柱扫动80帧) if(!b.plT||b.plT<=0)b.plT=Math.round((b.phase>=1?380:460)/fm); else{ @@ -428,8 +432,8 @@ function bossMain(b,def,fm){ case "usurper": // 夺权者X:蓝白长钉无人机(P1两架/P2四架僚机);P2周期性巨宽核心激光(压制其他攻击) if(ph===0){ if(!b.fn0){b.fn0=1;spawnFunnels(b,2);} - for(const sd of[-1,1]){const px2=b.x+sd*37,py2=b.y-4,a6=Math.atan2(ap2.y-py2,ap2.x-px2); - ebul(px2,py2,a6,4.4,"dartS",15);} + for(const sd of[-1,1]){const px2=b.x+sd*14,py2=b.y+6,a6=Math.atan2(ap2.y-py2,ap2.x-px2); + ebul(px2,py2,a6,4.4,"dartS",15);} // 发射点=最下甲板炮口(与drawUsurper同源) b.mainT=Math.round(46/fm); }else{ if(!b.plT||b.plT<=0){bossBeam(b.x,b.y+20,b.x,H+8,22,"#7ce9ff",46,80,30,{b,ox:0,oy:20,followX2:true}); @@ -478,6 +482,7 @@ function bossMinor(b,mk,fm){ bb.scale=2.4;bb.r=6;} b.pedT=8;b.minorT=Math.round(280/fm);break;} case "chain": for(let arm=0;arm<2;arm++)for(let i=0;i<4;i++)ebul(b.x,b.y+8,b.t*0.09+arm*Math.PI+i*0.11,1.7,"orbO",14);b.minorT=Math.round(44/fm);break; + case "deckVolley": if(b.phase>=1){b.minorT=80;break;}b.deckT=26;b.minorT=Math.round(320/fm);break; // 夺权者X:甲板齐射(P1限定)——最下甲板炮口逐个点亮前摇→6发垂直弹雨 case "pillar": {const px2=rnd(40,W-40);bossBeam(px2,-6,px2,H+8,4,"#b98cff",26,26,18);b.minorT=Math.round(220/fm);break;} case "eyeBeam": bossBeam(b.x,b.y+6,ap2.x,H+8,4,"#ff3355",22,24,20);b.minorT=Math.round(180/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; diff --git a/star-raid/js/render.js b/star-raid/js/render.js index e37166e..36448a2 100644 --- a/star-raid/js/render.js +++ b/star-raid/js/render.js @@ -82,33 +82,8 @@ function drawBoss(){ const pl=8+Math.sin(t*0.1)*2; px(-pl/2-3,-pl/2-3,pl+6,pl+6,fl||"#ff9a3d");px(-pl/2,-pl/2,pl,pl,"#fff4d9"); px(-2,-22,4,6,"#ffcf5c");px(-2,16,4,6,"#ffcf5c"); - }else if(b.idx===6){ // 夺权者X:巨型母舰(二阶段抛侧舱→拉长钻石机身+僚机) - if(ph2===0||mp!==null){ // P1巨舰主体(变身时收缩淡出) - const hullA=mp!==null?1-mp:1,hullS=mp!==null?1-mp*0.25:1; - if(hullA>0.02){ctx.save();ctx.scale(hullS,hullS);ctx.globalAlpha=hullA; - poly([0,46,-14,8,-22,-30,-9,-42,9,-42,22,-30,14,8],"#d8e4f0"); - poly([0,46,14,8,22,-30,9,-42,0,-42],"#9fb0c6"); - poly([-9,-42,-34,-52,-26,-28,-9,-34],"#aab8cc");poly([9,-42,34,-52,26,-28,9,-34],"#aab8cc"); - circ(0,-16,8,fl||"#43b8ff");circ(0,-16,4,"#bfefff"); - px(-2,-40,4,18,"#43b8ff");px(-2,-4,4,30,"#43b8ff"); - ctx.restore();ctx.globalAlpha=1;}} - if(ph2===0||mp!==null){ // 侧舱(变身时抛离飞走) - const jt=mp||0; - if(jt<0.99)for(const sd of[-1,1]){ctx.save(); - ctx.translate(sd*(37+jt*95),jt*60);ctx.rotate(sd*jt*0.7);ctx.globalAlpha=1-jt*0.8; - px(-11,-22,22,44,"#aab8cc");px(-11,-22,22,4,"#43b8ff"); - px(-8,18,16,6,"#8a9ab8"); - for(let i=0;i<3;i++)px(-3,-10+i*8,6,4,fl||"#ff3355"); - ctx.restore();ctx.globalAlpha=1;}} - if(ph2>=1){ // 拉长钻石机身+机翼(二阶段显现) - const di=mp!==null?mp:1; - ctx.save();ctx.globalAlpha=di;const ds=0.7+0.3*di;ctx.scale(ds,ds); - poly([0,58,-13,8,-8,-38,0,-48,8,-38,13,8],"#e8f4ff"); - poly([0,58,13,8,8,-38,0,-48],"#9fb0c6"); - poly([-8,-36,-36,-48,-28,-26,-8,-30],"#c0cddd");poly([8,-36,36,-48,28,-26,8,-30],"#c0cddd"); - 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 if(b.idx===6){ // 夺权者X:P1三层阶梯甲板母舰(巨大)→P2抛甲板露紧凑钻石机身(灵活) + drawUsurper(b,t,fl,ph2,mp); }else if(b.idx===8){ // 黑石要塞:厚重箭头臂+五棱金字塔核心(俯视五芒星堡,缓慢旋转);纹路充能=主炮前摇 const op=mp!==null?mp:(ph2>=1?1:0); const chg=Math.max(b.warpChg||0,ph2>=1?0.55:0); // P2纹路常亮半格,主炮充能满亮 @@ -338,7 +313,9 @@ function drawAssault(t,fl,swp,ph,mp){ // 暗黑突击(swp=翼展角;炮管/ if(ph>=2){px(-4,-16,8,12,fl||"#ff3355");px(-2,-14,4,8,"#ffdfe5");} } /* ---- Boss光束与浮游炮渲染 ---- */ -function drawFunnel(f){ // 蓝白长钉无人机(单架) +function drawFunnel(f){ // 蓝白长钉无人机(单架,带光环) + ctx.strokeStyle="rgba(127,216,255,0.7)";ctx.lineWidth=1; + ctx.beginPath();ctx.ellipse(f.x,f.y-1,6,2.5,0,0,TAU);ctx.stroke(); // 光环 poly([f.x,f.y-5,f.x+4,f.y+3,f.x-4,f.y+3],"#cfe4ff"); px(f.x-1,f.y-1,2,3,"#43b8ff"); if(f.flashT>0){ctx.globalAlpha=0.6;px(f.x-3,f.y+3,6,3,"#ffffff");ctx.globalAlpha=1;}