From 676f4344edf0ff2618a0431ac8300b9ccfbc219d Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Thu, 6 Aug 2026 20:40:23 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=88=B6=E4=B8=BB=E6=AD=A6=E5=99=A8/?= =?UTF-8?q?=E5=83=9A=E6=9C=BA/=E6=B2=BB=E7=96=97=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增追踪主武器:蜜蜂手雷、叶绿弹 - 蜂针刺弹/月牙斩/落雷术/火雨/电弧手里剑改为追踪或偏转 - 主武器数值 buff:蜂针x3、圣光x5、月牙攻速x2、泡泡x5等 - 副武器/僚机合并:移除 beamdrone/repair/frostd/teslaD/sweeper - 僚机重做:机枪高速连射、狙击自瞄穿透、导弹追踪爆炸、全体伤害加强 - 治疗反馈:绿十字粒子+血条绿闪+数字 - 同步 CODEX_KEYS 白名单 --- star-raid/js/combat.js | 27 +++++--- star-raid/js/core.js | 139 +++++++++++++++++++++++++++------------- star-raid/js/data.js | 73 ++++++++++----------- star-raid/js/enemies.js | 2 +- star-raid/js/render.js | 14 +++- star-raid/js/sprites.js | 5 ++ star-raid/js/ui.js | 4 +- star-raid/server/api.js | 9 +-- 8 files changed, 173 insertions(+), 100 deletions(-) diff --git a/star-raid/js/combat.js b/star-raid/js/combat.js index 31f5ab3..7be2c19 100644 --- a/star-raid/js/combat.js +++ b/star-raid/js/combat.js @@ -114,8 +114,13 @@ function updateBullets(){ } if(b.trailCol&&G.time%2===0)G.parts.push({x:b.x,y:b.y,vx:rnd(-0.2,0.2),vy:0.4,life:12,col:b.trailCol,sz:1}); if(b.t==="nb"&&G.time%4===0)G.parts.push({x:b.x+rnd(-4,4),y:b.y+rnd(-4,4),vx:rnd(-0.3,0.3),vy:rnd(-0.3,0.3),life:14,col:pick(["#b98cff","#e0b3ff"]),sz:1}); - // 电弧手里剑:一路前飞不停留,全程周期性放电 + // 电弧手里剑:引力偏转靠向敌人,全程周期性放电 if(b.t==="shk"&&!b.dead){ + const tg2=nearestEnemy(b.x,b.y,130); + if(tg2){const a=Math.atan2(tg2.y-b.y,tg2.x-b.x),c=Math.atan2(b.vy,b.vx); + let d4=a-c;while(d4>Math.PI)d4-=TAU;while(d4<-Math.PI)d4+=TAU; + const na=c+clamp(d4,-(b.deflect||0.04),b.deflect||0.04),s=Math.hypot(b.vx,b.vy); + b.vx=Math.cos(na)*s;b.vy=Math.sin(na)*s;} b.pt2=(b.pt2||0)-1; if(b.pt2<=0){b.pt2=b.pulse||20; const tg=nearEnemies(b.x,b.y,55,3); @@ -126,11 +131,11 @@ function updateBullets(){ let pz=!!nearestEnemy(b.x,b.y,26); if(!pz&&bossHit(b.x,b.y,26))pz=true; if(pz){b.dead=true;explodeOnce(b);}} - if(b.t==="c"&&!b.dead&&b.yMath.PI)d4-=TAU;while(d4<-Math.PI)d4+=TAU; - const na=ca+clamp(d4,-0.035,0.035),ss=Math.hypot(b.vx,b.vy); - b.vx=Math.cos(na)*ss;b.vy=Math.sin(na)*ss;} + if(b.t==="bg"&&!b.dead){ // 蜜蜂手雷:近炸引信 + const tg=nearestEnemy(b.x,b.y,38); + if(tg){b.dead=true;explodeOnce(b);} + else{b.fuse=(b.fuse||0)-1;if(b.fuse<=0){b.dead=true;explodeOnce(b);}} + } if(!b.back&&b.bt!==undefined){b.bt--;if(b.bt<=0&&!b.dead){b.dead=true;explodeOnce(b);}} if(b.t==="mt"&&b.ty2!==undefined&&b.y<=b.ty2&&!b.dead){b.dead=true;explodeOnce(b);} if(b.t==="s"&&!b.dead){ // 分裂弹:飞行一段距离后自动分裂 @@ -211,7 +216,8 @@ function collide(){ } if(b.pierce){if(!b.hits)b.hits={};const u2=e.uid||(e.uid=_uid++); if(b.hits[u2]!==undefined)continue; - b.hits[u2]=1;} + b.hits[u2]=1;b.phc=(b.phc||0)+1; + if(b.hitsMax&&b.phc>=b.hitsMax){b.dead=true;}} else b.dead=true; if(b.slow)e.slow=Math.max(e.slow||0,b.slow); if(b.freeze){e.frozen=Math.max(e.frozen||0,b.freeze);e.slow=0;explodeFx(b.x,b.y,"ice",0.5);} @@ -238,7 +244,7 @@ function collide(){ if(!b.dead&&G.boss){ const B=G.boss; if(bossHit(b.x,b.y,b.r)){ - if(b.pierce){if(!b.hits)b.hits={};if(!b.hits.boss){b.hits.boss=1;hurtBoss(b.dmg);}} + if(b.pierce){if(!b.hits)b.hits={};if(!b.hits.boss){b.hits.boss=1;hurtBoss(b.dmg);b.phc=(b.phc||0)+1;if(b.hitsMax&&b.phc>=b.hitsMax)b.dead=true;}} else{b.dead=true; if(b.t==="sg"||b.t==="ho"||b.t==="bb"||b.t==="am"||b.t==="tb"||b.t==="tb2"||b.t==="dw"||b.t==="ph"||b.t==="nb"||b.t==="ex"||b.t==="lm"||b.t==="lb")explodeOnce(b); else hurtBoss(b.dmg);} @@ -294,7 +300,10 @@ function collide(){ k.dead=true; if(k.kind==="gem"){addXp(G.mutator==="ARMOR"?1.3:1);SFX.pick();} else if(k.kind==="coin"){addCoins(1);SFX.coin();} - else if(k.kind==="heart"){if(G.hpH+10)k.dead=true; diff --git a/star-raid/js/core.js b/star-raid/js/core.js index 97a3bb5..c94dbc7 100644 --- a/star-raid/js/core.js +++ b/star-raid/js/core.js @@ -25,6 +25,7 @@ function newRun(mode,shipKey,diff){ luck:(meta.luck||0),mutator:null,mutList:[], time:0,boss:null,bossN:0,bossKills:0,shake:0,hitstop:0,flash:0,slowmo:0, weapons:{vulcan:1},loadout:["vulcan"],subs:{},subLoadout:[],drones:{},droneLoadout:[], + healFlash:0,healAmt:0, wt:{},wst:{},sst:{},dst:{},zones:[],zaps:[],novas:[],flares:[],holies:[],shocks:[],bbeams:[],funnels:[], u:{fire:0,crit:0,shield:0,nano:0,mag:0,bounty:0,odcore:0,ghost:0}, enemies:[],pb:[],eb:[],parts:[],picks:[],texts:[],lasers:[], @@ -132,6 +133,24 @@ function pbul(x,y,vx,vy,dmg,o){ if(!isFinite(x)||!isFinite(y)||!isFinite(vx)||!isFinite(vy))return; // NaN 防护 G.pb.push(Object.assign({x,y,vx,vy,dmg,r:3,t:"v",life:400,pierce:false,hit:null},o||{})); } +/* ================= 治疗反馈(绿十字+血条绿闪+数字) ================= */ +function healPlayer(amount,quiet){ + if(!amount||amount<=0)return; + const old=G.hp; + G.hp=Math.min(G.maxHp,G.hp+amount); + const actual=G.hp-old; + if(actual<=0)return; + G.healFlash=40; + G.healAmt=(G.healAmt||0)+actual; + if(!quiet){ + G.texts.push({x:G.p.x,y:G.p.y-14,t:"+"+Math.round(G.healAmt),col:"#5cff9d",life:40}); + for(let i=0;i<5;i++)G.parts.push({x:G.p.x+rnd(-6,6),y:G.p.y+rnd(-6,6),vx:rnd(-0.8,0.8),vy:rnd(-2,-0.6),life:28+rndi(0,14),col:"#5cff9d",sz:2,cross:true}); + G.healAmt=0; + SFX.pick(); + }else if(G.time%4===0){ + G.parts.push({x:G.p.x+rnd(-6,6),y:G.p.y+rnd(-6,6),vx:rnd(-0.8,0.8),vy:rnd(-2,-0.6),life:28+rndi(0,14),col:"#5cff9d",sz:2,cross:true}); + } +} /* ================= 武器引擎 ================= */ function hurtT(t,dmg,crit){if(G.boss&&t===G.boss)hurtBoss(dmg);else hurtEnemy(t,dmg,crit);} function nearEnemies(x,y,r,n){ @@ -307,6 +326,13 @@ function explodeBullet(b){ for(let i=0;i0){S.on--; for(let i=0;i=st.charge){S.c=0;S.beam=st.beam;SFX.od();}} break; - case "crescent": // 巨型旋刃:仅前方±30°两个方向,自身旋转,贯穿 + case "crescent": // 月牙斩:追踪旋刃,命中3次后消失 if(G.wt[wk]<=0){G.wt[wk]=Math.max(20,st.int/fm); for(const sd of[-1,1]){const ca=-Math.PI/2+sd*Math.PI/6; - pbul(p.x+sd*6,p.y-8,Math.cos(ca)*st.spd,Math.sin(ca)*st.spd,st.dmg*wdm,{t:"c",spr:"cres",pierce:true,r:6,spin:true,scale:1.8});} + pbul(p.x+sd*6,p.y-8,Math.cos(ca)*st.spd,Math.sin(ca)*st.spd,st.dmg*wdm,{t:"c",spr:"cres",pierce:true,r:6,spin:true,scale:1.8,homing:true,maxSpd:st.spd,hitsMax:3});} SFX.shoot();} break; case "fission": @@ -391,9 +423,12 @@ function fireWeapons(){ if(G.wt[wk]<=0){G.wt[wk]=Math.max(6,st.int/fm); pbul(p.x,p.y-10,rnd(-0.3,0.3),-st.spd,st.dmg*wdm,{t:"bb",spr:"bub",aoe:st.aoe,pierce:true,life:150,r:6});} break; - case "starfall": // 流星自屏幕底部逆冲而起 + case "starfall": // 流星火雨:瞄准敌人位置从天而降 if(G.wt[wk]<=0){G.wt[wk]=Math.max(70,st.int/fm); - for(let i=0;i0){S.on--; - const t=nearestEnemy(S.x,S.y,220); - if(t){G.lasers.push({x1:S.x,y1:S.y,x2:t.x,y2:t.y,w:3,life:2,col:"#ff6b9d"}); - if(G.time%3===0)hurtT(t,(6+3*lv)*dm*0.34,false);}} - else{S.t=(S.t||0)-1;if(S.t<=0){S.on=22;S.t=(140-15*lv)/fm;}} - break;} case "frostnova": S.t=(S.t||0)-1; if(S.t<=0){S.t=(260-30*lv)/fm; const r=50+10*lv; @@ -574,11 +616,6 @@ function fireWeapons(){ pbul(p.x+sd*8,p.y-2,sd*2.5,0,(16+5*lv)*dm,{t:"am",spr:"amsl",phase:1,pt:0,zone:16,r:3,trailCol:"#9aa4b8",rot:true,pierce:true}); SFX.shoot();} break; - case "repair": S.t=(S.t||0)-1; - if(S.t<=0){S.t=(30-4*lv)*60; - if(G.hp0){const spread=0.28,a=-Math.PI/2+rnd(-spread,spread); + pbul(S.x,S.y,Math.cos(a)*4.6,Math.sin(a)*4.6,(5+3*lv)*dm*db,{r:2,spr:"swep"}); + S.t=Math.max(3,5/fm);} + else{S.burst=4+lv;S.t=Math.max(10,(28-3*lv)/fm);}} + break;} + case "burst2": { // 双翼机枪手:双管高速连射 + if(S.t<=0){S.burst=(S.burst||0)-1; + if(S.burst>0){const spread=0.24,a=-Math.PI/2+rnd(-spread,spread); + pbul(S.x-3,S.y,Math.cos(a)*4.6,Math.sin(a)*4.6,(4+2.5*lv)*dm*db,{r:2,spr:"swep"}); + pbul(S.x+3,S.y,Math.cos(a)*4.6,Math.sin(a)*4.6,(4+2.5*lv)*dm*db,{r:2,spr:"swep"}); + S.t=Math.max(3,5/fm);} + else{S.burst=4+lv;S.t=Math.max(12,(32-3*lv)/fm);}} + break;} + case "snipe": { // 狙击僚机:自瞄高伤穿透 + if(S.t<=0){S.t=Math.max(45,(80-8*lv)/fm); + const t=nearestEnemy(S.x,S.y,280); + if(t){const d=Math.hypot(t.x-S.x,t.y-S.y)||1; + const vx=(t.x-S.x)/d*7.5,vy=(t.y-S.y)/d*7.5; + pbul(S.x,S.y,vx,vy,(35+22*lv)*dm*db,{r:3,spr:"dSnip",pierce:true,hitsMax:4,trailCol:"#43e8ff"});}} + break;} case "beam": - if(S.on>0){S.on--;const t=nearestEnemy(S.x,S.y,200); + if(S.on>0){S.on--;const t=nearestEnemy(S.x,S.y,220); if(t){G.lasers.push({x1:S.x,y1:S.y,x2:t.x,y2:t.y,w:3,life:2,col:"#ff6b9d"}); - if(G.time%3===0)hurtT(t,(5+3*lv)*dm*0.34,false);}} - else if(S.t<=0){S.on=20;S.t=(140-15*lv)/fm;} + if(G.time%3===0)hurtT(t,(10+5*lv)*dm*db*0.34,false);}} + else if(S.t<=0){S.on=25;S.t=(120-12*lv)/fm;} break; - case "bomb": if(S.t<=0){S.t=(150-12*lv)/fm;pbul(S.x,S.y,0,-2.5,(12+6*lv)*dm*db,{t:"tb2",spr:"bombp",bt:40,aoe:24,r:3});}break; - case "frostD": if(S.t<=0){S.t=Math.max(24,(44-3*lv)/fm);aimShot(S.x,S.y,(3+2*lv)*dm*db,5,"frost",60+20*lv);}break; - case "teslaD": if(S.t<=0){S.t=Math.max(30,(55-4*lv)/fm); - const t=nearestEnemy(S.x,S.y,85); - if(t){zapVisual(S.x,S.y,t.x,t.y,"#ffe95c");hurtT(t,(6+3*lv)*dm*db,true);}}break; + case "bomb": if(S.t<=0){S.t=(110-10*lv)/fm; + pbul(S.x,S.y,0,-2.5,(22+13*lv)*dm*db,{t:"tb2",spr:"bombp",bt:40,aoe:32+5*lv,r:3});}break; case "melee": { // 冲撞僚机:加大环绕半径与判定 const a2=G.time*0.07+i*(TAU/Math.max(1,dn)); S.x=p.x+Math.cos(a2)*38;S.y=p.y+Math.sin(a2)*38; - for(const e of G.enemies)if(!e.dead&&dist2(S.x,S.y,e.x,e.y)<(e.r+10)*(e.r+10)&&G.time-(e.ramT||0)>22){e.ramT=G.time;hurtEnemy(e,(8+4*lv)*dm*db,true);} - if(G.boss&&bossHit(S.x,S.y,10)&&G.time-(G.boss.ramT||0)>22){G.boss.ramT=G.time;hurtBoss((8+4*lv)*dm*db);} + for(const e of G.enemies)if(!e.dead&&dist2(S.x,S.y,e.x,e.y)<(e.r+12)*(e.r+12)&&G.time-(e.ramT||0)>18){e.ramT=G.time;hurtEnemy(e,(20+12*lv)*dm*db,true);} + if(G.boss&&bossHit(S.x,S.y,12)&&G.time-(G.boss.ramT||0)>18){G.boss.ramT=G.time;hurtBoss((20+12*lv)*dm*db);} break;} - case "heal": if(S.t<=0){S.t=(40-6*lv)*60; - if(G.hp0){S.sw--; - if(S.sw%2===0){const pr=1-S.sw/14,sa=-Math.PI/2+(pr-0.5)*1.5*(S.dir||1); - pbul(S.x,S.y,Math.cos(sa)*5.2,Math.sin(sa)*5.2,(3+1.5*lv)*dm*db,{r:2,spr:"swep"});} - }else if(S.t<=0){S.dir=S.dir===1?-1:1;S.sw=14;S.t=Math.max(50,(110-8*lv)/fm);} - break; + if(dist2(S.x,S.y,b.x,b.y)<130){b.dead=true;spawnPart(b.x,b.y,"#43e8ff",2);}}break; + case "missile": if(S.t<=0){S.t=(80-10*lv)/fm; + pbul(S.x,S.y,rnd(-0.6,0.6),-2.8,(18+10*lv)*dm*db,{t:"m",spr:"dMsl",homing:true,r:4,aoe:18+6*lv,trailCol:"#ffb84d"});}break; + case "bladeD": if(S.t<=0){S.t=(55-5*lv)/fm; + pbul(S.x,S.y,0,-4,(16+9*lv)*dm*db,{t:"b",spr:"blade",pierce:true,back:true,r:4,bt:34});}break; } } } diff --git a/star-raid/js/data.js b/star-raid/js/data.js index 3818197..0db7a3f 100644 --- a/star-raid/js/data.js +++ b/star-raid/js/data.js @@ -12,62 +12,67 @@ const SHIPS={ asura:{name:"修罗",spr:"ship4",cost:5000,trait:"暴击+15% · 伤害+10% · 命-1", mod:{spd:1,dmg:1.1,lives:-1,crit:0.15,dodge:0,hitR:0,mag:1,bombs:1,shield:0,drone:0,droneBoost:1}} }; -/* ================= 军械库:25 主武器 ================= +/* ================= 军械库:27 主武器 ================= beh: 行为引擎类型 lvl(w): 该等级的战斗参数 */ const WEAPONS={ vulcan:{name:"火神机炮",spr:"trcr",rare:0,beh:"streams",ds:"!?神神?!", - lvl:w=>({n:1+Math.floor(w/2),dmg:7*(1+.22*(w-1)),int:8,spd:5.4,gap:6})}, + lvl:w=>({n:1+Math.floor(w/2),dmg:9*(1+.22*(w-1)),int:8,spd:5.4,gap:6})}, shotgun:{name:"超级霰弹",spr:"pelt",rare:0,beh:"streams",ds:"“友谊颗粒”", - lvl:w=>({n:5+2*w,dmg:4.2*(1+.18*(w-1)),int:22,spd:5.5,fan:0.5,gap:2,skipMid:1})}, - needle:{name:"蜂针刺弹",spr:"ndl",rare:0,beh:"streams",ds:"这可是吐了剧毒的飞刀", - lvl:w=>({n:1+Math.floor(w/3),dmg:2.6*(1+.2*(w-1)),int:3,spd:7,gap:4,poison:100})}, + lvl:w=>({n:5+2*w,dmg:5*(1+.18*(w-1)),int:22,spd:5.5,fan:0.5,gap:2,skipMid:1})}, + needle:{name:"蜂针刺弹",spr:"ndl",rare:0,beh:"needle",ds:"这可是吐了剧毒的飞刀", + lvl:w=>({n:1+Math.floor(w/3),dmg:7.8*(1+.2*(w-1)),int:3,spd:7,gap:4,poison:100})}, flame:{name:"火焰喷射器",icon:"flame",rare:0,beh:"flame",ds:"让火焰净化一切", - lvl:w=>({n:3+Math.floor(w/2),dmg:1.1*(1+.22*(w-1)),range:70+8*w,burst:34+4*w,cd:Math.max(46,74-5*w)})}, + lvl:w=>({n:3+Math.floor(w/2),dmg:1.2*(1+.22*(w-1)),range:90+8*w,burst:44+4*w,cd:Math.max(40,74-5*w)})}, shotgun2:{name:"霜冻霰弹",spr:"shard",rare:1,beh:"streams",ds:"冷冷冷", - lvl:w=>({n:3+w,dmg:3*(1+.18*(w-1)),int:23,spd:5.2,fan:0.42,gap:2,slow:80+25*w})}, + lvl:w=>({n:3+w,dmg:3.2*(1+.18*(w-1)),int:23,spd:5.2,fan:0.42,gap:2,slow:80+25*w})}, tesla:{name:"电弧发生器",icon:"chain",rare:1,beh:"tesla",ds:"?!电电!?", - lvl:w=>({n:1+Math.floor(w/2),dmg:8*(1+.25*(w-1)),int:44-2*w,range:110})}, + lvl:w=>({n:1+Math.floor(w/2),dmg:11*(1+.25*(w-1)),int:44-2*w,range:110})}, railgun:{name:"电磁炮",icon:"rail",rare:2,beh:"rail",ds:"带轮子的垃圾桶", - lvl:w=>({dmg:55*(1+.3*(w-1)),charge:120-10*w,spd:11,zone:24+4*w})}, + lvl:w=>({dmg:70*(1+.3*(w-1)),charge:120-10*w,spd:11,zone:24+4*w})}, deathray:{name:"死光",icon:"laser",rare:2,beh:"deathray",ds:"记得带镜子", - lvl:w=>({dps:0.9*(1+.28*(w-1)),charge:160-12*w,beam:55,width:5+2*w})}, + lvl:w=>({dps:1.2*(1+.28*(w-1)),charge:160-12*w,beam:55,width:5+2*w})}, crescent:{name:"月牙斩",spr:"cres",rare:1,beh:"crescent",ds:"青豆?", - lvl:w=>({dmg:44*(1+.24*(w-1)),int:120,spd:3.4})}, + lvl:w=>({dmg:44*(1+.24*(w-1)),int:60,spd:3.4,hits:3})}, fission:{name:"分裂弹",spr:"fiss",rare:1,beh:"fission",ds:"四阶村长", - lvl:w=>({dmg:6*(1+.22*(w-1)),int:20,spd:5.2,split:3+Math.floor(w/2),splitAt:26})}, + lvl:w=>({dmg:7*(1+.22*(w-1)),int:20,spd:5.2,split:3+Math.floor(w/2),splitAt:26})}, frost:{name:"冰冻枪",spr:"icelance",rare:1,beh:"frost",ds:"冷冷冷冷", - lvl:w=>({dmg:6*(1+.2*(w-1)),int:16,spd:6,freeze:70+25*w})}, + lvl:w=>({dmg:10*(1+.2*(w-1)),int:13,spd:6,freeze:70+25*w})}, swarm:{name:"蜂巢导弹",spr:"msl2",rare:1,beh:"homing",ds:"不可用于对付肉山", - lvl:w=>({n:1+w,dmg:2.2*(1+.2*(w-1)),int:22,spd:3.2,aoe:10})}, + lvl:w=>({n:1+w,dmg:2.5*(1+.2*(w-1)),int:22,spd:3.2,aoe:10})}, bubble:{name:"重力泡泡",spr:"bub",rare:1,beh:"bubble",ds:"天呐!是海绵宝宝", - lvl:w=>({dmg:18*(1+.25*(w-1)),int:26,spd:1.4,aoe:30+4*w})}, + lvl:w=>({dmg:90*(1+.25*(w-1)),int:26,spd:1.4,aoe:30+4*w})}, starfall:{name:"流星火雨",spr:"met",rare:2,beh:"starfall",ds:"天火", lvl:w=>({n:3+Math.floor(w/2),dmg:16*(1+.25*(w-1)),int:150-8*w,aoe:16})}, boomerang:{name:"回旋镖",spr:"boomer",rare:0,beh:"boom",ds:"但愿不会打到自己", - lvl:w=>({n:1+Math.floor(w/2),dmg:7*(1+.22*(w-1)),int:21,spd:4.8})}, + lvl:w=>({n:1+Math.floor(w/2),dmg:9*(1+.22*(w-1)),int:21,spd:4.8})}, singularity:{name:"奇点炮",spr:"sing",rare:2,beh:"sing",ds:"雷工蛋?", - lvl:w=>({dmg:120*(1+.3*(w-1)),int:200,pull:88,aoe:62,fuse:160})}, // 伤害×3(2026-08-06) // 牵引/爆炸范围与射程增强 + lvl:w=>({dmg:120*(1+.3*(w-1)),int:200,pull:88,aoe:62,fuse:160})}, wavecannon:{name:"波动炮",spr:"waveb",rare:2,beh:"wave",ds:"炼狱无双波动炮", lvl:w=>({dmg:32*(1+.3*(w-1)),charge:100-8*w,spd:5,width:14+6*w})}, holy:{name:"圣光弹",spr:"holyo",rare:2,beh:"holy",ds:"哇哦", - lvl:w=>({dmg:26*(1+.25*(w-1)),int:65,spd:3,len:16+3*w})}, // 伤害×2(2026-08-06) + lvl:w=>({dmg:130*(1+.25*(w-1)),int:65,spd:3,len:16+3*w})}, thundercall:{name:"落雷术",spr:"thnd",rare:1,beh:"thunder",ds:"何方道友在此渡劫", lvl:w=>({n:2+Math.floor(w/2),dmg:12*(1+.25*(w-1)),int:90-4*w,aoe:13})}, arcshu:{name:"电弧手里剑",spr:"shuri",rare:2,beh:"shuriken",ds:"这个很熟悉了吧", - lvl:w=>({dmg:6*(1+.22*(w-1)),int:95-4*w,spd:2.2,zapDmg:5*(1+.25*(w-1)),pulse:7})}, // 电弧释放速度×3 + lvl:w=>({dmg:7*(1+.22*(w-1)),int:95-4*w,spd:2.2,zapDmg:6*(1+.25*(w-1)),pulse:7,deflect:0.04})}, volt:{name:"电能机炮",spr:"voltb",rare:1,beh:"volt",ds:"疑似电大", - lvl:w=>({n:1+Math.floor(w/3),dmg:3.2*(1+.2*(w-1)),int:5,spd:6.2,gap:5,chain:2+Math.floor(w/2)})}, + lvl:w=>({n:1+Math.floor(w/3),dmg:4.5*(1+.2*(w-1)),int:5,spd:6.2,gap:5,chain:2+Math.floor(w/2)})}, dawn:{name:"黎明重炮",spr:"dawnsh",rare:2,beh:"dawn",ds:"祖宗发射器", lvl:w=>({dmg:70*(1+.3*(w-1)),charge:170-12*w,spd:5,aoe:30+3*w})}, proto:{name:"协议武装",spr:"protb",rare:2,beh:"protocol",ds:"搜索,歼灭", lvl:w=>({dmg:3*(1+.2*(w-1)),int:6,spd:6.5,heavy:120-8*w,hdmg:36*(1+.28*(w-1)),haoe:26+3*w})}, nebula:{name:"星云奥秘",spr:"neb",rare:2,beh:"nebula",ds:"字面意思", - lvl:w=>({dmg:12*(1+.25*(w-1)),int:100-5*w,spd:1.6,stars:10+2*w})}, + lvl:w=>({dmg:14*(1+.25*(w-1)),int:100-5*w,spd:1.6,stars:10+2*w})}, loiter:{name:"巡飞弹",spr:"loms",rare:1,beh:"loiter",ds:"堵桥来", - lvl:w=>({dmg:22*(1+.25*(w-1)),int:68-5*w,spd:4.2,zone:20+3*w,fire:95+15*w})} + lvl:w=>({dmg:22*(1+.25*(w-1)),int:68-5*w,spd:4.2,zone:20+3*w,fire:95+15*w})}, + beegrenade:{name:"蜜蜂手雷",spr:"beegrenade",rare:1,beh:"beegrenade",ds:"嗡嗡嗡", + lvl:w=>({n:2,dmg:10*(1+.25*(w-1)),beeDmg:4*(1+.25*(w-1)),int:55-4*w,spd:3.2,aoe:18,bees:5,fuse:40})}, + chlorophyte:{name:"叶绿弹",spr:"chloro",rare:1,beh:"chlorophyte",ds:"丛林之怒", + lvl:w=>({n:1+Math.floor(w/2),dmg:4*(1+.2*(w-1)),int:10,spd:5.2,gap:5})} }; const MAINS=Object.keys(WEAPONS); -/* ================= 18 副武器 ================= */ +/* ================= 15 副武器 ================= + 爆发/控场/防御;分类原则:一次性大范围或长CD特效 */ const SUBS={ broad:{name:"侧舷火炮",spr:"broad",rare:0,max:5,beh:"broad",ds:l=>`舷炮斜向前方45°齐射,Lv${l+1}`}, sweep:{name:"探照扫射",icon:"laser",rare:1,max:5,beh:"sweep",ds:l=>`往复摆动的扫描光束,Lv${l+1}`}, @@ -78,31 +83,27 @@ const SUBS={ slowfield:{name:"时间力场",spr:"grv",rare:2,max:3,beh:"slowfield",ds:l=>"力场内敌人与敌弹大幅减速,Lv"+(l+1)}, flares:{name:"热诱弹舱",spr:"flare",rare:0,max:4,beh:"flares",ds:l=>"扇形抛射4枚缓速热诱弹,各诱爆一枚敌弹,Lv"+(l+1)}, seeker:{name:"索敌浮游炮",spr:"dGun2",rare:1,max:3,beh:"seeker",ds:l=>"离机索敌的浮游炮,Lv"+(l+1)}, - beamdrone:{name:"光束浮游炮",spr:"dBeam",rare:2,max:3,beh:"beamdrone",ds:l=>"环绕发射光束的浮游单元,Lv"+(l+1)}, frostnova:{name:"冰霜新星",spr:"frost",rare:1,max:3,beh:"frostnova",ds:l=>"周期性冻结周围敌人,Lv"+(l+1)}, thorns:{name:"反伤棘甲",icon:"crit",rare:1,max:3,beh:"thorns",ds:l=>"撞击你的敌人遭到反噬,Lv"+(l+1)}, sticky:{name:"粘着炸弹",spr:"sticky",rare:0,max:3,beh:"sticky",ds:l=>"粘附敌人的定时高爆炸弹,Lv"+(l+1)}, magnetar:{name:"磁暴环",icon:"mag",rare:2,max:3,beh:"magnetar",ds:l=>"周期性电磁脉冲,消弹伤敌,Lv"+(l+1)}, executor:{name:"斩首巡航弹",spr:"cmsl",rare:2,max:3,beh:"executor",ds:l=>"巡航导弹猎杀最强之敌,Lv"+(l+1)}, - airstrike:{name:"空爆弹",spr:"amsl",rare:1,max:5,beh:"airstrike",ds:l=>"双弹侧掠折向直上,穿透机身沿途轰炸,Lv"+(l+1)}, - repair:{name:"修复无人机",spr:"dHeal",rare:1,max:3,beh:"repair",ds:l=>"持续修复机体结构,Lv"+(l+1)} + airstrike:{name:"空爆弹",spr:"amsl",rare:1,max:5,beh:"airstrike",ds:l=>"双弹侧掠折向直上,穿透机身沿途轰炸,Lv"+(l+1)} }; const SUB_KEYS=Object.keys(SUBS); -/* ================= 12 僚机 ================= */ +/* ================= 10 僚机 ================= + 自动跟随/持续输出;全部获得伤害与功能强化 */ const DRONES={ - gunner:{name:"机枪僚机",spr:"dGun",rare:0,max:3,beh:"aim",ds:l=>"协同瞄准射击,Lv"+(l+1)}, - gunner2:{name:"双翼机枪手",spr:"dGun2",rare:1,max:3,beh:"aim2",ds:l=>"双管僚机,Lv"+(l+1)}, - sniperd:{name:"狙击僚机",spr:"dSnip",rare:1,max:3,beh:"snipe",ds:l=>"高伤点射,Lv"+(l+1)}, + gunner:{name:"机枪僚机",spr:"dGun",rare:0,max:3,beh:"burst",ds:l=>"高速连射+随机散布,Lv"+(l+1)}, + gunner2:{name:"双翼机枪手",spr:"dGun2",rare:1,max:3,beh:"burst2",ds:l=>"双管高速连射,Lv"+(l+1)}, + sniperd:{name:"狙击僚机",spr:"dSnip",rare:1,max:3,beh:"snipe",ds:l=>"自瞄高伤穿透弹,Lv"+(l+1)}, beamer:{name:"光束僚机",spr:"dBeam",rare:2,max:3,beh:"beam",ds:l=>"周期光束,Lv"+(l+1)}, bomber:{name:"轰炸僚机",spr:"dBomb",rare:1,max:3,beh:"bomb",ds:l=>"投掷爆炸弹,Lv"+(l+1)}, - frostd:{name:"冰霜僚机",spr:"dFrost",rare:1,max:3,beh:"frostD",ds:l=>"减速弹,Lv"+(l+1)}, - teslaD:{name:"电弧僚机",spr:"dTesla",rare:2,max:3,beh:"teslaD",ds:l=>"近身电击,Lv"+(l+1)}, rammer:{name:"冲撞僚机",spr:"dRam",rare:1,max:3,beh:"melee",big:1.6,ds:l=>"高速环绕撞击,Lv"+(l+1)}, - healer:{name:"修复僚机",spr:"dHeal",rare:1,max:3,beh:"heal",ds:l=>"缓慢回复结构值,Lv"+(l+1)}, + healer:{name:"修复僚机",spr:"dHeal",rare:1,max:3,beh:"heal",ds:l=>"持续修复机体结构,Lv"+(l+1)}, shieldd:{name:"护盾僚机",spr:"dShield",rare:2,max:3,beh:"block",big:1.5,ds:l=>"环绕格挡敌弹,Lv"+(l+1)}, - missileD:{name:"导弹僚机",spr:"dMsl",rare:1,max:3,beh:"missile",ds:l=>"追踪导弹,Lv"+(l+1)}, - bladeD:{name:"刃舞僚机",spr:"dBlade",rare:1,max:3,beh:"bladeD",ds:l=>"投掷回旋刃,Lv"+(l+1)}, - sweeper:{name:"扫射僚机",spr:"dSweep",rare:1,max:3,beh:"sweep",ds:l=>"扇形区域来回扫射,火力覆盖,Lv"+(l+1)} + missileD:{name:"导弹僚机",spr:"dMsl",rare:1,max:3,beh:"missile",ds:l=>"追踪导弹+大范围爆炸,Lv"+(l+1)}, + bladeD:{name:"刃舞僚机",spr:"dBlade",rare:1,max:3,beh:"bladeD",ds:l=>"投掷回旋刃,Lv"+(l+1)} }; const DRONE_KEYS=Object.keys(DRONES); /* ================= 8 被动强化 ================= */ diff --git a/star-raid/js/enemies.js b/star-raid/js/enemies.js index c4add24..1b68225 100644 --- a/star-raid/js/enemies.js +++ b/star-raid/js/enemies.js @@ -67,7 +67,7 @@ function updateEnemy(e){ if(e.hp<=0){killEnemy(e);return;} if(e.dot.t<=0)e.dot=null;} if(e.leech){e.leech.t--;e.hp-=e.leech.dps/60; // 寄生电浆:吸血 - G.hp=Math.min(G.maxHp,G.hp+e.leech.dps*0.3/60); + healPlayer(e.leech.dps*0.3/60,true); if(G.time%10===0)G.parts.push({x:e.x,y:e.y,vx:0,vy:0,life:12,col:"#b05ce8",sz:1,suck:{x:G.p.x,y:G.p.y}}); if(e.hp<=0){killEnemy(e);return;} if(e.leech.t<=0)e.leech=null;} diff --git a/star-raid/js/render.js b/star-raid/js/render.js index df55e93..5ab6b22 100644 --- a/star-raid/js/render.js +++ b/star-raid/js/render.js @@ -396,7 +396,6 @@ function render(){ if(G.subLoadout.includes("sats")){const n=1+G.subs.sats; for(let i=0;i0.5?"#5cff9d":pc2>0.25?"#ffcf5c":"#ff5566"); + if(G.healFlash>0){G.healFlash--; + ctx.globalAlpha=0.35+0.45*(G.healFlash/40); + px(5,H-11,hpw*pc2,4,"#5cff9d"); + ctx.globalAlpha=0.9+0.1*Math.sin(G.time*0.4); + ctx.fillStyle="#5cff9d";ctx.font="6px 'Press Start 2P',monospace";ctx.textAlign="left"; + ctx.fillText("+"+Math.round(G.healAmt),5,H-16); + ctx.globalAlpha=1; + if(G.healFlash<=0)G.healAmt=0;} for(let i=0;i