Processing中实现全屏竖线按行数动态等分拆分的技术求助
解决方案:实现动态等分的对讲机式音频可视化
针对你的需求,我重构了代码,实现了全屏竖线覆盖+每行填满后动态等分屏幕的效果,同时保留对讲机式的说话方切换逻辑。以下是核心修改点和完整代码:
核心修改说明
- 用
keyPressed事件替代draw中的按键检测,避免重复触发导致的绘制异常 - 新增行计数与动态行高计算,实现每行填满后自动将屏幕等分为
总行数+1份 - 通过画面缩放保留历史对话的可视化内容,新行自动占据等分后的新区域
- 统一管理两个说话方的配色方案,简化代码逻辑
- 增加交互提示(初始引导、行填满提示)
完整修改代码
import processing.sound.*; AudioIn input; Amplitude amp; // 说话方标识:0=A(蓝色系),1=L(橙色系),-1=未开始 int currentSpeaker = -1; int currentX = 0; // 当前绘制的横向像素位置 int rowCount = 1; // 当前总行数 float rowHeight; // 每行的高度(动态计算) // 两个说话方的配色方案 color[] highColors = {color(72, 16, 255), color(255, 128, 16)}; color[] lowColors = {color(179, 155, 255), color(255, 203, 156)}; color midColor; // 中间音量的过渡色 void setup() { size(1440, 846); background(255); pixelDensity(displayDensity()); // 初始化音频输入 input = new AudioIn(this, 0); input.start(); amp = new Amplitude(this); amp.input(input); // 初始行高为全屏高度 rowHeight = height / (float)rowCount; } void keyPressed() { // 切换到A说话方 if (key == 'a' || key == 'A') { currentSpeaker = 0; handleRowCompletion(); midColor = lerpColor(lowColors[currentSpeaker], highColors[currentSpeaker], 0.5); } // 切换到L说话方 else if (key == 'l' || key == 'L') { currentSpeaker = 1; handleRowCompletion(); midColor = lerpColor(lowColors[currentSpeaker], highColors[currentSpeaker], 0.5); } } // 处理当前行填满后的逻辑:新增行+缩放历史画面 void handleRowCompletion() { if (currentX >= width) { rowCount++; currentX = 0; rowHeight = height / (float)rowCount; // 将历史画面缩放到上方(rowCount-1)/rowCount区域,为新行腾出空间 if (rowCount > 1) { PImage history = get(0, 0, width, height); background(255); image(history, 0, 0, width, height * (rowCount-1)/rowCount); } } } void draw() { // 初始引导提示 if (currentSpeaker == -1) { background(255); textSize(40); fill(0); textAlign(CENTER, CENTER); text("按A或L切换说话方开始录制", width/2, height/2); return; } // 获取当前音量并映射到颜色等级 float volume = amp.analyze(); int colorLevel = int(map(volume, 0, 0.05, 0, 3)); noFill(); strokeCap(SQUARE); // 根据音量设置线条颜色 switch(colorLevel) { case 0: stroke(255); break; // 静音:背景色,不显示线条 case 1: stroke(lowColors[currentSpeaker]); break; case 2: stroke(midColor); break; case 3: stroke(highColors[currentSpeaker]); break; } // 绘制当前行的竖线(从当前行顶部到底部) float currentRowTop = height - rowHeight; line(currentX, currentRowTop, currentX, height); currentX++; // 当前行填满后的提示 if (currentX >= width) { textSize(40); fill(0); textAlign(CENTER, CENTER); text("当前行已填满,按A/L切换说话方继续", width/2, currentRowTop + rowHeight/2); } }
功能说明
- 初始状态:屏幕显示引导文字,按
A或L切换到对应说话方 - 实时绘制:根据麦克风输入的音量,绘制对应颜色的竖线,从左到右填充当前行
- 行填满逻辑:当一行横向填满全屏后,按任意说话方按键,会将历史画面缩放到屏幕上方的
(总行数-1)/总行数区域,新行占据下方的1/总行数区域 - 对讲机切换:全程可通过
A/L键随时切换说话方,切换后继续在当前行绘制对应色系的可视化线条
内容的提问来源于stack exchange,提问作者Massimo Bertoldo
相关产品推荐
相关产品推荐

