滑动音效
TypeScript
//AudioMgr.ts
import { Node, AudioSource, AudioClip, resources, director } from 'cc';
/**
* @en
* this is a sington class for audio play, can be easily called from anywhere in you project.
* @zh
* 这是一个用于播放音频的单件类,可以很方便地在项目的任何地方调用。
*/
export class AudioMgr {
private static _inst: AudioMgr;
public static get inst(): AudioMgr {
if (this._inst == null) {
this._inst = new AudioMgr();
}
return this._inst;
}
private _audioSource: AudioSource;
constructor() {
//@en create a node as audioMgr
//@zh 创建一个节点作为 audioMgr
let audioMgr = new Node();
audioMgr.name = '__audioMgr__';
//@en add to the scene.
//@zh 添加节点到场景
director.getScene().addChild(audioMgr);
//@en make it as a persistent node, so it won't be destroied when scene change.
//@zh 标记为常驻节点,这样场景切换的时候就不会被销毁了
director.addPersistRootNode(audioMgr);
//@en add AudioSource componrnt to play audios.
//@zh 添加 AudioSource 组件,用于播放音频。
this._audioSource = audioMgr.addComponent(AudioSource);
}
public get audioSource() {
return this._audioSource;
}
/**
* @en
* play short audio, such as strikes,explosions
* @zh
* 播放短音频,比如 打击音效,爆炸音效等
* @param sound clip or url for the audio
* @param volume
*/
playOneShot(sound: AudioClip | string, volume: number = 1.0) {
if (sound instanceof AudioClip) {
this._audioSource.playOneShot(sound, volume);
}
else {
resources.load(sound, (err, clip: AudioClip) => {
if (err) {
console.log(err);
}
else {
this._audioSource.playOneShot(clip, volume);
}
});
}
}
/**
* @en
* play long audio, such as the bg music
* @zh
* 播放长音频,比如 背景音乐
* @param sound clip or url for the sound
* @param volume
*/
play(sound: AudioClip | string, volume: number = 1.0) {
if (sound instanceof AudioClip) {
this._audioSource.stop();
this._audioSource.clip = sound;
this._audioSource.loop=true;
this._audioSource.play();
this.audioSource.volume = volume;
}
else {
resources.load(sound, (err, clip: AudioClip) => {
if (err) {
console.log(err);
}
else {
this._audioSource.stop();
this._audioSource.clip = clip;
this._audioSource.loop=true;
this._audioSource.play();
this.audioSource.volume = volume;
}
});
}
}
/**
* stop the audio play
*/
stop() {
this._audioSource.stop();
}
/**
* pause the audio play
*/
pause() {
this._audioSource.pause();
}
/**
* resume the audio play
*/
resume(){
this._audioSource.play();
}
}
TypeScript
// 声明音频资源属性
@property(AudioClip)
clickAudio:AudioClip = null;
private emitSwipeEvent(direction: SwipeDirection) {
// 播放滑动音效(方向有效才播)
if (direction !== SwipeDirection.None && this.clickAudio) {
AudioMgr.inst.playOneShot(this.clickAudio);
}
if (this.chessboardNode) {
this.chessboardNode.emit('swipe', direction);
console.log(`已向棋盘发送滑动事件 - 方向: ${this.getDirectionText(direction)}`); // 事件发送日志
} else {
console.warn("未设置chessboardNode,无法发送滑动事件"); // 警告日志
}
}
✅ 实现效果
只要玩家滑动了(方向有效),就会播放一次
click.mp3,不重复、不卡顿。
✅ 音频资源声明
TypeScript
@property(AudioClip)
clickAudio: AudioClip = null;
- 在编辑器里把
click.mp3拖到这个字段上,才能播放。
✅ 播放时机:滑动方向确定后
TypeScript
private emitSwipeEvent(direction: SwipeDirection) {
// ✅ 播放滑动音效(方向有效才播)
if (direction !== SwipeDirection.None && this.clickAudio) {
// 关键
AudioMgr.inst.playOneShot(this.clickAudio);
}
}
✅ 为什么这样写?
| 关键点 | 说明 |
|---|---|
direction !== SwipeDirection.None |
防止轻微触摸 也播音效,只播有效滑动 |
playOneShot |
不打断其他音效,播完就结束,不循环 |
AudioMgr.inst.playOneShot(...) |
用单例管理器,全局唯一音频源,不依赖场景节点 |
✅ 总结
方向有效 → 播放一次
click.mp3→ 不卡顿、不重叠、不依赖场景。