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)); }
关键修改点说明
- 用ArrayList保存红圆坐标:全局声明
ArrayList<PVector>来存储每个红圆的x、y坐标,这样所有绘制过的红圆位置都不会丢失。 - 拆分场景绘制为独立函数:把白天和夜晚的绘制逻辑拆成
drawDayScene()和drawNightScene(),让代码更清晰,避免重复代码。 - 用keyPressed()处理模式切换:原来在
draw()里判断key变量会导致持续触发重绘,改用keyPressed()事件,只在按键瞬间切换模式标记,避免不必要的重复绘制。 - draw()里最后绘制所有红圆:每次刷新画面时,先画昼夜场景,再遍历列表画出所有保存的红圆,这样红圆会始终显示在场景上方,不会被覆盖。
内容的提问来源于stack exchange,提问作者Arsalan Atif
相关产品推荐
相关产品推荐

