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

p5.js类中变量仅函数内定义生效?求类内全局复用方案

问题原因与修复方案

你的代码核心问题有两个:

  1. 未定义buttonwidth属性:你在updateAA和mouseClicked方法中使用了this.buttonwidth,但构造函数里只定义了buttonlength,没有初始化buttonwidth,导致这个值为undefined,鼠标hover和点击的判断逻辑完全失效。
  2. 绘制按钮时使用硬编码值:display方法里绘制按钮的rect()用的是固定数值189, 189, 50, 25,没有引用类中定义的this.x1、this.y1等属性,所以即使你修改类属性,按钮的位置和大小也不会变化。

另外,还有一个优化点:不要在draw()循环里调用mouseClicked()方法,应该利用p5.js原生的mouseClicked全局事件函数,否则每帧都会执行点击判断,可能导致重复触发逻辑。

修正后的完整代码

class Buttons {
  constructor() {
    this.rectOver = false;
    this.x1 = 189;
    this.y1 = 189;
    this.textspacingx = 14;
    this.textspacingy = 22;
    this.buttonlength = 50;
    // 新增buttonwidth属性初始化
    this.buttonwidth = 25;
  }
  
  table() {
    strokeWeight(0.5);
    fill(255);
    stroke(0);
    rect(120, 130, 230, 160);
  }
  
  range() {
    text("Low", 145, 210 );
    text("Mid", 145, 245 );
    text("High", 145, 280 );
    push();
    let angle2 = radians(270);
    translate(140, 260);
    rotate(angle2);
    let nuclear = createFont("Avenir-Light", 20);
    textFont(nuclear, 20);
    fill(0);
    textAlign(LEFT);
    text("Climate", 0, 0);
    pop();
    text("Low", 195, 185 );
    text("Mid", 250, 185 );
    text("High", 305, 185 );
    text("Nuclear", 230, 155 );
  }
  
  display() {
    this.updateAA(mouseX, mouseY);
    fill(this.rectOver ? 200 : 220);
    stroke(200);
    // 改用类属性绘制按钮
    rect(this.x1, this.y1, this.buttonlength, this.buttonwidth, 2);
    fill(0);
  }

  updateAA(x, y) {
    this.rectOver = this.overRectAA(this.x1, this.y1, this.buttonlength, this.buttonwidth);
  }
  
  overRectAA(x, y, width, height) {
    return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
  }

  mouseClicked() {
    if (this.overRectAA(this.x1, this.y1, this.buttonlength, this.buttonwidth)) {
      // 这里确保scenarioA已经正确定义
      scenarioA.scenarioAA();
    } 
  }
}

let buttonAA;
let scenarioA = {
  scenarioAA: function() {
    console.log("按钮AA被点击");
  }
};

function setup() {
  createCanvas(800, 800);
  buttonAA = new Buttons();
}

function draw() {
  background(255);
  buttonAA.table();
  buttonAA.display();
  buttonAA.range();
}

// 使用p5.js原生鼠标点击事件
function mouseClicked() {
  buttonAA.mouseClicked();
}

关键修改说明

  • 在构造函数中添加this.buttonwidth = 25;,补全缺失的属性
  • 将display里的rect()参数替换为类的实例属性,确保按钮的位置大小和类属性同步
  • 简化updateAA的逻辑,直接赋值this.rectOver,代码更简洁
  • 把mouseClicked的调用移到p5.js原生事件函数中,避免每帧重复执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:17:42