同一个指令,GPT 5.5 和 Claude Opus 4.7 的代码差距居然这么大?

发表时间:2026-05-09 18:00

两周前 Open AI 正式上线 GPT 5.5。


Claude   Opus 4.7 还没坐稳宝座,就被 GPT 5.5 赶下去。4.7好不好用呢?我们可以看看以往的文章。



目前 Nebula Lab 已上线 GPT 5.5,欢迎大家前来测试使用。



那么 GPT 5.5 的效果如何呢?官方说:

A new class of intelligence for real work and powering agents, built to understand complex goals, use tools, check its work, and carry more tasks through to completion. It marks a new way of getting computer work done.


即,一款面向真实工作、赋能智能代理的全新智能模型,专为理解复杂目标、调用工具、自主核验工作成果而设计,可将更多任务全程执行直至完成。


它标志着计算机工作模式迈入全新阶段。



此次 GPT 5.5 的核心升级,集中于智能体(Agent)能力的跨越式突破:用户仅需明确任务目标,模型即可自主完成全流程执行、过程校验与闭环落地,无需额外人工干预。


当前,智能体(端到端任务执行)能力已成为全球大模型厂商的核心竞争赛道,包括国内 Kimi 在内的主流产品,均将该能力作为核心迭代方向与核心卖点。


OpenAI 在本次发布中援引了第三方机构发布的 AI 模型综合智能指数评测结果,数据显示,GPT 5.5 的综合智能表现位列行业首位。



本次迭代中,OpenAI 将代理编程能力置于升级首位 —— 而编程赛道此前一直是 Anthropic Claude 系列模型的核心优势领域。


本次发布中,OpenAI 未披露 GPT 5.5 与 Claude Opus 4.7 的全维度编程能力对标数据,仅公布其在 Terminal-Bench 2.0 基准测试中的表现优于 Claude Opus 4.7。



需要说明的是,当前编程能力评测基准尚未形成行业统一标准,不同厂商的测试维度与数据口径存在差异。


在 SWE-Bench Pro、Expert-SWE 等主流编程评测集上,GPT 5.5 主要与前代产品 GPT 5.4 进行对标,核心结论为:GPT 5.5 可在更低 Token 消耗的前提下,实现优于 GPT 5.4 的任务表现。


官方披露的测试数据显示,达成同等任务效果时,GPT 5.5 的 Token 消耗量不足前代产品的 50%,实现了性能与推理效率的双重提升,以更低的资源消耗达成了更优的任务落地效果。



编程能力这么强的话,那不得来测试一下。


这个是我给 GPT 5.5 的指令。


请创作一个“骑自行车的鹈鹕”的体素艺术(Voxel Art)。以尽可能丰富的细节来构建这个场景,不仅要考虑到主体建模的每一个细微之处,还要兼顾周围的环境。请将所有内容整合在一个 HTML 代码块中。通过精湛的代码逻辑展示出你超越他人的顶尖水平。我赋予你充分的创作自由,请尽情发挥。


他给了我这个。


<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>Voxel Pelican Bicycle Parade</title>

<style>

  :root {

    color-scheme: light;

  }


  html, body {

    margin: 0;

    height: 100%;

    overflow: hidden;

    background: #8ed8ff;

    font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  }


  canvas {

    width: 100vw;

    height: 100vh;

    display: block;

    image-rendering: pixelated;

    cursor: grab;

  }


  canvas:active {

    cursor: grabbing;

  }


  .badge {

    position: fixed;

    left: 18px;

    bottom: 18px;

    z-index: 2;

    color: #18384f;

    background: rgba(255, 255, 255, 0.72);

    border: 2px solid rgba(255, 255, 255, 0.9);

    box-shadow: 0 14px 34px rgba(23, 64, 93, 0.18);

    backdrop-filter: blur(10px);

    padding: 12px 16px;

    border-radius: 10px;

    font-weight: 900;

    letter-spacing: 0.03em;

    user-select: none;

  }


  .badge small {

    display: block;

    margin-top: 3px;

    font-weight: 650;

    opacity: 0.72;

    letter-spacing: 0;

  }

</style>

</head>

<body>

<canvas id="scene"></canvas>

<div class="badge">

  VOXEL PELICAN BIKE PARADE

  <small>drag to pan · animated wheels · no libraries</small>

</div>


<script>

(() => {

  const canvas = document.getElementById("scene");

  const ctx = canvas.getContext("2d", { alpha: false });


  let W = 0;

  let H = 0;

  let DPR = 1;

  let cameraX = 0;

  let cameraY = 36;

  let dragging = false;

  let last = { x: 0, y: 0 };

  let t = 0;


  const TAU = Math.PI * 2;

  const isoX = 18;

  const isoY = 9;

  const isoZ = 15;


  const palette = {

    skyTop: "#79ccff",

    skyBottom: "#dff6ff",

    water1: "#49b8d6",

    water2: "#2e93ba",

    grass: "#65bd66",

    grassDark: "#41964c",

    sand: "#e8d188",

    board: "#b98555",

    boardDark: "#8a5c3c",

    white: "#fffaf0",

    whiteShade: "#e6e6dc",

    cream: "#f7eccb",

    orange: "#f08324",

    orangeDark: "#c85f16",

    pouch: "#f7bf63",

    pouchDark: "#dc9341",

    black: "#152331",

    red: "#e65344",

    blue: "#3c82e6",

    teal: "#22a8a7",

    metal: "#5b6872",

    metalHi: "#cad6de",

    tire: "#1d2a31",

    rubberHi: "#40515b",

    yellow: "#ffd04a"

  };


  function resize() {

    DPR = Math.min(2, window.devicePixelRatio || 1);

    W = Math.floor(innerWidth * DPR);

    H = Math.floor(innerHeight * DPR);

    canvas.width = W;

    canvas.height = H;

    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);

    W = innerWidth;

    H = innerHeight;

  }


  addEventListener("resize", resize);

  resize();


  canvas.addEventListener("pointerdown", e => {

    dragging = true;

    last.x = e.clientX;

    last.y = e.clientY;

    canvas.setPointerCapture(e.pointerId);

  });


  canvas.addEventListener("pointermove", e => {

    if (!dragging) return;

    cameraX += e.clientX - last.x;

    cameraY += e.clientY - last.y;

    last.x = e.clientX;

    last.y = e.clientY;

  });


  canvas.addEventListener("pointerup", () => dragging = false);

  canvas.addEventListener("pointercancel", () => dragging = false);


  function shade(hex, amt) {

    const n = parseInt(hex.slice(1), 16);

    let r = (n >> 16) + amt;

    let g = ((n >> 8) & 255) + amt;

    let b = (n & 255) + amt;

    r = Math.max(0, Math.min(255, r));

    g = Math.max(0, Math.min(255, g));

    b = Math.max(0, Math.min(255, b));

    return "#" + (b | (g << 8) | (r << 16)).toString(16).padStart(6, "0");

  }


  function iso(x, y, z) {

    return {

      x: W * 0.5 + cameraX + (x - y) * isoX,

      y: H * 0.58 + cameraY + (x + y) * isoY - z * isoZ

    };

  }


  function poly(points, fill, stroke = "rgba(30,45,55,0.22)", width = 1) {

    ctx.beginPath();

    ctx.moveTo(points[0].x, points[0].y);

    for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y);

    ctx.closePath();

    ctx.fillStyle = fill;

    ctx.fill();

    if (stroke) {

      ctx.lineWidth = width;

      ctx.strokeStyle = stroke;

      ctx.stroke();

    }

  }


  function cube(x, y, z, w, d, h, color, stroke) {

    const A = iso(x, y, z + h);

    const B = iso(x + w, y, z + h);

    const C = iso(x + w, y + d, z + h);

    const D = iso(x, y + d, z + h);

    const E = iso(x, y, z);

    const F = iso(x + w, y, z);

    const G = iso(x + w, y + d, z);

    const Hh = iso(x, y + d, z);


    poly([A, B, C, D], shade(color, 18), stroke);

    poly([B, F, G, C], shade(color, -26), stroke);

    poly([D, C, G, Hh], shade(color, -42), stroke);

  }


  function rect2(cx, cy, w, h, color, rot = 0, stroke = "rgba(0,0,0,0.22)") {

    ctx.save();

    ctx.translate(cx, cy);

    ctx.rotate(rot);

    ctx.fillStyle = color;

    ctx.strokeStyle = stroke;

    ctx.lineWidth = 2;

    ctx.fillRect(-w / 2, -h / 2, w, h);

    ctx.strokeRect(-w / 2, -h / 2, w, h);

    ctx.restore();

  }


  function line(a, b, color, width = 5) {

    ctx.beginPath();

    ctx.moveTo(a.x, a.y);

    ctx.lineTo(b.x, b.y);

    ctx.lineCap = "square";

    ctx.lineWidth = width;

    ctx.strokeStyle = color;

    ctx.stroke();

  }


  function circleBlock(cx, cy, r, count, size, color, phase = 0) {

    for (let i = 0; i < count; i++) {

      const a = i / count * TAU + phase;

      rect2(cx + Math.cos(a) * r, cy + Math.sin(a) * r, size, size, color, a);

    }

  }


  function background() {

    const g = ctx.createLinearGradient(0, 0, 0, H);

    g.addColorStop(0, palette.skyTop);

    g.addColorStop(0.58, palette.skyBottom);

    g.addColorStop(1, "#fff4d3");

    ctx.fillStyle = g;

    ctx.fillRect(0, 0, W, H);


    ctx.fillStyle = "#ffe78b";

    ctx.beginPath();

    ctx.arc(W - 122, 102, 46, 0, TAU);

    ctx.fill();


    for (let i = 0; i < 7; i++) {

      const x = (i * 250 + (t * 9) % 250) - 130;

      const y = 68 + (i % 3) * 38;

      cloud(x, y, 1 + (i % 2) * 0.24);

    }


    ctx.fillStyle = "#b7e8f8";

    for (let i = 0; i < 4; i++) {

      const y = H * 0.42 + i * 22;

      ctx.fillRect(0, y, W, 2);

    }

  }


  function cloud(x, y, s) {

    ctx.fillStyle = "rgba(255,255,255,0.82)";

    const blocks = [

      [0, 12, 58, 22], [34, 0, 72, 34], [90, 13, 62, 24],

      [25, 28, 110, 18], [118, 28, 34, 18]

    ];

    for (const b of blocks) ctx.fillRect(x + b[0] * s, y + b[1] * s, b[2] * s, b[3] * s);

  }


  function waterAndLand() {

    const waterY = H * 0.48 + cameraY * 0.08;

    ctx.fillStyle = palette.water1;

    ctx.fillRect(0, waterY, W, H - waterY);


    for (let i = 0; i < 26; i++) {

      const y = waterY + 18 + i * 18;

      ctx.fillStyle = i % 2 ? "rgba(255,255,255,0.15)" : "rgba(35,105,140,0.16)";

      const shift = (Math.sin(t * 1.2 + i) * 18);

      for (let x = -80; x < W + 80; x += 115) {

        ctx.fillRect(x + shift, y, 54, 4);

      }

    }


    for (let x = -12; x < 36; x += 4) {

      for (let y = -18; y < 22; y += 4) cube(x, y, -1, 4, 4, 1, palette.sand, null);

    }


    for (let x = -14; x < 38; x += 4) {

      cube(x, -22, 0, 4, 5, 2, palette.grass, null);

      if (x % 8 === 0) cube(x + 1, -24, 2, 1, 1, 4, palette.grassDark, null);

    }


    for (let x = -16; x < 40; x += 4) {

      cube(x, 21, 0, 4, 4, 2, palette.grass, null);

      if (x % 12 === 0) cube(x + 2, 24, 2, 1, 1, 5, "#5aa24c", null);

    }


    for (let x = -18; x < 42; x += 5) {

      cube(x, -3, 0, 5, 26, 1.2, palette.board, "rgba(79,54,37,0.28)");

      cube(x, -3.2, 1.2, 0.3, 26.4, 0.35, palette.boardDark, null);

    }


    for (let y = -1; y < 22; y += 7) {

      cube(-19, y, 0, 62, 1.2, 1.5, palette.boardDark, null);

    }


    for (let x = -18; x < 44; x += 12) {

      cube(x, -5, 0, 1.4, 1.4, 7, "#7a4b2e", null);

      cube(x, 23, 0, 1.4, 1.4, 7, "#7a4b2e", null);

      cube(x - 0.4, -5.4, 7, 2.2, 2.2, 0.8, "#d3a16a", null);

      cube(x - 0.4, 22.6, 7, 2.2, 2.2, 0.8, "#d3a16a", null);

    }


    for (let x = -17; x < 40; x += 3) cube(x, -5, 6.5, 2, 1, 1, "#e5c399", null);

    for (let x = -17; x < 40; x += 3) cube(x, 23, 6.5, 2, 1, 1, "#e5c399", null);

  }


  function lighthouseAndShops() {

    cube(27, -19, 0, 4, 4, 15, "#f5f0dd", null);

    cube(27, -19, 15, 4, 4, 3, palette.red, null);

    cube(26.5, -19.5, 18, 5, 5, 1.2, palette.black, null);

    cube(28, -20, 19, 2, 6, 2, "#ffd759", null);

    cube(26.4, -20.2, 21, 5.2, 5.2, 1.2, palette.red, null);


    cube(-19, -20, 0, 8, 6, 5, "#ffdf9b", null);

    cube(-20, -21, 5, 10, 8, 2, "#de5144", null);

    cube(-17, -19, 1, 2, 1, 2, "#4fa8d9", null);

    cube(-13.8, -19, 0, 2, 1, 3, "#825a3e", null);


    cube(-7, -21, 0, 7, 7, 5, "#c7e7c4", null);

    cube(-8, -22, 5, 9, 9, 2, "#348f7c", null);

    cube(-5.5, -20, 1, 2, 1, 2, "#f7f7ff", null);

    cube(-2, -20, 1, 1.8, 1, 2, "#f7f7ff", null);


    for (let i = 0; i < 7; i++) {

      const x = -16 + i * 5;

      cube(x, -9, 0, 1, 1, 4 + (i % 2), "#2e9c57", null);

      cube(x - 0.8, -9.8, 4 + (i % 2), 2.6, 2.6, 1.6, i % 2 ? "#fb6f92" : "#ffd166", null);

    }

  }


  function drawBike() {

    const bounce = Math.sin(t * 4) * 2;

    const base = iso(9, 8, 6);

    const bx = base.x;

    const by = base.y + bounce;

    const rot = -t * 3.6;


    const rear = { x: bx - 126, y: by + 74 };

    const front = { x: bx + 118, y: by + 74 };

    const crank = { x: bx - 10, y: by + 52 };

    const seat = { x: bx - 52, y: by - 14 };

    const handle = { x: bx + 88, y: by - 24 };

    const forkTop = { x: bx + 70, y: by + 10 };


    ctx.lineCap = "square";

    circleBlock(rear.x, rear.y, 45, 46, 8, palette.tire, rot);

    circleBlock(front.x, front.y, 45, 46, 8, palette.tire, rot);

    circleBlock(rear.x, rear.y, 32, 24, 4, palette.rubberHi, -rot * 1.4);

    circleBlock(front.x, front.y, 32, 24, 4, palette.rubberHi, -rot * 1.4);


    for (let i = 0; i < 12; i++) {

      const a = i / 12 * TAU + rot;

      line(rear, { x: rear.x + Math.cos(a) * 39, y: rear.y + Math.sin(a) * 39 }, palette.metalHi, 2);

      line(front, { x: front.x + Math.cos(a) * 39, y: front.y + Math.sin(a) * 39 }, palette.metalHi, 2);

    }


    rect2(rear.x, rear.y, 15, 15, palette.metal);

    rect2(front.x, front.y, 15, 15, palette.metal);


    line(rear, crank, palette.teal, 8);

    line(crank, front, palette.teal, 8);

    line(rear, seat, palette.teal, 8);

    line(seat, handle, palette.teal, 8);

    line(crank, seat, palette.teal, 8);

    line(front, forkTop, palette.teal, 8);

    line(forkTop, handle, palette.teal, 8);


    line({ x: bx - 82, y: by + 30 }, { x: bx - 118, y: by + 22 }, "#263843", 4);

    line({ x: bx + 92, y: by - 24 }, { x: bx + 130, y: by - 34 }, "#263843", 4);

    rect2(bx - 52, by - 23, 54, 12, "#422f29", -0.04);

    rect2(bx + 130, by - 36, 34, 8, "#263843", -0.05);


    circleBlock(crank.x, crank.y, 16, 14, 5, palette.yellow, rot * 1.7);

    rect2(crank.x + Math.cos(rot * 1.7) * 26, crank.y + Math.sin(rot * 1.7) * 26, 34, 7, palette.orange, rot * 1.7);

    rect2(crank.x + Math.cos(rot * 1.7 + Math.PI) * 26, crank.y + Math.sin(rot * 1.7 + Math.PI) * 26, 34, 7, palette.orange, rot * 1.7 + Math.PI);


    const basket = { x: bx + 138, y: by - 3 };

    rect2(basket.x, basket.y, 52, 36, "#b77a44", 0.05);

    for (let i = -2; i <= 2; i++) rect2(basket.x + i * 10, basket.y, 2, 36, "#815231", 0.05);

    for (let i = -1; i <= 1; i++) rect2(basket.x, basket.y + i * 10, 52, 2, "#815231", 0.05);

    rect2(basket.x - 12, basket.y - 27, 12, 20, "#ff5f7d", -0.4);

    rect2(basket.x + 8, basket.y - 28, 13, 19, "#ffd166", 0.35);

    rect2(basket.x + 24, basket.y - 21, 10, 16, "#6ed06e", 0.1);

  }


  function drawPelican() {

    const bob = Math.sin(t * 4) * 2;

    const base = iso(8, 8, 12);

    const x = base.x - 7;

    const y = base.y - 88 + bob;


    const block = (dx, dy, w, h, color, rot = 0) => rect2(x + dx, y + dy, w, h, color, rot);


    block(-68, 38, 116, 72, palette.white);

    block(-56, 25, 86, 34, palette.whiteShade);

    block(-86, 46, 38, 56, palette.whiteShade, -0.18);

    block(-101, 58, 22, 48, "#d9ded7", -0.28);

    block(4, 72, 43, 23, "#d8d8cf", 0.12);


    block(7, -4, 62, 57, palette.white);

    block(30, -39, 68, 55, palette.white);

    block(66, -49, 32, 29, palette.whiteShade);


    block(79, -31, 106, 23, palette.orange, 0.02);

    block(83, -7, 86, 36, palette.pouch, 0.04);

    block(154, -32, 44, 20, palette.orangeDark, 0.02);

    block(164, -5, 24, 18, palette.pouchDark, 0.05);

    block(58, -22, 8, 8, palette.black);

    block(61, -24, 3, 3, "#ffffff");

    block(23, -60, 16, 22, palette.whiteShade, -0.16);

    block(38, -67, 14, 20, palette.white, 0.1);

    block(51, -63, 12, 18, palette.whiteShade, 0.25);


    block(-35, -4, 40, 34, "#f3f0e3", -0.2);

    block(-48, 4, 18, 18, "#d1d5ce", -0.2);

    block(-52, 73, 16, 64, palette.orangeDark, 0.25);

    block(14, 79, 16, 60, palette.orangeDark, -0.22);


    const pedalA = t * 6;

    block(-58 + Math.cos(pedalA) * 14, 126 + Math.sin(pedalA) * 14, 34, 11, palette.orange, pedalA * 0.3);

    block(10 + Math.cos(pedalA + Math.PI) * 14, 126 + Math.sin(pedalA + Math.PI) * 14, 34, 11, palette.orange, -pedalA * 0.3);


    block(-15, -19, 22, 13, "#4ec5da", 0.08);

    block(7, -20, 19, 13, "#ffcf57", 0.08);

    block(29, -19, 22, 13, "#ff6b60", 0.08);

    block(-20, -24, 58, 4, "#263843", 0.08);


    for (let i = 0; i < 9; i++) {

      block(-74 + i * 14, 31 + Math.sin(i + t * 2) * 2, 8, 7, "#f5f4e7");

    }

    for (let i = 0; i < 5; i++) {

      block(100 + i * 13, -16 + (i % 2) * 4, 7, 5, "#ffd99b");

    }

  }


  function details() {

    for (let i = 0; i < 18; i++) {

      const x = -17 + (i * 3.2);

      const y = i % 2 ? 20 : -2;

      cube(x, y, 1.4, 0.8, 0.8, 1.2, i % 3 ? "#f4eee0" : "#d1ebef", null);

    }


    for (let i = 0; i < 16; i++) {

      const x = -14 + i * 3.5;

      const h = 2 + (i % 4);

      cube(x, 26 + (i % 3), 0, 0.7, 0.7, h, "#3f8f52", null);

      cube(x - 0.4, 26.4 + (i % 3), h, 1.5, 0.7, 0.7, i % 2 ? "#ffe66d" : "#ff7a7a", null);

    }


    for (let i = 0; i < 8; i++) {

      const p = iso(-14 + i * 7, 31, 1);

      const swim = Math.sin(t * 2 + i) * 4;

      ctx.fillStyle = i % 2 ? "#f6b645" : "#66d0d3";

      ctx.fillRect(p.x - 8, p.y + swim, 20, 7);

      ctx.fillRect(p.x + 10, p.y + swim + 2, 6, 3);

    }


    const bannerA = iso(-12, -7, 9);

    const bannerB = iso(34, -7, 9);

    line(bannerA, bannerB, "#f8f4d2", 3);

    for (let i = 0; i < 12; i++) {

      const u = i / 11;

      const x = bannerA.x * (1 - u) + bannerB.x * u;

      const y = bannerA.y * (1 - u) + bannerB.y * u + Math.sin(t * 3 + i) * 2;

      rect2(x, y + 9, 11, 15, ["#f94144", "#f9c74f", "#43aa8b", "#577590"][i % 4], 0.03);

    }

  }


  function drawShadow() {

    const p = iso(8, 8, 1.4);

    ctx.fillStyle = "rgba(33, 52, 47, 0.18)";

    ctx.beginPath();

    ctx.ellipse(p.x, p.y + 73, 188, 42, -0.01, 0, TAU);

    ctx.fill();

  }


  function drawScene() {

    background();

    waterAndLand();

    lighthouseAndShops();

    details();

    drawShadow();

    drawBike();

    drawPelican();


    ctx.fillStyle = "rgba(255,255,255,0.18)";

    for (let i = 0; i < 80; i++) {

      const x = (i * 97 + t * 14) % (W + 160) - 80;

      const y = H * 0.52 + ((i * 53) % Math.max(1, H * 0.42));

      const w = 12 + (i % 4) * 8;

      ctx.fillRect(x, y, w, 2);

    }

  }


  function animate(now) {

    t = now / 1000;

    drawScene();

    requestAnimationFrame(animate);

  }


  requestAnimationFrame(animate);

})();

</script>

</body>

</html>



我们运行一下,可以运行。


然后我以同样的问题,又去问了 Claude   Opus 4.7,得到这个代码。


<!DOCTYPE html>

<html lang="zh">

<head>

<meta charset="UTF-8">

<title>骑自行车的鹈鹕 · Voxel Art</title>

<style>

*{margin:0;padding:0;box-sizing:border-box}

body{background:#1a1a2e;display:flex;align-items:center;justify-content:center;min-height:100vh;overflow:hidden}

canvas{display:block;image-rendering:pixelated;image-rendering:crisp-edges}

#info{position:fixed;bottom:16px;left:16px;color:#fff;font:700 13px/1.6 system-ui;

background:rgba(0,0,0,.45);padding:10px 14px;border-radius:12px;backdrop-filter:blur(6px);pointer-events:none}

</style>

</head>

<body>

<canvas id="c"></canvas>

<div id="info"> 骑自行车的鹈鹕 · Voxel Art<br><small>纯 Canvas · 无依赖 · 实时动画</small></div>

<script>

(function(){

"use strict";


/* ─────────────── 画布初始化 ─────────────── */

const canvas = document.getElementById("c");

const ctx    = canvas.getContext("2d");

const W = 900, H = 620;

canvas.width   = W;

canvas.height = H;

canvas.style.width   = W + "px";

canvas.style.height = H + "px";


/* ─────────────── 体素绘制核心 ─────────────── */

const ISO_X   = 0.70;   // isometric tilt

const ISO_Y   = 0.35;


/* 将体素坐标 (gx,gy,gz) 转成屏幕 2D */

function toScreen(gx, gy, gz){

  return {

    x: W/2 + (gx - gy) * ISO_X * gz * 0 + (gx - gy) * 14,

    y: H/2 - gz * 14   + (gx + gy) * 7

  };

}


/* 画一个单体素(面向正面朝左的等轴视角) */

function vox(gx, gy, gz, col){

  const S   = 14;           // voxel base size px

  const ox = 14 * ISO_X;   // offset x for depth

  const oy = 14 * ISO_Y;   // offset y for depth


  const px = W/2 + (gx - gy) * S;

  const py = H/2 - gz * S + (gx + gy) * (S * 0.5);


  // top face

  ctx.fillStyle = lighten(col, 40);

  ctx.beginPath();

  ctx.moveTo(px,        py);

  ctx.lineTo(px + S,    py);

  ctx.lineTo(px + S + ox, py - oy);

  ctx.lineTo(px     + ox, py - oy);

  ctx.closePath();

  ctx.fill();


  // right face

  ctx.fillStyle = darken(col, 30);

  ctx.beginPath();

  ctx.moveTo(px + S,    py);

  ctx.lineTo(px + S,    py + S);

  ctx.lineTo(px + S + ox, py + S - oy);

  ctx.lineTo(px + S + ox, py - oy);

  ctx.closePath();

  ctx.fill();


  // front face

  ctx.fillStyle = col;

  ctx.beginPath();

  ctx.moveTo(px,     py);

  ctx.lineTo(px,     py + S);

  ctx.lineTo(px + S, py + S);

  ctx.lineTo(px + S, py);

  ctx.closePath();

  ctx.fill();


  // outline

  ctx.strokeStyle = "rgba(0,0,0,0.18)";

  ctx.lineWidth   = 0.5;

  ctx.strokeRect(px, py, S, S);

}


/* 颜色工具 */

function lighten(hex, n){

  return shiftColor(hex, n);

}

function darken(hex, n){

  return shiftColor(hex, -n);

}

function shiftColor(hex, n){

  let r = parseInt(hex.slice(1,3),16);

  let g = parseInt(hex.slice(3,5),16);

  let b = parseInt(hex.slice(5,7),16);

  r = Math.max(0,Math.min(255,r+n));

  g = Math.max(0,Math.min(255,g+n));

  b = Math.max(0,Math.min(255,b+n));

  return `rgb(${r},${g},${b})`;

}


/* ─────────────── 批量绘制工具 ─────────────── */

/* 用 ASCII 图定义层,逐层堆叠 */

function drawLayer(map, z, palette, ox=0, oy=0){

  for(let r=0;r<map.length;r++){

    for(let c=0;c<map[r].length;c++){

      const ch = map[r][c];

      if(ch !== "." && palette[ch]){

        vox(ox+c, oy+r, z, palette[ch]);

      }

    }

  }

}


/* ─────────────── 场景物件 ─────────────── */


/* 天空背景 */

function drawSky(){

  const g = ctx.createLinearGradient(0,0,0,H);

  g.addColorStop(0,"#1a1a6e");

  g.addColorStop(0.35,"#2255bb");

  g.addColorStop(0.72,"#59b8e8");

  g.addColorStop(1,"#a8e8ff");

  ctx.fillStyle = g;

  ctx.fillRect(0,0,W,H);

}


/* 太阳 */

function drawSun(){

  const sx = W*0.82, sy = H*0.14;

  const g = ctx.createRadialGradient(sx,sy,4,sx,sy,52);

  g.addColorStop(0,"#fff7a0");

  g.addColorStop(0.45,"#ffd84d");

  g.addColorStop(1,"rgba(255,200,50,0)");

  ctx.fillStyle = g;

  ctx.beginPath();

  ctx.arc(sx,sy,52,0,Math.PI*2);

  ctx.fill();


  // pixel sun core

  for(let r=-2;r<=2;r++)

    for(let c=-2;c<=2;c++)

      if(r*r+c*c<6)

        ctx.fillStyle="#fffcd0",

        ctx.fillRect(sx+c*8-4,sy+r*8-4,8,8);

}


/* 云朵(像素块) */

function drawCloud(sx,sy,scale){

  const s = scale*7;

  const m = [

    "..WW....",

    ".WWWW...",

    "WWWWWWW.",

    ".WWWWWW.",

    "..WWWW.."

  ];

  for(let r=0;r<m.length;r++)

    for(let c=0;c<m[r].length;c++)

      if(m[r][c]==="W"){

        ctx.fillStyle = r<2 ? "#ffffff" : "#e8f4ff";

        ctx.fillRect(sx+c*s, sy+r*s, s-1, s-1);

      }

}


/* 地面(绿地+道路+海边) */

function drawGround(){

  // 草地

  const g = ctx.createLinearGradient(0,H*0.62,0,H);

  g.addColorStop(0,"#4caf6a");

  g.addColorStop(1,"#2e7d46");

  ctx.fillStyle = g;

  ctx.fillRect(0, H*0.62, W, H);


  // 路面

  ctx.fillStyle = "#6e7080";

  ctx.fillRect(0, H*0.62, W, H*0.18);


  // 路线

  ctx.fillStyle = "#ffffff";

  for(let x=0;x<W;x+=90){

    ctx.fillRect(x, H*0.70, 55, 5);

  }


  // 路边石

  ctx.fillStyle = "#bcbcbc";

  ctx.fillRect(0,H*0.615,W,6);

  ctx.fillRect(0,H*0.795,W,6);


  // 海 (远景)

  const sea = ctx.createLinearGradient(0,H*0.50,0,H*0.62);

  sea.addColorStop(0,"#1a7bbf");

  sea.addColorStop(1,"#1e96d8");

  ctx.fillStyle = sea;

  ctx.fillRect(0,H*0.50,W,H*0.12);


  // 海浪像素

  ctx.fillStyle = "rgba(255,255,255,0.25)";

  for(let i=0;i<12;i++){

    ctx.fillRect(i*80, H*0.54, 40, 3);

    ctx.fillRect(i*80+30, H*0.58, 30, 2);

  }

}


/* 树(体素) */

function drawTree(gx,gy){

  const trunk = "#7a4520";

  const leafA = "#2d9e52";

  const leafB = "#3dbb66";

  const leafC = "#23813e";

  // 树干

  for(let z=0;z<5;z++) vox(gx,gy,z,trunk);

  // 树冠层1

  const c1=[

    "..LLL..",

    ".LLLLL.",

    "LLLLLLL",

    ".LLLLL.",

    "..LLL.."

  ];

  drawLayer(c1,5,{L:leafA},gx-3,gy-2);

  drawLayer(c1,6,{L:leafB},gx-2,gy-2);

  drawLayer(c1,7,{L:leafC},gx-2,gy-2);

  // 顶部

  const c2=[

    ".LL.",

    "LLLL",

    ".LL."

  ];

  drawLayer(c2,8,{L:leafA},gx-1,gy-1);

  drawLayer(c2,9,{L:leafB},gx-1,gy-1);

}


/* 路灯(体素) */

function drawLamp(gx,gy){

  for(let z=0;z<9;z++) vox(gx,gy,z,"#888899");

  vox(gx,gy,9,"#aaaacc");

  vox(gx+1,gy,9,"#aaaacc");

  vox(gx+1,gy,8,"#888899");

  vox(gx,gy,10,"#ffee88");

  vox(gx+1,gy,10,"#ffe066");

}


/* 自行车 */

function drawBicycle(bx, by, wheelRot){

  const METAL   = "#c0c8d8";

  const DARK   = "#3a3f55";

  const RED    = "#e84040";

  const CHROME = "#e8eef8";


  // 后轮

  drawWheel(bx-4, by, 3, wheelRot, DARK, CHROME, "#ffaa22");

  // 前轮

  drawWheel(bx+5, by, 3, wheelRot, DARK, CHROME, "#ffaa22");


  // 车架(简化为体素杆)

  // 座管(竖直)

  for(let z=0;z<=4;z++) vox(bx-2,by,z+3,METAL);

  // 上管(横)

  for(let i=0;i<=6;i++) vox(bx-2+i,by,7,RED);

  // 下管(斜)

  vox(bx-2,by,7,METAL); vox(bx-1,by,5,METAL); vox(bx,by,4,METAL);

  vox(bx+1,by,4,METAL); vox(bx+2,by,4,METAL); vox(bx+3,by,3,METAL);

  // 立管(前)

  for(let z=3;z<=7;z++) vox(bx+4,by,z,METAL);

  // 后叉

  vox(bx-3,by,3,METAL); vox(bx-4,by,3,METAL);

  // 前叉

  vox(bx+5,by,3,METAL); vox(bx+5,by,4,METAL);

  // 车把

  vox(bx+4,by,8,CHROME); vox(bx+5,by,8,CHROME);

  vox(bx+4,by-1,8,CHROME); vox(bx+4,by+1,8,CHROME);

  // 车座

  for(let i=-1;i<=1;i++) vox(bx-2+i,by,8,"#2a2a3a");

  vox(bx-3,by,8,"#2a2a3a");

  // 踏板(动画)

  const pr = 1.6;

  const pax = bx + Math.round(Math.cos(wheelRot)*pr);

  const paz = 5   + Math.round(Math.sin(wheelRot)*pr);

  const pbx = bx + Math.round(Math.cos(wheelRot+Math.PI)*pr);

  const pbz = 5   + Math.round(Math.sin(wheelRot+Math.PI)*pr);

  vox(pax,by,paz,"#ffcc44");

  vox(pbx,by,pbz,"#ffcc44");

  // 链条(简单装饰)

  for(let i=0;i<=3;i++) vox(bx-2+i,by,3,"#888888");


  // 车铃

  vox(bx+4,by,9,"#ffd700");


  // 车篮(前)

  for(let z=7;z<=9;z++){

    vox(bx+5,by-1,z,"#c8a060");

    vox(bx+5,by+1,z,"#c8a060");

  }

  vox(bx+5,by-1,9,"#c8a060");

  vox(bx+5,by,9,"#c8a060");

  vox(bx+5,by+1,9,"#c8a060");

  vox(bx+6,by-1,8,"#c8a060");

  vox(bx+6,by+1,8,"#c8a060");

  vox(bx+6,by-1,9,"#e8c080");

  vox(bx+6,by,9,"#e8c080");

  vox(bx+6,by+1,9,"#e8c080");


  // 车篮里的鱼

  vox(bx+6,by,10,"#ff8844");

  vox(bx+5,by,10,"#ffaa66");

}


/* 车轮(体素圆环) */

function drawWheel(wx, wy, r, rot, tireCol, rimCol, hubCol){

  const pts = 20;

  for(let i=0;i<pts;i++){

    const a = i*Math.PI*2/pts;

    const gx = wx + Math.round(Math.cos(a)*r);

    const gz = wy + Math.round(Math.sin(a)*r);

    vox(gx, 0, gz, tireCol);

  }

  // 轮辐

  for(let i=0;i<6;i++){

    const a = rot + i*Math.PI/3;

    for(let d=0;d<r;d++){

      const t = d/r;

      const gx = wx + Math.round(Math.cos(a)*d);

      const gz = wy + Math.round(Math.sin(a)*d);

      vox(gx, 0, gz, t<0.3?hubCol:rimCol);

    }

  }

  // 轮毂

  vox(wx,0,wy,hubCol);

  vox(wx,0,wy+1,hubCol);

}


/* ─────────────── 鹈鹕 ─────────────── */

function drawPelican(px, py, t){

  /* 颜色 */

  const W_COL   = "#f5f5f5";   // 白色羽毛

  const GRAY   = "#c8d0dc";   // 翅膀深色

  const ORANGE = "#ff8822";   // 喙

  const PINK   = "#ffaaaa";   // 喉囊

  const EYE    = "#1a1a2e";

  const PUPIL   = "#ffffff";

  const LEG    = "#e8a040";

  const FOOT   = "#d08030";

  const BEAK_D = "#cc6611";

  const BELLY   = "#fffaf0";

  const WING_A = "#e8ecf0";

  const WING_B = "#b0bac8";


  const bz = py; // base Z


  /* 身体(蛋形,多层) */

  // 层0 腹部底

  const body0=[

    "..BBB..",

    ".BBBBB.",

    ".BBBBB.",

    "..BBB.."

  ];

  drawLayer(body0,bz+4,{B:BELLY},px-1,0-1);


  // 层1-4 身体主体

  const body1=[

    "..WWW..",

    ".WWWWW.",

    "WWWWWWW",

    ".WWWWW.",

    "..WWW.."

  ];

  for(let z=bz+5;z<=bz+8;z++)

    drawLayer(body1,z,{W:W_COL},px-3,0-2);


  // 层5-6 身体上部(收窄)

  const body2=[

    ".WWWW.",

    "WWWWWW",

    ".WWWW."

  ];

  drawLayer(body2,bz+9, {W:W_COL},px-2,0-1);

  drawLayer(body2,bz+10,{W:W_COL},px-2,0-1);


  /* 翅膀(左=前,右=后,带扑翼动画) */

  const wFlap   = Math.sin(t*0.04)*2;

  const wOff   = Math.round(wFlap);


  // 左翅

  const wingL=[

    "...AAAA",

    "..AAAAA",

    ".AAAAAA",

    "..BBBB.",

    "...BB.."

  ];

  for(let z=bz+6;z<=bz+9;z++)

    drawLayer(wingL,z+wOff,{A:WING_A,B:WING_B},px-7,0-2);


  // 右翅

  const wingR=[

    "AAAA...",

    "AAAAA..",

    "AAAAAA.",

    ".BBBB..",

    "..BB..."

  ];

  for(let z=bz+6;z<=bz+9;z++)

    drawLayer(wingR,z-wOff,{A:WING_A,B:WING_B},px+2,0-2);


  /* 颈部 */

  const neck=[

    ".NN.",

    "NNNN",

    ".NN."

  ];

  drawLayer(neck,bz+11,{N:W_COL},px-1,0-1);

  drawLayer(neck,bz+12,{N:W_COL},px-1,0-1);

  drawLayer(neck,bz+13,{N:W_COL},px   ,0-1);


  /* 头部 */

  const head=[

    ".HHH.",

    "HHHHH",

    "HHHHH",

    ".HHH."

  ];

  drawLayer(head,bz+14,{H:W_COL},px-1,0-1);

  drawLayer(head,bz+15,{H:W_COL},px-1,0-1);

  drawLayer(head,bz+16,{H:W_COL},px-1,0-1);


  // 头顶羽冠

  vox(px,0,bz+17,W_COL);

  vox(px+1,0,bz+17,W_COL);

  vox(px+1,0,bz+18,"#ffe0a0");


  /* 眼睛 */

  vox(px+2,0,bz+16,EYE);   // 眼白外圈

  vox(px+2,0,bz+15,EYE);

  vox(px+3,0,bz+16,PUPIL); // 高光

  // 眼圈(橙色)

  vox(px+2,0,bz+17,ORANGE);

  vox(px+3,0,bz+17,"#cc6611");


  /* 喙(上) */

  const beakU=[

    "OOOOO",

    "OOOOO",

    ".OOO."

  ];

  drawLayer(beakU,bz+15,{O:ORANGE},px+2,0);

  drawLayer(beakU,bz+14,{O:BEAK_D},px+2,0);

  // 喙尖

  vox(px+7,0,bz+14,BEAK_D);

  vox(px+7,0,bz+15,ORANGE);


  /* 喉囊(下颌袋,大特征!) */

  const pouch=[

    ".PPP.",

    "PPPPP",

    "PPPPP",

    "PPPPP",

    ".PPP.",

    "..P.."

  ];

  drawLayer(pouch,bz+8, {P:PINK},px+2,0-1);

  drawLayer(pouch,bz+9, {P:"#ff9999"},px+2,0-1);

  drawLayer(pouch,bz+10,{P:"#ffbbbb"},px+2,0-1);

  drawLayer(pouch,bz+11,{P:"#ffcccc"},px+2,0-1);

  // 喉囊纹理

  vox(px+3,0,bz+10,"#ffaaaa");

  vox(px+4,0,bz+9, "#ff8888");


  /* 腿和脚 */

  // 左腿

  for(let z=bz+1;z<=bz+4;z++) vox(px-1,0,z,LEG);

  // 右腿

  for(let z=bz+1;z<=bz+4;z++) vox(px+1,0,z,LEG);

  // 左脚(3趾)

  vox(px-1,0,bz+1,FOOT);vox(px-2,0,bz+1,FOOT);vox(px,0,bz+1,FOOT);

  // 右脚(3趾)

  vox(px+1,0,bz+1,FOOT);vox(px+2,0,bz+1,FOOT);vox(px+3,0,bz+1,FOOT);


  /* 尾部 */

  const tail=[

    ".TT.",

    "TTTT",

    ".TT.",

    "..T."

  ];

  drawLayer(tail,bz+5,{T:GRAY},px-5,0-1);

  drawLayer(tail,bz+6,{T:"#a8b4c0"},px-5,0-1);


  /* 肩章(橙色斑块) */

  vox(px-2,0,bz+9,"#ffcc44");

  vox(px+2,0,bz+9,"#ffcc44");

  vox(px-2,0,bz+10,"#ffd866");

  vox(px+2,0,bz+10,"#ffd866");


  /* 安全帽(小细节) */

  const helmet=[

    ".HHH.",

    "HHHHH",

    "HHHHH",

    ".HHH."

  ];

  drawLayer(helmet,bz+17,{H:"#ff3333"},px-1,0-1);

  drawLayer(helmet,bz+18,{H:"#ff4444"},px-1,0-1);

  // 帽檐

  vox(px-2,0,bz+17,"#cc2222");

  vox(px+2,0,bz+17,"#cc2222");

  // 帽扣(黄色条纹)

  vox(px,0,bz+17,"#ffee44");

  vox(px+1,0,bz+17,"#ffee44");


  /* 太阳镜 */

  vox(px+3,0,bz+15,"#224488");

  vox(px+4,0,bz+15,"#224488");

  vox(px+2,0,bz+15,"#335599");

  // 镜框

  vox(px+2,0,bz+16,"#111122");

  vox(px+5,0,bz+15,"#112233");

}


/* ─────────────── 环境物件 ─────────────── */


/* 指示牌 */

function drawSign(gx,gy){

  for(let z=0;z<6;z++) vox(gx,gy,z,"#9a7050");

  for(let r=0;r<3;r++)

    for(let c=0;c<6;c++)

      vox(gx-3+c,gy,6+r,c===0||c===5||r===0||r===2?"#cc4444":"#ffffdd");

}


/* 邮筒 */

function drawMailbox(gx,gy){

  for(let z=0;z<3;z++) vox(gx,gy,z,"#777788");

  for(let z=3;z<=6;z++) vox(gx,gy,z,"#dd2222");

  vox(gx,gy,7,"#cc2222");

  vox(gx-1,gy,5,"#dd2222");

  vox(gx+1,gy,5,"#dd2222");

  vox(gx,gy,5,"#eeeeee"); // 投信口

}


/* 长椅 */

function drawBench(gx,gy){

  // 腿

  vox(gx,gy,0,"#8b6340"); vox(gx,gy,1,"#8b6340");

  vox(gx+3,gy,0,"#8b6340"); vox(gx+3,gy,1,"#8b6340");

  // 座板

  for(let c=0;c<=3;c++) vox(gx+c,gy,2,"#a0784a");

  // 靠背

  for(let c=0;c<=3;c++) vox(gx+c,gy,3,"#a0784a");

  for(let c=0;c<=3;c++) vox(gx+c,gy,4,"#a0784a");

}


/* 花朵 */

function drawFlower(gx,gy,col){

  vox(gx,gy,0,"#2e8b44"); // 茎

  vox(gx,gy,1,"#2e8b44");

  vox(gx,gy,2,col);       // 花

  vox(gx-1,gy,2,col);

  vox(gx+1,gy,2,col);

  vox(gx,gy-1,2,col);

  vox(gx,gy+1,2,col);

  vox(gx,gy,3,"#ffee44"); // 花心

}


/* 蝴蝶 */

function drawButterfly(gx,gy,gz,t){

  const flapW = Math.round(Math.sin(t*0.08)*1.5);

  vox(gx,gy,gz,"#ff6622");

  vox(gx-1+flapW,gy,gz,"#ff8833");

  vox(gx+1-flapW,gy,gz,"#ff8833");

  vox(gx,gy,gz+1,"#111111");

}


/* 海鸥 */

function drawSeagull(gx,gy,gz,t){

  const flap = Math.round(Math.sin(t*0.06+gx)*1);

  vox(gx,gy,gz,"#f5f5f5");

  vox(gx-2,gy,gz-flap,"#e0e0e0");

  vox(gx-1,gy,gz-flap,"#eeeeee");

  vox(gx+1,gy,gz-flap,"#eeeeee");

  vox(gx+2,gy,gz-flap,"#e0e0e0");

  vox(gx,gy,gz,"#ffcc88"); // 嘴

}


/* ─────────────── 主渲染循环 ─────────────── */

let t = 0;


function render(){

  t++;


  /* 1. 天空 */

  drawSky();

  drawSun();


  /* 2. 云 */

  drawCloud(60+Math.sin(t*0.002)*15, 40, 1.4);

  drawCloud(280+Math.sin(t*0.0015)*20, 20, 1.1);

  drawCloud(530+Math.sin(t*0.0018)*12, 55, 1.6);

  drawCloud(740+Math.sin(t*0.0012)*18, 30, 1.0);


  /* 3. 地面 */

  drawGround();


  /* 4. 体素层:坐标系原点投射到道路中央 */

  // 远处树

  drawTree(-18, 5);

  drawTree(-12, 7);

  drawTree(12,   6);

  drawTree(18,   8);

  drawTree(20,   4);

  drawTree(-20, 3);


  // 路灯

  drawLamp(-10, 3);

  drawLamp( 10, 3);


  // 长椅(路边)

  drawBench(-7, 5);

  drawBench( 8, 5);


  // 邮筒

  drawMailbox(-14, 4);


  // 指示牌

  drawSign(13, 4);


  // 路边花朵

  const flowerCols=["#ff4466","#ff8833","#ffee22","#aa44ff","#22ccff"];

  for(let i=-8;i<=8;i++){

    drawFlower(i*2.5|0, 5, flowerCols[((i+8)%5)]);

    drawFlower(i*2.5|0, -6, flowerCols[((i+5)%5)]);

  }


  // 蝴蝶(2只)

  drawButterfly(-3, 4, 4, t);

  drawButterfly( 5, 5, 6, t+30);


  // 海鸥(远处)

  drawSeagull(-15,-8,14,t);

  drawSeagull( 10,-9,12,t);

  drawSeagull(   2,-11,16,t);


  /* 5. 自行车(动画) */

  const wheelRot = t * 0.05;

  drawBicycle(-2, 3, wheelRot);


  /* 6. 鹈鹕(骑在车上) */

  drawPelican(-2, 8, t);


  requestAnimationFrame(render);

}


requestAnimationFrame(render);


})();

</script>

</body>

</html>


运行起来,是一张图片,无法动起来。


那这两个代码有什么区别呢,我看不懂,所以我去问了 DeepSeek V4。


我的问题是:请问这两篇代码有什么不一样,区别在哪?为什么一个能运行动态效果,一个不可以,两个都是用同一个指令生成出来的代码。


DeepSeek V4给我回答了不同之处。


比如渲染方式上,一个是 2D Canvas + 多边形模拟体素(等距投影,手动计算每个面的颜色和阴影);一个是逐个绘制立方体(每个体素画三个面),用类似体素构建的简单块状风格。


绘制顺序上,一个是手工排序:背景 → 地面 → 建筑 → 阴影 → 自行车 → 鹈鹉 → 前景特效,遮挡正确;另一个则无排序,后绘制的体素直接覆盖先绘制的,导致视觉混乱。


关于为什么 Claude opus 4.7 的代码块不能动,有以下几个原因。


1、车轮动画失效


// 第二个代码中的 drawWheel 片段

function drawWheel(wx, wy, r, rot, tireCol, rimCol, hubCol){

  for(let i=0;i<pts;i++){

    const a = i*Math.PI*2/pts;

    const gx = wx + Math.round(Math.cos(a)*r);

    const gz = wy + Math.round(Math.sin(a)*r);

    vox(gx, 0, gz, tireCol);   // ❌ 第二个参数 0 表示 gy 坐标,但这里本应是车轮的高度

  }

  // 辐条同理……

}


问题:vox(gx, 0, gz) 中 gy=0 固定,gz 被当作深度(实际应为高度)。


后果:车轮的每个“块”都绘制在地面高度 gy=0 的同一个水平面上,形成一个平躺的圆环,而不是竖直的轮子。


旋转效果:rot 参数虽然随时间变化,但它只影响辐条位置,而辐条同样使用错误的坐标系,最终画面看不到正常的车轮转动。


2、翅膀动画偏移可能导致不可见


问题:扑翼应该改变翅膀的横向或纵向位置,但这里修改了 z(高度),相当于翅膀上下移动,且 drawLayer 内部调用 vox 时 z 作为高度参数,会导致翅膀整体升高或降低,脱离身体。


后果:看起来像翅膀“瞬移”而非扇动,且可能超出画布或与其他体素重叠混乱。


3、缺乏深度排序

第二个代码中,自行车、鹈鹕、树木、建筑等没有按“远→近”顺序绘制。后绘制的物体会完全覆盖先绘制的,即使它在逻辑上应该被遮挡。


例如:鹈鹕的后半身体可能被前轮遮挡,或者车把被鹈鹕的肚子覆盖,视觉上非常杂乱,动态效果难以辨认。


4.、潜在的错误与性能问题

drawPelican 中多处使用 0-1 这样的表达式作为偏移量(如 px-3,0-2),虽然 JavaScript 会计算为 -2,但容易误导阅读。


drawLayer 内部没有边界检查,负坐标的体素会被绘制到画布外,浪费性能。


大量密集的 vox 调用(每个体素绘制多个路径和填充)导致每帧操作过多,若同时存在动画计算,可能造成卡顿或掉帧,使得动态变化更不明显。


那为什么第一个代码能完美运行呢?他有:

正确的等距投影:iso(x,y,z) 统一转换,所有物体都基于同一个世界坐标系。


严格的绘制顺序:背景 → 地面 → 建筑 → 阴影 → 自行车 → 鹈鹕 → 粒子效果,前后遮挡正确。


清晰的动画变量:t 随时间线性增长,车轮旋转用 rot = -t * 3.6,鹈鹕弹跳用 bounce = Math.sin(t*4)*2,云移动用 (t * 9) % 250,简单可靠。


高效渲染:只绘制可见的多边形面,没有逐个体素绘制,复杂度低,动画流畅。


细节丰富且可交互:鼠标拖拽平移视角,动态海浪、旗帜飘动、车篮里的鱼跳动等,所有效果都肉眼可见。


写到这里,其实可以明显的看出,相同的指令交给不同的 AI 模型,实现质量差异巨大。


第二个代码虽然结构完整,但坐标系设计失误和绘制顺序缺失导致动态效果完全失效。


第一个代码则正确运用了等距投影、深度排序和基于时间的动画,因此能够呈现出预期的“鹈鹕骑自行车”的生动体素艺术场景。


当然我这个只是一个个例,不能就此说明,GPT 5.5 比 Claude   Opus 4.7 强。大模型一直在进步中,人也是。


期待所有大模型百花齐放。




Nebula Data 星雲數據,总部位于新加坡,在雅加达、广州、上海、香港设有分支机构。公司自主研发 Nebula Lab 一站式 AI 内容生成与模型聚合平台,搭载企业级 AI Agent,聚合全球通用大模型与行业垂直模型;同步推出 Nebula AIoT 硬件生态体系(含智能交互终端、物联网网关等产品),形成 “云 - 边 - 端” 全链路智能解决方案,为电商、制造、零售等多领域客户提供从云端算力支撑、AI 智能决策到终端场景落地的一体化服务;同时提供全球 AIDC(AI 智算中心)+ 低延迟网络服务,以技术底座赋能企业拥抱 AI、链接物理世界,拓展全球业务。