From 54b8a6d137c919912df18686c29923c575ea7cbc Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Wed, 5 Aug 2026 23:38:56 +0800 Subject: [PATCH] =?UTF-8?q?=E9=BB=91=E7=9F=B3=E8=A6=81=E5=A1=9E=E9=87=8D?= =?UTF-8?q?=E5=81=9Av3=EF=BC=9A=E5=8E=9A=E9=87=8D=E7=AE=AD=E5=A4=B4?= =?UTF-8?q?=E8=87=82=EF=BC=88=E5=AE=BD=E8=82=A9=E5=90=8E=E6=8E=A0=EF=BC=89?= =?UTF-8?q?+=E4=BA=94=E6=A3=B1=E9=87=91=E5=AD=97=E5=A1=94=E6=A0=B8?= =?UTF-8?q?=E5=BF=83+=E4=BA=9A=E7=A9=BA=E9=97=B4=E7=BA=B9=E8=B7=AF?= =?UTF-8?q?=E5=85=85=E8=83=BD=E5=89=8D=E6=91=87=EF=BC=9B=E6=94=BB=E5=87=BB?= =?UTF-8?q?=E9=87=8D=E5=81=9A=EF=BC=9A=E7=AD=BE=E5=90=8D=E4=B8=BB=E7=82=AE?= =?UTF-8?q?=E4=BB=8E=E6=A0=B8=E5=BF=83=E5=8F=91=E5=B0=84=E7=BC=93=E6=85=A2?= =?UTF-8?q?=E6=89=AB=E5=8A=A8/=E4=BA=94=E9=87=8D=E6=97=8B=E8=BD=AC?= =?UTF-8?q?=E8=8A=B1=E7=93=A3=E5=BC=B9=E5=B9=95/=E7=94=B2=E6=9D=BF?= =?UTF-8?q?=E7=82=AE=E7=BE=A4=E4=BA=A4=E5=8F=89=E7=BD=91/=E4=BA=9A?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E8=A3=82=E9=9A=99/=E6=98=9F=E8=8A=92?= =?UTF-8?q?=E8=84=89=E5=86=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/combat.js | 6 ++++-- js/enemies.js | 41 +++++++++++++++++++++++++++-------------- js/render.js | 44 ++++++++++++++++++++++++++------------------ 3 files changed, 57 insertions(+), 34 deletions(-) diff --git a/js/combat.js b/js/combat.js index bbf963c..88b3156 100644 --- a/js/combat.js +++ b/js/combat.js @@ -158,6 +158,8 @@ function updateBullets(){ b.vx=Math.cos(na)*ss;b.vy=Math.sin(na)*ss; if(fd<36){b.dead=true;fl.dead=true;spawnPart(b.x,b.y,"#ffd23d",2);SFX.graze();}} if(b.grow){b.scale=Math.min(b.maxS||2.6,(b.scale||1)+b.grow);b.r=2.4*b.scale;} // 花弹:越变越大(有上限) + if(b.rift){if(b.rift>0){b.rift--;b.vx=0;b.vy=0; // 亚空间裂隙:悬停预瞄 + if(b.rift<=0){const ra2=Math.atan2(G.p.y-b.y,G.p.x-b.x);b.vx=Math.cos(ra2)*3.9;b.vy=Math.sin(ra2)*3.9;b.spr="dartS";b.scale=1;b.r=2.5;}}} // 倒计时尽化长钉射出 b.x+=b.vx*esf;b.y+=b.vy*esf; if(b.y<-10||b.y>H+10||b.x<-10||b.x>W+10)b.dead=true;} // 热诱弹 @@ -255,8 +257,8 @@ function collide(){ // Boss光束:预警后伤害(点-线段距离判定,每束有命中冷却) for(const bm of G.bbeams){ if(bm.src&&G.boss&&bm.src.b===G.boss){let ox=bm.src.ox||0,oy=bm.src.oy||0; - if(bm.src.arm!==undefined){const ra=G.boss.t*0.0032+bm.src.arm*TAU/5;ox=Math.sin(ra)*32;oy=-Math.cos(ra)*32;} // 黑石要塞:臂尖随整体旋转 - bm.x1=G.boss.x+ox;bm.y1=G.boss.y+oy;if(bm.src.followX2)bm.x2=bm.x1;} // 发射点跟随Boss炮台 + bm.x1=G.boss.x+ox;bm.y1=G.boss.y+oy;if(bm.src.followX2)bm.x2=bm.x1; + if(bm.src.sweep)bm.x2=bm.x1+Math.sin(G.time*0.014)*(bm.src.amp||55);} // 黑石要塞:亚空间主炮缓慢扫动 if(bm.tele>0){bm.tele--;continue;} bm.life--; if(bm.cd>0)bm.cd--; diff --git a/js/enemies.js b/js/enemies.js index 343940e..863a934 100644 --- a/js/enemies.js +++ b/js/enemies.js @@ -155,7 +155,7 @@ const BOSSES=[ {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:"暗黑魔碟",sub:"DARK SAUCER",hp:4500,col:"#8a5cff",r:24,rr:[30,32,34],main:"saucer",minors:["ringBig","coneFan","crossEye","dartSpiral"],phases:3}, {name:"兽人战斗月亮",sub:"ORK ROK",hp:2000,col:"#c8752a",r:26,rr:[26,29],ryy:[24,26],main:"rok",minors:["rockRain","spawnMini","snipe"],phases:2}, - {name:"黑石要塞",sub:"BLACKSTONE",hp:3400,col:"#5cff9d",r:30,rr:[30,33],ryy:[22,24],wide:1,main:"blackstone",minors:["torpedo","ringBig","spawnMini"],phases:2}, + {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:2800,col:"#7dff8a",r:24,rr:[24,28],ryy:[17,19],main:"hiveship",minors:["bioPlasma","spawnMini","ringBig"],phases:2} ]; /* Boss命中判定:支持椭圆(宽扁机型),rr=x半径,ry=y半径 */ @@ -262,6 +262,14 @@ function updateBoss(){ 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.idx===9){ // 黑石要塞:亚空间主炮序列(纹路充能52帧→巨柱扫动80帧) + if(!b.plT||b.plT<=0)b.plT=Math.round((b.phase>=1?380:460)/fm); + else{ + if(b.plT===142){b.laserT=142;b.warpChg=0.001;SFX.warn();} + if(b.plT<=142&&b.plT>90)b.warpChg=Math.min(1,(142-b.plT)/52); + if(b.plT===90){b.warpChg=0;bossBeam(b.x,b.y+6,b.x,H+8,b.phase>=1?24:20,"#5cff9d",10,80,30,{b,ox:0,oy:6,followX2:true,sweep:1,amp:b.phase>=1?70:50});} + } + } const lck=(b.laserT||0)>0; // 巨宽核心激光期间压制其他攻击 // —— 主攻击 —— b.mainT--; @@ -330,18 +338,11 @@ function bossMain(b,def,fm){ b.rokC=(b.rokC||0)+1; if(b.rokC%(ph?2:3)===0){const mb=ebul(b.x,b.y+26,a0,1.05,"orbO",26);mb.scale=2.4;mb.r=6;SFX.warn();} b.mainT=Math.round((ph?80:95)/fm);break; - case "blackstone": { // 黑石要塞:单臂光矛依序绕堡充能 + 全体臂尖黑石碎片幕 交替;P2周期性亚空间主炮(压制其他攻击) - b.armC=(b.armC||0)+1; - const rot=b.t*0.0032; - if(b.armC%2===1){const ai=(b.armC>>1)%5; // 单臂光矛(依序轮换) - const a=rot+ai*TAU/5,tx=Math.sin(a)*32,ty=-Math.cos(a)*32; - bossBeam(b.x+tx,b.y+ty,b.x+tx*2.2,H+8,4,"#5cff9d",22,24,18,{b,arm:ai}); - }else for(let k=0;k<5;k++){const a=rot+k*TAU/5,tx=Math.sin(a)*32,ty=-Math.cos(a)*32; // 全体臂尖碎片幕 - for(let j=-1;j<=1;j++)ebul(b.x+tx,b.y+ty,Math.PI/2+Math.sin(a)*0.5+j*0.16,1.7,"shardB",13);} - b.mainT=Math.round(40/fm); - if(ph>=1&&(!b.plT||b.plT<=0)){bossBeam(b.x,b.y+8,b.x,H+8,16,"#5cff9d",46,70,28,{b,ox:0,oy:8,followX2:true}); - b.laserT=120;b.plT=Math.round(380/fm);SFX.warn();} - break;} + case "blackstone": { // 黑石要塞:五重旋转花瓣弹幕(往复旋摆);签名亚空间主炮见updateBoss帧级序列 + const base=Math.sin(b.t*0.008)*1.1; + for(let k=0;k<5;k++)ebul(b.x,b.y,k*TAU/5+base,1.55,"orbG",13); + if(ph>=1)for(let k=0;k<5;k++)ebul(b.x,b.y,k*TAU/5-base+TAU/10,1.55,"orbG",13); // P2双层反向编织 + b.mainT=Math.round((ph>=1?38:46)/fm);break;} case "hiveship": // 泰伦母舰:酸液扇 + 孢子雷散布 + 周期孵化虫群 for(let i=-2;i<=2;i++)ebul(b.x,b.y+14,a0+i*0.17,2.5,"orbG",14); b.spC=(b.spC||0)-1; @@ -405,7 +406,19 @@ function bossMinor(b,mk,fm){ 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 "rockRain": for(let i=0;i<4;i++)ebul(rnd(25,W-25),-6,Math.PI/2+rnd(-0.08,0.08),1.7,"rockb",15);b.minorT=Math.round(150/fm);break; // 兽人月:碎石雨 - case "torpedo": for(let i=-1;i<=1;i++){const tb=ebul(b.x+i*18,b.y+12,Math.PI/2+i*0.1,1.25,"orbO",18);tb.scale=1.8;tb.r=4.5;}b.minorT=Math.round(240/fm);break; // 黑石:重型鱼雷三连 + case "deckGuns": { // 黑石:甲板炮群——五臂侧舷齐射交叉火力网 + const rt=b.t*0.0032; + for(let k=0;k<5;k++){const a=rt+k*TAU/5,gx=b.x+Math.sin(a)*22,gy=b.y-Math.cos(a)*22; + for(const sd of[-1,1])ebul(gx+Math.cos(a)*sd*8,gy+Math.sin(a)*sd*8,Math.PI/2+Math.sin(a)*0.7+sd*0.3,1.5,"orbG",12);} + b.minorT=Math.round(225/fm);break;} + case "crackRift": // 黑石:亚空间裂隙——现身预瞄,延迟变长钉射出 + for(let i=0;i<3+b.phase*2;i++){const rb=ebul(clamp(ap2.x+rnd(-70,70),16,W-16),clamp(ap2.y+rnd(-60,30),H*0.32,H-30),0,0,"orbG",14); + rb.rift=rndi(26,44);rb.scale=1.5;rb.r=4;} + b.minorT=Math.round(255/fm);break; + case "starLine": { // 黑石:星芒脉冲——十向高速弹线,交替偏相半格 + b.stC=(b.stC||0)+1;const off=(b.stC%2)*(TAU/20); + for(let k=0;k<10;k++)ebul(b.x,b.y,k*TAU/10+off,3.1,"orbG",13); + b.minorT=Math.round(215/fm);break;} case "bioPlasma": for(let k=0;k<3;k++)ebul(b.x,b.y+12,a0+(k-1)*0.1,3.4,"orbG",14);b.minorT=Math.round(150/fm);break; // 泰伦:生物电浆三连 } } diff --git a/js/render.js b/js/render.js index b599cf4..00e5b20 100644 --- a/js/render.js +++ b/js/render.js @@ -126,28 +126,35 @@ function drawBoss(){ ctx.globalAlpha=0.35+0.45*op; px(-22,-26,3,cl,fl||"#ff5a2a");px(8,-16,3,cl*0.8,fl||"#ff5a2a");px(-6,0,3,cl*0.6,fl||"#ff5a2a"); ctx.globalAlpha=1;} - }else if(b.idx===9){ // 黑石要塞:五芒黑石装甲星堡(俯视),缓慢旋转;二阶段外壳裂瓣微开露亚空间绿光 + }else if(b.idx===9){ // 黑石要塞:厚重箭头臂+五棱金字塔核心(俯视五芒星堡,缓慢旋转);纹路充能=主炮前摇 const op=mp!==null?mp:(ph2>=1?1:0); - ctx.save();ctx.rotate(t*0.0032); // 整体缓慢旋转(光矛臂尖同步跟随) - for(let k=0;k<5;k++){ctx.save();ctx.rotate(k*TAU/5); - px(-2,-26,4,24,"#2fae6a"); // 臂内亚空间光芯(壳下常存,裂开后露出) - for(const sd of[-1,1]){ctx.save();ctx.translate(sd*op*2.5,0); // 装甲外壳两瓣沿中线微开 - poly([0,-32,sd*6,-20,sd*12,6,sd*6,12,0,10],"#161d2c"); - poly([0,-28,sd*4,-18,sd*8,4,sd*4,8,0,6],"#232f47"); // 板面层次 - px(sd<0?-8:5,-12,3,9,"#3d4f73"); // 棱线高光 + const chg=Math.max(b.warpChg||0,ph2>=1?0.55:0); // P2纹路常亮半格,主炮充能满亮 + ctx.save();ctx.rotate(t*0.0032); // 整体缓慢旋转 + for(let k=0;k<5;k++){ctx.save();ctx.rotate(k*TAU/5); // —— 五支厚重箭头臂 —— + px(-2,-30,4,22,"#173d2a"); // 壳下亚空间光芯(常存,裂开才见) + for(const sd of[-1,1]){ctx.save();ctx.translate(sd*op*2,0); // 二阶段臂板沿中线微开 + poly([0,-50,sd*16,-32,sd*9,-26,sd*6,-6,0,-6],"#10151f"); // 下层臂板:宽肩后掠箭头剪影 + poly([0,-47,sd*12.5,-31,sd*7,-25,sd*4.5,-8,0,-8],"#1b2434"); // 上层臂板(厚度层次) + poly([0,-47,sd*12.5,-31,sd*7,-25,0,-30],sd<0?"#33436a":"#232f47"); // 箭头斜面受光(左亮右暗) + px(sd*2-1,-22,2,12,"#0a0e16"); // 板缝 ctx.restore();} - px(-1.5,-34,3,4,fl||"#5cff9d"); // 臂尖绿晶 + px(-1,-26,2,18,"#123324"); // 中央能量纹路(暗纹常存) + if(chg>0){const vl=18*chg;px(-1,-8-vl,2,vl,"#5cff9d");} // 亮纹从臂根向箭头蔓延(充能前摇) + px(-1.5,-50,3,3,fl||"#5cff9d"); // 箭头尖绿晶 ctx.restore();} - for(let k=0;k<5;k++){ctx.save();ctx.rotate((k+0.5)*TAU/5); // 臂间小堡(次层剪影) - poly([0,-13,5,-4,-5,-4],"#0f1622"); - ctx.restore();} - poly([0,-17,12,-12,17,0,12,12,0,17,-12,12,-17,0,-12,-12],"#161d2c"); // 中央八角堡垒·外环 - poly([0,-14,10,-10,14,0,10,10,0,14,-10,10,-14,0,-10,-10],"#232f47"); // 内环 - for(let i=0;i<8;i++){const a2=i*TAU/8+TAU/16;px(Math.cos(a2)*14-1,Math.sin(a2)*14-1,2,2,t%40<20?"#3d4f73":"#24304a");} // 堡沿窗火 - circ(0,0,7,"#1f6a44");circ(0,0,4.5,fl||"#5cff9d");circ(0,0,2,"#d6ffe8"); // 亚空间核心(穹顶之下常存) - for(let k=0;k<4;k++){ctx.save();ctx.rotate(k*Math.PI/2+Math.PI/4);ctx.translate(0,-op*4); // 四瓣穹顶对角滑开 - poly([0,0,-5,-2,0,-9,5,-2],"#1c2434"); + for(let k=0;k<5;k++){ctx.save();ctx.rotate((k+0.5)*TAU/5); // 臂间小堡 + poly([0,-15,6.5,-5,-6.5,-5],"#141b29");px(-1,-11,2,2,"#1f6a44"); ctx.restore();} + poly([0,-20,12,-16,19,-6,19,6,12,16,0,20,-12,16,-19,6,-19,-6,-12,-16],"#10151f"); // 外环堡垒·下层 + poly([0,-17,10,-13,16,-5,16,5,10,13,0,17,-10,13,-16,5,-16,-5,-10,-13],"#1b2434"); // 外环堡垒·上层 + for(let i=0;i<10;i++){const a2=i*TAU/10;px(Math.sin(a2)*17.5-1,-Math.cos(a2)*17.5-1,2,2,t%40<20?"#3d4f73":"#24304a");} // 环上窗火 + for(let k=0;k<5;k++){const a1=k*TAU/5-TAU/20,a2=k*TAU/5+TAU/20; // 五棱金字塔(俯视棱面交替受光) + ctx.fillStyle=k%2?"#33436a":"#1b2434"; + ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(Math.sin(a1)*13,-Math.cos(a1)*13);ctx.lineTo(Math.sin(a2)*13,-Math.cos(a2)*13);ctx.closePath();ctx.fill();} + if(op>0){ctx.strokeStyle=`rgba(92,255,157,${op*0.7})`;ctx.lineWidth=1; // 二阶段棱缝透绿 + for(let k=0;k<5;k++){const a=k*TAU/5+TAU/20;ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(Math.sin(a)*13,-Math.cos(a)*13);ctx.stroke();}} + if(chg>0)circ(0,0,5+chg*3.5,`rgba(92,255,157,${chg*0.3})`); // 充能光晕 + circ(0,0,4.5,"#0a2418");circ(0,0,3,fl||"#5cff9d");circ(0,0,1.3,"#d6ffe8"); // 亚空间核心 ctx.restore(); }else if(b.idx===10){ // 泰伦母舰:生物质长舰+前触手;二阶段背甲滑开露荧光器官、触手伸长 const op=mp!==null?mp:(ph2>=1?1:0); @@ -393,6 +400,7 @@ function render(){ for(const b of G.eb){ if(b.scale&&b.scale!==1){const sp=SPR[b.spr]; // 成长弹(花弹) ctx.save();ctx.translate(Math.round(b.x),Math.round(b.y));ctx.scale(b.scale,b.scale); + if(b.rift>0)ctx.globalAlpha=0.5+0.4*Math.sin(G.time*0.35); // 裂隙弹预警闪烁 ctx.drawImage(sp,-Math.round(sp.width/2),-Math.round(sp.height/2));ctx.restore();} else if(b.spr==="dartS"||b.spr==="dartB"||b.spr==="dartP"||b.spr==="shardB"){const sp=SPR[b.spr]; // 长条弹:按飞行方向偏转 ctx.save();ctx.translate(Math.round(b.x),Math.round(b.y));