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

如何停止P5.js数组中已创建3D对象的旋转?

解决P5.js中新增形状后停止旧形状旋转的问题

你的核心问题是所有形状都依赖全局的frameCount计算旋转角度,导致只要帧在更新,所有形状都会持续旋转。要实现新增形状时旧形状停止旋转,得给每个形状单独记录自己的旋转状态和角度,具体修改如下:

修改思路

  • 给每个Shape实例添加独立的旋转角度变量和旋转开关,替代全局的frameCount
  • 新增形状时,关闭所有已存在形状的旋转开关

修改后的完整代码

let BLACK;
let GRAY;
let LIGHTGRAY;
let WHITE;
let RED;
let forms = [];
let coorX, coorY, coorZ, colour;
let COL = [];
let ran;

function setup() {
  createCanvas(586, 810, WEBGL);
  BLACK = color(0);
  GRAY = color(70);
  LIGHTGRAY = color(180);
  WHITE = color(255);
  RED = color(217, 4, 33);
  COL = [BLACK, WHITE, GRAY, RED, RED];
  ran = random(0.01, 0.1);
}

function draw() {
  background(80);
  pointLight(250, 250, 250, 250);
  for (let i = 0; i < forms.length; i++) {
    let newSpeed = 0.05 + i * ran;
    forms[i].update(newSpeed, 0.01);
    forms[i].draw();
  }
  if (forms.length > 10) {
    // 限制数组最多10个对象
    forms.splice(0, 1);
  }
}

function keyTyped() {
  if (key === 'a') {
    // 新增形状前,关闭所有已有形状的旋转
    forms.forEach(shape => shape.isRotating = false);
    
    coorX = int(random(-100, 100));
    coorY = int(random(-100, 100));
    coorZ = int(random(-200, 200));
    forms.push(new Shape(coorX, coorY, coorZ));
  }
  if (key === 'd') {
    forms.pop();
  }
}

class Shape {
  constructor(posX, posY, posZ, colour) {
    this.x = 50; // 宽度
    this.y = 50; // 高度
    this.z = 50; // 深度
    this.posX = posX;
    this.posY = posY;
    this.posZ = posZ;
    this.rand = int(random(0, 5));
    this.colour = colour;
    // 独立的旋转角度变量
    this.rotX = 0;
    this.rotY = 0;
    // 旋转开关,默认开启
    this.isRotating = true;
  }
  
  // 更新旋转状态
  update(speed, rotationStep) {
    if (this.isRotating) {
      // 仅开启旋转时更新角度
      this.rotX += rotationStep * speed;
      this.rotY += rotationStep * speed;
    }
  }
  
  // 绘制形状
  draw() {
    stroke(0);
    strokeWeight(0);
    push();
    translate(this.posX, this.posY, this.posZ);
    // 使用自身的旋转角度,不再依赖全局frameCount
    rotateX(this.rotX);
    rotateY(this.rotY);
    
    switch(this.rand) {
      case 1:
        fill(RED);
        box(50, 50, 50);
        break;
      case 2:
        fill(LIGHTGRAY);
        sphere(50, 10);
        break;
      case 3:
        fill(WHITE);
        cylinder(5, 280, 15);
        break;
      case 4:
        fill(GRAY);
        torus(90, 24, 3);
        break;
    }
    pop();
  }
}

关键改动说明

  1. 拆分方法职责:把原create方法拆成update(更新旋转状态)和draw(绘制形状),逻辑更清晰
  2. 独立旋转控制:每个形状用rotX/rotY记录自身旋转角度,用isRotating开关控制是否继续旋转
  3. 新增形状时关闭旧旋转:按'A'键新增前,遍历已有形状并关闭它们的旋转开关,实现旧形状停止旋转的效果
  4. 优化条件判断:用switch替代多个if,代码更整洁易读

内容的提问来源于stack exchange,提问作者NoEl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:50:21