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

p5.js中display()方法无法显示图片:类移出draw函数后图像消失问题

问题解决:Drumcircle类移到draw外后图像不显示的问题

你的代码存在几个关键问题导致图像无法显示,逐一修正即可解决:

1. 未实例化Drumcircle对象

你已经声明了let drum;,但没有在setup()中创建类的实例。需要在setup里初始化对象,传入正确的坐标和尺寸:

function setup() {
  createCanvas(500, 500);
  
  drumSound.playMode('restart');
  volSlider = createSlider(0, 1, .5, 0.01);
  volSlider.position(130,40);
  
  // 实例化Drumcircle,传入初始坐标和尺寸
  drum = new Drumcircle(width/2 - 150, height/2 - 150, 300, 300);
}

2. 修正Drumcircle类的构造函数与属性

构造函数未接收sizeX和sizeY参数,且this.drum应该在构造函数中直接赋值,无需等到clicked方法触发:

class Drumcircle{
  constructor(x,y, sizeX, sizeY){
    this.name ='drumCircle';
    this.x = x;
    this.y = y;
    this.sizeX = sizeX;
    this.sizeY = sizeY;
    this.drum = drumImg; // 直接在构造函数绑定图像资源
  }
  
  clicked(x,y){
    // 整合点击交互逻辑到类方法中
    let radialDistance = dist(x,y, this.x + this.sizeX/2, this.y + this.sizeY/2);
    if(radialDistance < this.sizeX/2){
      drumSound.play();
      print('play drum');
    } else{ 
      print('silence');
    }    
  }
  
  display(){
    image(this.drum, this.x, this.y, this.sizeX, this.sizeY);
  }
}

3. 在draw()中调用display方法

要让图像持续显示,必须在draw()循环里调用drum.display():

function draw() {
  background(0, 24, 25);
  drumSound.setVolume(volSlider.value());
  
  let volText = 'Volume';
  textSize(12);
  fill(255);
  stroke(0);
  strokeWeight(2);
  text(volText, 85, 45, 70, 80);
  
  // 调用display方法渲染图像
  drum.display();
}

4. 简化点击交互逻辑

将原有的mousePressed和checkIntersection简化,直接调用类的clicked方法:

function mousePressed(){
  drum.clicked(mouseX, mouseY);
}

完整修正后的代码

let drumImg;
let drum;
let drumSound;
let volSlider;

function preload(){
  drumSound = loadSound('HandDrum.mp3');
  drumImg = loadImage('handdrum2.png');
}

function setup() {
  createCanvas(500, 500);
  
  drumSound.playMode('restart');
  volSlider = createSlider(0, 1, .5, 0.01);
  volSlider.position(130,40);
  
  // 实例化Drumcircle对象
  drum = new Drumcircle(width/2 - 150, height/2 - 150, 300, 300);
}

function mousePressed(){
  drum.clicked(mouseX, mouseY);
}

class Drumcircle{
  constructor(x,y, sizeX, sizeY){
    this.name ='drumCircle';
    this.x = x;
    this.y = y;
    this.sizeX = sizeX;
    this.sizeY = sizeY;
    this.drum = drumImg;
  }
  
  clicked(x,y){
    // 计算点击位置到图像中心的距离
    let radialDistance = dist(x,y, this.x + this.sizeX/2, this.y + this.sizeY/2);
    if(radialDistance < this.sizeX/2){
      drumSound.play();
      print('play drum');
    } else{ 
      print('silence');
    }    
  }
  
  display(){
    image(this.drum, this.x, this.y, this.sizeX, this.sizeY);
  }
}

function draw() {
  background(0, 24, 25);
  drumSound.setVolume(volSlider.value());
  
  let volText = 'Volume';
  textSize(12);
  fill(255);
  stroke(0);
  strokeWeight(2);
  text(volText, 85, 45, 70, 80);
  
  drum.display();
}

核心要点总结

  • 类的定义放在**全局作用域(draw函数外)**是正确的,无需嵌套在任何函数内
  • 必须实例化类对象,才能调用类的属性和方法
  • 要在draw()循环中调用display(),保证图像持续渲染到画布上
  • 类的核心属性(如图像、坐标)应在构造函数中初始化,确保对象创建时就具备必要数据

内容的提问来源于stack exchange,提问作者K-PopCorn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:00:14