ymo2017 commited on
Commit
db7082b
·
verified ·
1 Parent(s): 08b4bc4

进化轮3项:敌机铆钉纹理/扫雷抛光亮面/金苹果成熟度红晕

Browse files
Files changed (3) hide show
  1. minesweeper.html +16 -1
  2. snake.html +16 -0
  3. star-shooter.html +13 -0
minesweeper.html CHANGED
@@ -151,6 +151,11 @@ const MS_RUST=new Image(); let MS_RUST_OK=false;
151
  MS_RUST.onload=()=>{ MS_RUST_OK=true; };
152
  MS_RUST.onerror=()=>{ MS_RUST_OK=false; };
153
  MS_RUST.src='art/ms-rust.webp';
 
 
 
 
 
154
  /* 数字格开盖铜粉碎屑贴图(纯表现层,加载失败自动跳过) */
155
  const MS_COPF=new Image(); let MS_COPF_OK=false;
156
  MS_COPF.onload=()=>{ MS_COPF_OK=true; };
@@ -314,7 +319,7 @@ function reset(){
314
  G.board=[];
315
  for(let y=0;y<G.rows;y++){
316
  const row=[];
317
- for(let x=0;x<G.cols;x++) row.push({mine:false,open:false,flag:false,n:0,dead:false,rust:Math.random()<0.2?(1+Math.floor(Math.random()*4)):0,warmth:(Math.random()*3)|0});
318
  G.board.push(row);
319
  }
320
  G.state='playing'; G.paused=false; G.started=false;
@@ -651,6 +656,13 @@ function draw(){
651
  ctx.drawImage(MS_RUST,-G.cell/2,-G.cell/2,G.cell,G.cell);
652
  ctx.restore();
653
  }
 
 
 
 
 
 
 
654
  if(c.flag) drawFlagIcon(px,py,flagPopScale(c),flagWave(c));
655
  }
656
  ctx.strokeStyle='rgba(255,200,120,.14)';
@@ -1094,6 +1106,9 @@ window.__ms={G:G,
1094
  craterDraws(){ return window.__craterDraws||0; },
1095
  openRivetDraws(){ return window.__openRivetDraws||0; },
1096
  warmthDraws(){ return window.__warmthDraws||0; },
 
 
 
1097
  flagAt(x,y){ flagCell(x,y); const c=G.board[y][x]; return !!(c&&c.flag); },
1098
  flagAge(x,y){ const c=G.board[y][x]; return c&&c.flagT?(performance.now()-c.flagT):-1; }
1099
  };
 
151
  MS_RUST.onload=()=>{ MS_RUST_OK=true; };
152
  MS_RUST.onerror=()=>{ MS_RUST_OK=false; };
153
  MS_RUST.src='art/ms-rust.webp';
154
+ /* 未翻开格抛光亮面贴图:每局随机约8%的铆钉盖顶部叠加抛光亮斑(纯表现层:常被踩踏磨亮的盖子,与锈斑/色温差异化叠加;加载失败自动跳过,不改逻辑) */
155
+ const MS_SHINE=new Image(); let MS_SHINE_OK=false;
156
+ MS_SHINE.onload=()=>{ MS_SHINE_OK=true; };
157
+ MS_SHINE.onerror=()=>{ MS_SHINE_OK=false; };
158
+ MS_SHINE.src='art/ms-shine.webp';
159
  /* 数字格开盖铜粉碎屑贴图(纯表现层,加载失败自动跳过) */
160
  const MS_COPF=new Image(); let MS_COPF_OK=false;
161
  MS_COPF.onload=()=>{ MS_COPF_OK=true; };
 
319
  G.board=[];
320
  for(let y=0;y<G.rows;y++){
321
  const row=[];
322
+ for(let x=0;x<G.cols;x++) row.push({mine:false,open:false,flag:false,n:0,dead:false,rust:Math.random()<0.2?(1+Math.floor(Math.random()*4)):0,warmth:(Math.random()*3)|0,shine:Math.random()<0.08?1:0});
323
  G.board.push(row);
324
  }
325
  G.state='playing'; G.paused=false; G.started=false;
 
656
  ctx.drawImage(MS_RUST,-G.cell/2,-G.cell/2,G.cell,G.cell);
657
  ctx.restore();
658
  }
659
+ /* 磨光亮面(纯表现层:约8%的未翻开格铆钉盖顶部叠加抛光亮斑,与锈斑/色温差异化叠加,不改逻辑) */
660
+ if(c.shine&&MS_SHINE_OK&&MS_SHINE.naturalWidth){
661
+ ctx.save(); ctx.globalAlpha=0.75;
662
+ ctx.drawImage(MS_SHINE,px+0.5,py+0.5,G.cell-1,G.cell-1);
663
+ ctx.restore();
664
+ window.__shineDraws=(window.__shineDraws||0)+1; // 探针:抛光亮面确实绘制
665
+ }
666
  if(c.flag) drawFlagIcon(px,py,flagPopScale(c),flagWave(c));
667
  }
668
  ctx.strokeStyle='rgba(255,200,120,.14)';
 
1106
  craterDraws(){ return window.__craterDraws||0; },
1107
  openRivetDraws(){ return window.__openRivetDraws||0; },
1108
  warmthDraws(){ return window.__warmthDraws||0; },
1109
+ shineOk(){ return MS_SHINE_OK&&MS_SHINE.naturalWidth>0; },
1110
+ shineDraws(){ return window.__shineDraws||0; },
1111
+ shineCount(){ let n=0; for(const r of G.board) for(const c of r) if(c.shine) n++; return n; },
1112
  flagAt(x,y){ flagCell(x,y); const c=G.board[y][x]; return !!(c&&c.flag); },
1113
  flagAge(x,y){ const c=G.board[y][x]; return c&&c.flagT?(performance.now()-c.flagT):-1; }
1114
  };
snake.html CHANGED
@@ -149,6 +149,11 @@ const SN_GOLDPATCH=new Image(); let SN_GOLDPATCH_OK=false;
149
  SN_GOLDPATCH.onload=()=>{ SN_GOLDPATCH_OK=true; };
150
  SN_GOLDPATCH.onerror=()=>{ SN_GOLDPATCH_OK=false; };
151
  SN_GOLDPATCH.src='art/sn-goldpatch.webp';
 
 
 
 
 
152
  /* 金苹果果蒂叶贴图(纯表现层:金苹果顶部叠加果蒂叶贴图、随苹果脉冲同呼吸,加载失败跳过、红果不画;不改玩法/碰撞) */
153
  const SN_LEAF=new Image(); let SN_LEAF_OK=false;
154
  SN_LEAF.onload=()=>{ SN_LEAF_OK=true; };
@@ -284,6 +289,7 @@ function spawnFood(){
284
  if(!free.length){ G.food=null; return; }
285
  G.food=free[(Math.random()*free.length)|0];
286
  G.food.gold=Math.random()<0.18; // 金苹果:纯表现层视觉变体,得分/速度/碰撞完全不变
 
287
  /* 新食物涟漪提示(纯表现层:刷新处扩散小光圈 0.6 秒后消退,不改玩法/碰撞) */
288
  const cx0=OX+G.food.x*CELL+CELL/2, cy0=OY+G.food.y*CELL+CELL/2;
289
  rings.push({x:cx0,y:cy0,r:4,maxR:CELL*1.35,t:0,life:0.6,c:G.food.gold?'255,215,106':'255,255,220'});
@@ -537,6 +543,13 @@ function draw(){
537
  }
538
  const s=CELL*1.7*pulse*(gold?1.1:1.0);
539
  ctx.drawImage(_appleImg,fx+CELL/2-s/2,fy+CELL/2-s/2,s,s);
 
 
 
 
 
 
 
540
  if(gold) window.__snakeGoldDraws=(window.__snakeGoldDraws||0)+1; // 探针:金苹果确实绘制
541
  if(gold&&SN_LEAF_OK&&SN_LEAF.naturalWidth){ // 果蒂叶(纯表现层:金苹果顶部叶贴图,随苹果脉冲同呼吸+微摆;加载失败跳过,不改玩法/碰撞)
542
  const ls=CELL*1.05;
@@ -952,6 +965,9 @@ window.__snake={G:G,
952
  leafOk(){ return SN_LEAF_OK&&SN_LEAF.naturalWidth>0; },
953
  leafDraws(){ return window.__snakeLeafDraws||0; },
954
  foodShadowDraws(){ return window.__snakeFoodShadowDraws||0; },
 
 
 
955
  foodGold(){ return !!(G.food&&G.food.gold); },
956
  score(){ return G.score; },
957
  state(){ return G.state; }
 
149
  SN_GOLDPATCH.onload=()=>{ SN_GOLDPATCH_OK=true; };
150
  SN_GOLDPATCH.onerror=()=>{ SN_GOLDPATCH_OK=false; };
151
  SN_GOLDPATCH.src='art/sn-goldpatch.webp';
152
+ /* 金苹果成熟度红晕(纯表现层:存活越久果面红晕越重(20秒封顶),成熟度图像化;加载失败跳过,不改玩法/碰撞) */
153
+ const SN_BLUSH=new Image(); let SN_BLUSH_OK=false;
154
+ SN_BLUSH.onload=()=>{ SN_BLUSH_OK=true; };
155
+ SN_BLUSH.onerror=()=>{ SN_BLUSH_OK=false; };
156
+ SN_BLUSH.src='art/sn-blush.webp';
157
  /* 金苹果果蒂叶贴图(纯表现层:金苹果顶部叠加果蒂叶贴图、随苹果脉冲同呼吸,加载失败跳过、红果不画;不改玩法/碰撞) */
158
  const SN_LEAF=new Image(); let SN_LEAF_OK=false;
159
  SN_LEAF.onload=()=>{ SN_LEAF_OK=true; };
 
289
  if(!free.length){ G.food=null; return; }
290
  G.food=free[(Math.random()*free.length)|0];
291
  G.food.gold=Math.random()<0.18; // 金苹果:纯表现层视觉变体,得分/速度/碰撞完全不变
292
+ G.food.bornT=performance.now(); // 食物出生时间(纯表现层:金苹果成熟度红晕计时)
293
  /* 新食物涟漪提示(纯表现层:刷新处扩散小光圈 0.6 秒后消退,不改玩法/碰撞) */
294
  const cx0=OX+G.food.x*CELL+CELL/2, cy0=OY+G.food.y*CELL+CELL/2;
295
  rings.push({x:cx0,y:cy0,r:4,maxR:CELL*1.35,t:0,life:0.6,c:G.food.gold?'255,215,106':'255,255,220'});
 
543
  }
544
  const s=CELL*1.7*pulse*(gold?1.1:1.0);
545
  ctx.drawImage(_appleImg,fx+CELL/2-s/2,fy+CELL/2-s/2,s,s);
546
+ if(gold&&SN_BLUSH_OK&&SN_BLUSH.naturalWidth){ // 金苹果成熟度红晕(纯表现层:存活越久红晕越重、20秒封顶,与金色草皮光斑/光环叠加不冲突;红果不画;加载失败跳过,不改玩法/碰撞)
547
+ const mat=Math.min(1,(performance.now()-((G.food&&G.food.bornT)||performance.now()))/20000);
548
+ ctx.save(); ctx.globalAlpha=(0.15+0.65*mat).toFixed(2);
549
+ ctx.drawImage(SN_BLUSH,fx+CELL/2-s/2,fy+CELL/2-s/2,s,s);
550
+ ctx.restore();
551
+ window.__snakeBlushDraws=(window.__snakeBlushDraws||0)+1; // 探针:成熟度红晕确实绘制
552
+ }
553
  if(gold) window.__snakeGoldDraws=(window.__snakeGoldDraws||0)+1; // 探针:金苹果确实绘制
554
  if(gold&&SN_LEAF_OK&&SN_LEAF.naturalWidth){ // 果蒂叶(纯表现层:金苹果顶部叶贴图,随苹果脉冲同呼吸+微摆;加载失败跳过,不改玩法/碰撞)
555
  const ls=CELL*1.05;
 
965
  leafOk(){ return SN_LEAF_OK&&SN_LEAF.naturalWidth>0; },
966
  leafDraws(){ return window.__snakeLeafDraws||0; },
967
  foodShadowDraws(){ return window.__snakeFoodShadowDraws||0; },
968
+ blushOk(){ return SN_BLUSH_OK&&SN_BLUSH.naturalWidth>0; },
969
+ blushDraws(){ return window.__snakeBlushDraws||0; },
970
+ blushMat(){ if(!(G.food&&G.food.gold)) return -1; return Math.min(1,(performance.now()-((G.food&&G.food.bornT)||performance.now()))/20000); },
971
  foodGold(){ return !!(G.food&&G.food.gold); },
972
  score(){ return G.score; },
973
  state(){ return G.state; }
star-shooter.html CHANGED
@@ -324,7 +324,9 @@ for (const k of ['ship', 'diver', 'weaver', 'tank', 'elite', 'boss']) {
324
  function sprReady(k) { const i = SPR[k]; return !!(i && i.complete && i.naturalWidth > 0); }
325
  const dmgTex=new Image(); dmgTex.src='art/ss-damage.webp'; // 敌机受损焦痕贴图(加载失败自动跳过)
326
  const enemyFlameTex=new Image(); enemyFlameTex.src='art/ss-enemy-flame.webp'; // 敌机尾焰贴图(绯红/橙、与玩家青白尾焰敌我区分,加载失败自动跳过)
 
327
  window.__enemyFlameDraws=0; // 敌机尾焰绘制计数(纯表现层探针)
 
328
  window.__dmgTex=dmgTex;
329
  const smokeTex=new Image(); smokeTex.src='art/ss-smoke.webp'; // 玩家飞船受损机翼焦烟贴图(加载失败自动跳过)
330
  window.__smokeTex=smokeTex; window.__smokeDraws=0;
@@ -841,6 +843,14 @@ function drawEnemy(e) {
841
  if (e.type === 'elite') ctx.rotate(e.t * 0.5); // 保持原旋转感
842
  else if (e.type === 'boss') ctx.rotate(Math.sin(e.t * 0.8) * 0.1);
843
  ctx.drawImage(SPR[e.type], -S / 2, -S / 2, S, S);
 
 
 
 
 
 
 
 
844
  if (e.flash > 0) { // 受击闪白
845
  ctx.globalAlpha = 0.45;
846
  ctx.fillStyle = '#ffffff';
@@ -1481,6 +1491,9 @@ window.gameDebug = {
1481
  return !!b;
1482
  },
1483
  bossLowWarned: () => { const b = enemies.find((e) => e.type === 'boss'); return b ? !!b.lowWarned : null; },
 
 
 
1484
  killEliteForProbe: () => { // 探针用:生成一只精英怪并立即击破,验证残骸生成
1485
  spawnEnemy('elite');
1486
  const e = enemies[enemies.length - 1];
 
324
  function sprReady(k) { const i = SPR[k]; return !!(i && i.complete && i.naturalWidth > 0); }
325
  const dmgTex=new Image(); dmgTex.src='art/ss-damage.webp'; // 敌机受损焦痕贴图(加载失败自动跳过)
326
  const enemyFlameTex=new Image(); enemyFlameTex.src='art/ss-enemy-flame.webp'; // 敌机尾焰贴图(绯红/橙、与玩家青白尾焰敌我区分,加载失败自动跳过)
327
+ const rivetTex=new Image(); rivetTex.src='art/ss-rivets.webp'; // 敌机装甲铆钉/焊缝纹理(纯表现层:5 种敌机装甲精灵叠加铆钉纹理差异化,与焦痕/尾焰叠加不冲突,加载失败跳过,不改伤害/血量)
328
  window.__enemyFlameDraws=0; // 敌机尾焰绘制计数(纯表现层探针)
329
+ window.__rivetTex=rivetTex; window.__rivetDraws=0; // 敌机装甲铆钉绘制计数(纯表现层探针)
330
  window.__dmgTex=dmgTex;
331
  const smokeTex=new Image(); smokeTex.src='art/ss-smoke.webp'; // 玩家飞船受损机翼焦烟贴图(加载失败自动跳过)
332
  window.__smokeTex=smokeTex; window.__smokeDraws=0;
 
843
  if (e.type === 'elite') ctx.rotate(e.t * 0.5); // 保持原旋转感
844
  else if (e.type === 'boss') ctx.rotate(Math.sin(e.t * 0.8) * 0.1);
845
  ctx.drawImage(SPR[e.type], -S / 2, -S / 2, S, S);
846
+ if (rivetTex.complete && rivetTex.naturalWidth) { // 装甲铆钉纹理:纯表现层,每种敌机固定旋转角差异,与焦痕层叠加不冲突,加载失败跳过
847
+ ctx.save();
848
+ ctx.globalAlpha = 0.55;
849
+ ctx.rotate({diver:0,weaver:0.6,tank:1.2,elite:1.8,boss:2.4}[e.type]||0);
850
+ ctx.drawImage(rivetTex, -S / 2, -S / 2, S, S);
851
+ ctx.restore();
852
+ window.__rivetDraws++;
853
+ }
854
  if (e.flash > 0) { // 受击闪白
855
  ctx.globalAlpha = 0.45;
856
  ctx.fillStyle = '#ffffff';
 
1491
  return !!b;
1492
  },
1493
  bossLowWarned: () => { const b = enemies.find((e) => e.type === 'boss'); return b ? !!b.lowWarned : null; },
1494
+ spawnAllTypes: () => { ['diver','weaver','tank','elite','boss'].forEach(spawnEnemy); }, // 探针用:5 种敌机各生成一只(验证铆钉纹理差异化)
1495
+ rivetTexOk: () => rivetTex.complete && rivetTex.naturalWidth > 0,
1496
+ rivetDraws: () => window.__rivetDraws,
1497
  killEliteForProbe: () => { // 探针用:生成一只精英怪并立即击破,验证残骸生成
1498
  spawnEnemy('elite');
1499
  const e = enemies[enemies.length - 1];