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

p5.js中调用menuMusic.play()出现undefined错误的技术求助

问题解决:调用menuMusic.play()出现undefined错误

问题根源

你用loadSound在setup中加载音频,但loadSound是异步操作——它不会立刻完成音频文件的加载,而draw函数会在setup执行后立即开始循环运行。当第一帧draw执行时,menuMusic和backgroundMusic可能还没完成初始化,此时调用play()自然会抛出undefined错误。

另外,代码里menuMusic和backgroundMusic没有用var/let/const声明,虽然浏览器会自动提升为全局变量,但这不是规范写法,也可能引发潜在问题。

解决方案

1. 使用preload函数加载音频

p5.js的preload函数会在setup和draw之前执行,并且会等待所有加载操作完成后才继续后续代码,完美解决异步加载的问题。

2. 规范变量声明

给音频变量添加声明,避免全局变量污染,同时让代码更清晰。

3. 优化状态判断逻辑

用else if合并互斥的判断条件,减少冗余代码,同时避免不必要的音频状态检查。

修改后的完整代码

// 声明变量
let menu = 0; // 0=主菜单,1=选关,2=游戏中,3=死亡,4=关卡完成,5= credits
let playedMenuMusic = false;
let playedBackgroundMusic = false;
let menuMusic;
let backgroundMusic;

// 预加载音频,确保setup执行前加载完成
function preload() {
  menuMusic = loadSound("centaur-forest-60695.mp3");
  backgroundMusic = loadSound("8bit-music-for-game-68698.mp3");
}

function setup() {
  // 这里可以添加画布初始化等其他代码
}

function draw() {
  // 游戏中或credits界面,播放背景音乐
  if ((menu === 2 || menu === 5) && !backgroundMusic.isPlaying() && !playedBackgroundMusic) {
    backgroundMusic.play();
    playedBackgroundMusic = true;
    menuMusic.stop();
    playedMenuMusic = false;
  } 
  // 其他界面播放菜单音乐
  else if ((menu === 0 || menu === 1 || menu === 3 || menu === 4) && !menuMusic.isPlaying() && !playedMenuMusic) {
    menuMusic.play();
    playedMenuMusic = true;
    backgroundMusic.stop();
    playedBackgroundMusic = false;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/addons/p5.sound.min.js"></script>

额外注意事项

  • 确保音频文件路径正确,浏览器能访问到对应的mp3文件
  • 如果音频加载慢,可以在preload阶段添加加载提示,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:45:00