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

mousePressed()触发异常:鼠标悬停即执行而非点击的问题求助

音乐播放器mousePressed()函数异常触发问题求助

开发一款包含上一曲、停止、下一曲三个按钮的音乐播放器,期望通过mousePressed()函数实现点击停止按钮时暂停音频播放,但目前遇到异常:mousePressed()函数并非在点击时触发,只要鼠标悬停在定义的按钮区域就会执行,更换区域后问题仍存在。

以下是我的代码:

import processing.serial.*;
import processing.sound.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import cc.arduino.*;

Arduino arduino;
Serial myPort;

Minim minim;
AudioPlayer song;
AudioMetaData meta;

Amplitude amp;
AudioIn in;

BeatDetect beat;
BeatListener bl;

SoundFile now_playing;
Waveform waveform;

float DEFAULT_VOL_AMP = 1;


PFont poppins;
PImage prevIcon, playIcon, nextIcon;
boolean prevPressed, playPressed, nextPressed = false;

// ----- songs & waveform -----
String songs[] = {"song1.mp3",
                  "song2.mp3", 
                  "song3.mp3", 
                  "song4.mp3", 
                  "song5.mp3", 
                  "song6.mp3"};
int songsLength = songs.length;
int pointer = 2;

String decibelsLevel = "";
int samples = 60000; // detail waveform
boolean displayWarning = false;
String warning = "WARNING! \n Your song is too loud, it can damage your hearing.";

int prevX, prevY, playX, playY, nextX, nextY, iPrevX, iPrevY, iPlayX, iPlayY, iNextX, iNextY; // posisi x & y dari masing-masing button
int btnSize = 72;
color btnColor, prevBtnColor, playBtnColor, nextBtnColor;


public void setup() {
  size(800, 500);
  poppins = createFont("poppins-regular.ttf", 22);
  textFont(poppins);

  // waveform
  now_playing = new SoundFile(this, songs[pointer]);
  now_playing.loop();
  waveform = new Waveform(this, samples);
  waveform.input(now_playing);
  now_playing.amp(DEFAULT_VOL_AMP);
  
  // scans amplitude level
  amp = new Amplitude(this); in = new AudioIn(this, 0);
  in.start();
  amp.input(now_playing);
  
  // getting song's metadata
  minim = new Minim(this);
  song = minim.loadFile(songs[pointer]);
  meta = song.getMetaData();
  
  // buttons & icons
  btnColor = color(85,103,186);
  prevBtnColor = color(85,103,186);
  prevX = 300; iPrevX = prevX - 25;
  prevY = 400; iPrevY = prevY - 25;
  prevIcon = loadImage("icon_previous.png");
  
  playBtnColor = color(85,103,186); 
  playX = 400; iPlayX = playX - 15;
  playY = 400; iPlayY = playY - 18;
  playIcon = loadImage("icon_play.png");

  
  nextBtnColor = color(85,103,186);
  nextX = 500; iNextX = nextX - 25;
  nextY = 400; iNextY = nextY - 25;
  nextIcon = loadImage("icon_next.png");

}

public void draw() {

  background(49, 65, 161); // blue 
  AmplitudeLevel();
  Waveform();
  
  if (amp.analyze() > 2){
    DisplayWarning();
  }
  else {
    SongDesc();
  }
  
  Buttons();
 mousePressed();
}

public void mousePressed(){
  // prevBtn position
  if (mouseX > prevX-btnSize && mouseX < prevX+btnSize && mouseY > prevY-btnSize && mouseY < prevY+btnSize){
    if (songs[pointer-1] != null) {
      pointer--;
    }
    else {
      pointer = songsLength - 1;
    }
      
  }
  // stopBtn position
  else if (mouseX > playX-btnSize && mouseX < playX+btnSize && mouseY > playY-btnSize && mouseY < playY+btnSize){
    now_playing.stop();
  }
  // nextBtn position
  else if (mouseX > nextX-btnSize && mouseX < nextX+btnSize && mouseY > nextY-btnSize && mouseY < nextY+btnSize){
    if (songs[pointer + 1] != null) {
      pointer++;
    }
    else {
      pointer = 0;
    }
  }
}

我还尝试了如下调试代码,但未触发任何鼠标事件时仍打印出“pressed”:

boolean alreadyPressed = false;
public void mousePressed(){
  if (!alreadyPressed) {
    println("pressed");
    alreadyPressed = true;
  }
}

解决方案

问题根源在于你在draw()函数中手动调用了mousePressed()方法。Processing的draw()函数会以默认60帧/秒的频率循环执行,这意味着每帧都会触发一次mousePressed()逻辑,只要鼠标处于按钮区域内,就会持续执行对应代码,造成“悬停即触发”的假象。

解决步骤:

  • 删除draw()函数中的mousePressed();这一行代码

Processing的mousePressed()是内置事件回调函数,不需要手动调用。当用户在窗口内点击鼠标时,系统会自动触发该函数,此时再判断鼠标位置是否在按钮区域内即可实现预期的点击交互。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:50:26