SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="theme-color" content="#05101a">
<title>小鲸鱼大冒险</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
  html, body {
    width: 100%; height: 100%; overflow: hidden;
    background: #05101a; touch-action: none;
    font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
    user-select: none; -webkit-user-select: none;
  }
  canvas { display: block; width: 100vw; height: 100vh; }
  #ui {
    position: fixed; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; color: #fff;
    background: rgba(5, 16, 26, 0.85); backdrop-filter: blur(4px);
    transition: opacity 0.3s; pointer-events: none; opacity: 1;
  }
  #ui.hide { opacity: 0; pointer-events: none; }
  #ui h1 { font-size: 28px; margin-bottom: 10px; color: #8FE3FF; text-shadow: 0 2px 10px rgba(143, 227, 255, 0.3); }
  #ui p { font-size: 15px; color: #9cb8cc; margin-bottom: 30px; text-align: center; line-height: 1.6; padding: 0 20px; }
  #ui button {
    padding: 14px 40px; font-size: 18px; font-weight: bold; color: #05101a;
    background: linear-gradient(135deg, #8FE3FF, #2AA0DC);
    border: none; border-radius: 30px; box-shadow: 0 10px 20px rgba(42, 160, 220, 0.4);
    pointer-events: auto; cursor: pointer; transition: transform 0.1s;
  }
  #ui button:active { transform: scale(0.95); }
  #score-display {
    position: fixed; top: 40px; left: 0; width: 100%; text-align: center;
    font-size: 32px; font-weight: bold; color: #fff; pointer-events: none;
    text-shadow: 0 2px 10px rgba(0,0,0,0.8); z-index: 10;
  }
  #final-score { font-size: 20px; color: #FFD700; margin-bottom: 25px; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="score-display">0</div>

<div id="ui">
  <h1 id="ui-title">小鲸鱼大冒险</h1>
  <p id="ui-desc">手指按住屏幕左右滑动<br>躲避海胆,吃星星!</p>
  <div id="final-score"></div>
  <button id="start-btn">开始游戏</button>
</div>

<script>
(function(){
  const canvas = document.getElementById('c');
  const ctx = canvas.getContext('2d');
  const ui = document.getElementById('ui');
  const uiTitle = document.getElementById('ui-title');
  const uiDesc = document.getElementById('ui-desc');
  const btn = document.getElementById('start-btn');
  const finalScoreEl = document.getElementById('final-score');
  const scoreDisplay = document.getElementById('score-display');

  let vw, vh, dpr;
  function resize() {
    vw = window.innerWidth; vh = window.innerHeight;
    dpr = Math.min(window.devicePixelRatio || 1, 2);
    canvas.width = vw * dpr; canvas.height = vh * dpr;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  }
  window.addEventListener('resize', resize);
  resize();

  // 游戏状态
  let playing = false;
  let score = 0;
  let speed = 4;
  let time = 0;
  
  // 玩家鲸鱼
  const player = { x: vw / 2, y: vh - 120, r: 25, targetX: vw / 2 };
  
  // 物体数组
  let stars = [];
  let enemies = [];

  // 触摸控制
  function handleMove(e) {
    if (!playing) return;
    let clientX = e.touches ? e.touches[0].clientX : e.clientX;
    player.targetX = clientX;
  }
  canvas.addEventListener('touchstart', handleMove, { passive: false });
  canvas.addEventListener('touchmove', handleMove, { passive: false });
  canvas.addEventListener('mousedown', handleMove);
  canvas.addEventListener('mousemove', e => { if(e.buttons === 1) handleMove(e); });

  // 开始游戏
  btn.addEventListener('click', () => {
    ui.classList.add('hide');
    playing = true;
    score = 0;
    speed = 4;
    time = 0;
    stars = [];
    enemies = [];
    player.x = vw / 2;
    player.targetX = vw / 2;
    scoreDisplay.innerText = '0';
    lastTime = performance.now();
    requestAnimationFrame(loop);
  });

  // 画鲸鱼
  function drawWhale(x, y, r) {
    ctx.save();
    ctx.translate(x, y);
    
    // 尾巴
    ctx.fillStyle = '#2AA0DC';
    ctx.beginPath();
    ctx.moveTo(0, r * 0.5);
    ctx.quadraticCurveTo(-r * 1.5, r * 1.2, -r * 1.2, r * 0.5);
    ctx.quadraticCurveTo(-r * 0.5, r * 0.8, 0, r * 0.8);
    ctx.quadraticCurveTo(r * 0.5, r * 0.8, r * 1.2, r * 0.5);
    ctx.quadraticCurveTo(r * 1.5, r * 1.2, 0, r * 0.5);
    ctx.fill();

    // 身体
    const grad = ctx.createLinearGradient(0, -r, 0, r);
    grad.addColorStop(0, '#A5E7FF');
    grad.addColorStop(1, '#2AA0DC');
    ctx.fillStyle = grad;
    ctx.beginPath();
    ctx.ellipse(0, 0, r, r * 1.2, 0, 0, Math.PI * 2);
    ctx.fill();

    // 肚皮
    ctx.fillStyle = '#FFFFFF';
    ctx.beginPath();
    ctx.ellipse(0, r * 0.3, r * 0.7, r * 0.8, 0, 0, Math.PI * 2);
    ctx.fill();

    // 眼睛
    ctx.fillStyle = '#12324a';
    ctx.beginPath();
    ctx.arc(-r * 0.4, -r * 0.2, r * 0.12, 0, Math.PI * 2);
    ctx.arc(r * 0.4, -r * 0.2, r * 0.12, 0, Math.PI * 2);
    ctx.fill();

    // 腮红
    ctx.fillStyle = 'rgba(255, 145, 170, 0.6)';
    ctx.beginPath();
    ctx.ellipse(-r * 0.6, r * 0.1, r * 0.15, r * 0.08, 0, 0, Math.PI * 2);
    ctx.ellipse(r * 0.6, r * 0.1, r * 0.15, r * 0.08, 0, 0, Math.PI * 2);
    ctx.fill();

    ctx.restore();
  }

  // 画星星
  function drawStar(x, y, r) {
    ctx.save();
    ctx.translate(x, y);
    ctx.fillStyle = '#FFD700';
    ctx.shadowColor = '#FFD700';
    ctx.shadowBlur = 15;
    ctx.beginPath();
    for (let i = 0; i < 5; i++) {
      ctx.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI) * r,
                 -Math.sin((18 + i * 72) / 180 * Math.PI) * r);
      ctx.lineTo(Math.cos((54 + i * 72) / 180 * Math.PI) * r * 0.4,
                 -Math.sin((54 + i * 72) / 180 * Math.PI) * r * 0.4);
    }
    ctx.closePath();
    ctx.fill();
    ctx.restore();
  }

  // 画海胆
  function drawUrchin(x, y, r) {
    ctx.save();
    ctx.translate(x, y);
    ctx.fillStyle = '#2a0b2e';
    ctx.strokeStyle = '#6b1f6e';
    ctx.lineWidth = 3;
    
    // 刺
    ctx.beginPath();
    for (let i = 0; i < 12; i++) {
      const angle = (i / 12) * Math.PI * 2;
      ctx.moveTo(Math.cos(angle) * r * 0.8, Math.sin(angle) * r * 0.8);
      ctx.lineTo(Math.cos(angle) * r * 1.4, Math.sin(angle) * r * 1.4);
    }
    ctx.stroke();

    // 身体
    ctx.beginPath();
    ctx.arc(0, 0, r, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();
  }

  // 碰撞检测
  function checkCollision(c1, c2) {
    const dx = c1.x - c2.x;
    const dy = c1.y - c2.y;
    const dist = Math.sqrt(dx * dx + dy * dy);
    return dist < (c1.r + c2.r) * 0.8; // 留点容错率
  }

  // 游戏结束
  function gameOver() {
    playing = false;
    uiTitle.innerText = "游戏结束";
    uiDesc.innerText = "不小心撞到海胆啦!";
    finalScoreEl.innerText = "得分:" + score;
    btn.innerText = "再试一次";
    ui.classList.remove('hide');
    // 手机震动反馈(如果支持)
    if (navigator.vibrate) navigator.vibrate([100, 50, 100]);
  }

  // 主循环
  let lastTime = 0;
  let spawnTimer = 0;
  
  function loop(now) {
    if (!playing) return;
    
    const dt = Math.min(0.05, (now - lastTime) / 1000);
    lastTime = now;
    time += dt;
    spawnTimer += dt;

    // 难度随时间增加
    speed = 4 + time * 0.2;

    // 更新玩家位置 (平滑跟随手指)
    player.x += (player.targetX - player.x) * 10 * dt;
    // 限制在屏幕内
    if (player.x < player.r) player.x = player.r;
    if (player.x > vw - player.r) player.x = vw - player.r;

    // 生成物体
    if (spawnTimer > 0.6) {
      spawnTimer = 0;
      const isEnemy = Math.random() < 0.65; // 65%概率生成敌人
      const x = Math.random() * (vw - 80) + 40;
      if (isEnemy) {
        enemies.push({ x, y: -50, r: 18, speed: speed * 1.1 });
      } else {
        stars.push({ x, y: -50, r: 15, speed: speed });
      }
    }

    // 更新星星
    for (let i = stars.length - 1; i >= 0; i--) {
      const s = stars[i];
      s.y += s.speed * 60 * dt;
      if (s.y > vh + 50) {
        stars.splice(i, 1);
      } else if (checkCollision(player, s)) {
        score += 10;
        scoreDisplay.innerText = score;
        stars.splice(i, 1);
      }
    }

    // 更新敌人
    for (let i = enemies.length - 1; i >= 0; i--) {
      const e = enemies[i];
      e.y += e.speed * 60 * dt;
      if (e.y > vh + 50) {
        enemies.splice(i, 1);
      } else if (checkCollision(player, e)) {
        gameOver();
        return;
      }
    }

    // --- 渲染 ---
    // 背景
    ctx.fillStyle = '#05101a';
    ctx.fillRect(0, 0, vw, vh);
    
    // 背景水泡
    ctx.fillStyle = 'rgba(255,255,255,0.05)';
    for (let i = 0; i < 10; i++) {
      const bx = (i * 123) % vw;
      const by = vh - ((time * 40 + i * 80) % (vh + 100));
      ctx.beginPath();
      ctx.arc(bx, by, 10 + i * 2, 0, Math.PI * 2);
      ctx.fill();
    }

    stars.forEach(s => drawStar(s.x, s.y, s.r));
    enemies.forEach(e => drawUrchin(e.x, e.y, e.r));
    
    // 玩家稍微有点上下浮动
    const bobY = player.y + Math.sin(time * 6) * 3;
    drawWhale(player.x, bobY, player.r);

    requestAnimationFrame(loop);
  }

})();
</script>
</body>
</html>