You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何制作带动画的交通灯?3秒颜色切换代码实现失败求助

问题分析与修复方案

你的代码存在几个关键问题,导致交通灯切换逻辑失效:

核心问题

  1. 计数逻辑不可靠:用x+=10在draw循环里计数,依赖draw的帧率(默认60fps的话,每秒x仅增加600),无法精准对应3秒的时间;而且x == 3000这种精确判断很容易因为帧率波动错过触发条件。
  2. setTimeout与绘图循环冲突:draw循环是同步持续执行的,异步的setTimeout会导致颜色更新时机和绘图渲染不同步,出现延迟或状态混乱。
  3. 状态切换逻辑错误:比如红灯阶段,你先直接把红灯设为black,再延迟3秒亮黄灯,这会导致中间3秒全黑,不符合「红灯维持3秒后切黄灯」的需求。

修复后的代码(基于p5.js)

let trafficState = "OFF"; // OFF:全黑, RED:红灯, YELLOW:黄灯, GREEN:绿灯
let stateStartTime = 0;
const STATE_DURATION = 3000; // 每个状态持续3秒

function setup() {
  createCanvas(400, 150);
  stateStartTime = millis();
}

function draw() {
  background(220);
  
  // 绘制交通灯外壳
  fill(50);
  rect(300, 20, 30, 80);
  
  // 根据当前状态设置灯的颜色
  let redColor = trafficState === "RED" ? "red" : "black";
  let yellowColor = trafficState === "YELLOW" ? "yellow" : "black";
  let greenColor = trafficState === "GREEN" ? "green" : "black";
  
  // 绘制三个灯
  fill(redColor);
  ellipse(315, 40, 20, 20);
  fill(yellowColor);
  ellipse(315, 65, 20, 20);
  fill(greenColor);
  ellipse(315, 90, 20, 20);
  
  // 状态切换逻辑
  let elapsedTime = millis() - stateStartTime;
  if (elapsedTime >= STATE_DURATION) {
    switch(trafficState) {
      case "OFF":
        trafficState = "RED";
        break;
      case "RED":
        trafficState = "YELLOW";
        break;
      case "YELLOW":
        trafficState = "GREEN";
        break;
      case "GREEN":
        trafficState = "RED"; // 绿灯后回到红灯,可按需调整
        break;
    }
    stateStartTime = millis(); // 重置当前状态的开始时间
  }
}

修复说明

  • 用millis()精准计时:millis()获取程序运行的毫秒数,计算每个状态的持续时间,完全不受帧率影响,计时精准。
  • 状态机管理:用trafficState变量明确当前交通灯状态,逻辑清晰,避免复杂的多条件判断。
  • 同步更新颜色:在draw循环里直接根据当前状态设置灯的颜色,和渲染完全同步,不会出现异步延迟问题。
  • 自动循环切换:绿灯之后会自动切回红灯,形成完整的交通灯循环,你可以根据需求修改最后一个case的逻辑。

内容的提问来源于stack exchange,提问作者Jun Wei Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:07:44