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

Processing中Void Draw交互异常:点击图形切换昼夜后消失

问题根源

你的代码存在两个核心问题:

  • Processing的draw()是持续循环刷新的(默认每秒60次),mousePressed()里直接画的红圆只会在当前帧显示,下一次draw刷新就会被新绘制的场景覆盖。
  • 切换昼夜时,draw()里直接重绘了整个背景和场景,完全覆盖之前的红圆,而且没有保存这些红圆的位置,所以切换后红圆直接消失。
修复方案

核心思路是保存所有红圆的坐标,每次draw时先绘制昼夜场景,再重新画出所有保存的红圆。同时优化模式切换的逻辑,避免重复触发重绘:

完整修复代码

// 全局变量:存储所有红圆的坐标
ArrayList<PVector> circles = new ArrayList<PVector>();
// 标记当前是否为夜晚模式
boolean isNight = false;

void setup() {
  size(500,500);
  // 初始化默认白天场景
  drawDayScene();
}

void draw() {
  // 根据当前模式绘制场景
  if (isNight) {
    drawNightScene();
  } else {
    drawDayScene();
  }
  
  // 绘制所有保存的红圆
  fill(#FF0000);
  noStroke();
  for (PVector circle : circles) {
    circle(circle.x, circle.y, 50);
  }
}

// 白天场景绘制函数
void drawDayScene() {
  background(#87ceeb);
  fill(#567d46);
  rect(0,height/2,500,height/2);
  fill(#FFA500);
  circle(50,50,75);
  // Cloud 1
  noStroke();
  fill(#FFFFFF);
  circle(335,50,50);
  circle(300,50,35);
  circle(370,50,35);
  circle(335,75,50);
  circle(300,75,35);
  circle(370,75,35);
  // Cloud 2
  circle(200,50,50);
  circle(165,50,35);
  circle(235,50,35);
  // Bush 1
  fill(#112A12);
  circle(100,425,50);
  circle(65,425,35);
  circle(135,425,35);
  circle(100,450,50);
  circle(65,450,35);
  circle(135,450,35);
  // Bush 2
  circle(400,250,50);
  circle(365,250,35);
  circle(435,250,35);
  // Path
  fill(#d9b99b);
  rect(0,300,width,75);
  // Post
  fill(#563d2d);
  rect(20,225,35,15);
  fill(#5C4033);
  rect(50,200,15,100);
  fill(#563d2d);
  rect(65,210,35,15);
}

// 夜晚场景绘制函数
void drawNightScene() {
  background(#040348);
  fill(#006400);
  rect(0,height/2,500,height/2);
  // Moon
  fill(#d3d3d3);
  circle(450,50,75);
  fill(#808080);
  circle(435,35,15);
  circle(450,65,25);
  // Rock
  rect(365,190,100,100);
  rect(350,280,130,20);
  fill(#563d2d);
  rect(365,300,100,85);
  textSize(35);
  fill(#d3d3d3);
  text("RIP",390,235);
  // Tree
  fill(#563d2d);
  rect(60,140,75,200);
  fill(#154734);
  rect(25,150,145,75);
  rect(35,125,125,75);
  // Stars
  fill(#ffff00);
  circle(75,50,10);
  circle(135,80,10);
  circle(225,65,10);
  circle(275,200,10);
  circle(300,150,10);
  circle(330,20,10);
  // Path
  fill(#AC9362);
  rect(0,400,width,75);
}

void keyPressed() {
  // 按n切换夜晚,d切换白天
  if (key == 'n') {
    isNight = true;
  } else if (key == 'd') {
    isNight = false;
  }
}

void mousePressed() {
  // 把当前鼠标位置添加到红圆列表
  circles.add(new PVector(mouseX, mouseY));
}

关键修改点说明

  1. 用ArrayList保存红圆坐标:全局声明ArrayList<PVector>来存储每个红圆的x、y坐标,这样所有绘制过的红圆位置都不会丢失。
  2. 拆分场景绘制为独立函数:把白天和夜晚的绘制逻辑拆成drawDayScene()和drawNightScene(),让代码更清晰,避免重复代码。
  3. 用keyPressed()处理模式切换:原来在draw()里判断key变量会导致持续触发重绘,改用keyPressed()事件,只在按键瞬间切换模式标记,避免不必要的重复绘制。
  4. draw()里最后绘制所有红圆:每次刷新画面时,先画昼夜场景,再遍历列表画出所有保存的红圆,这样红圆会始终显示在场景上方,不会被覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:10:56