@cc-component/cc-core 1.6.6 → 1.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,160 +1,181 @@
1
- //AudioUtil.ts
2
- import { Node, AudioSource, AudioClip, resources, director } from 'cc';
1
+ // AudioUtil.ts
2
+ import { Node, AudioSource, AudioClip, director } from 'cc';
3
3
  import { ResourceManager } from './ResourceManager';
4
4
  import { BundleConfigName } from '../config/CommonEnum';
5
5
  import { EDITOR } from 'cc/env';
6
+
6
7
  /**
7
8
  * @en
8
- * this is a sington class for audio play, can be easily called from anywhere in you project.
9
+ * This is a singleton class for audio playback, can be easily called from anywhere in your project.
9
10
  * @zh
10
- * 这是一个用于播放音频的单件类,可以很方便地在项目的任何地方调用。
11
+ * 这是一个用于播放音频的单例类,可以很方便地在项目的任何地方调用。
11
12
  */
12
13
  export class AudioUtil {
13
-
14
-
15
14
  private _audioSource: AudioSource;
16
- private _audioSource2: AudioSource;
15
+ public audioSourceShot: AudioSource;
17
16
 
17
+ // 用于存储背景音乐播放完成的回调
18
+ private _musicCompleteCallback: (() => void) | undefined;
19
+ // 用于存储背景音乐播放完成的回调-音效
20
+ private _musicCompleteCallbackShot: (() => void) | undefined;
18
21
  constructor() {
19
22
  if (EDITOR) return;
20
- //@en create a node as AudioUtil
21
- //@zh 创建一个节点作为 AudioUtil
22
- let AudioUtil = new Node();
23
- AudioUtil.name = '__AudioUtil__';
24
23
 
25
- //@en add to the scene.
26
- //@zh 添加节点到场景
27
- director.getScene().addChild(AudioUtil);
24
+ // 创建主音频节点
25
+ const audioNode = new Node('__AudioUtil__');
26
+ audioNode.name = '__AudioUtil__';
27
+ director.getScene().addChild(audioNode);
28
+ director.addPersistRootNode(audioNode);
29
+
30
+ // 主 AudioSource(用于背景音乐)
31
+ this._audioSource = audioNode.addComponent(AudioSource);
32
+ this._audioSource.playOnAwake = false;
33
+ this._audioSource.volume = this.music_volume;
34
+
35
+ // 监听播放结束事件(仅对非循环 clip 有效)
36
+ audioNode.on(AudioSource.EventType.ENDED, this.onAudioEnded, this);
37
+ // 初始化音效 AudioSource
38
+ this.AddAudioShot();
39
+ }
28
40
 
29
- //@en make it as a persistent node, so it won't be destroied when scene change.
30
- //@zh 标记为常驻节点,这样场景切换的时候就不会被销毁了
31
- director.addPersistRootNode(AudioUtil);
41
+ private onAudioEnded() {
42
+ if (this._musicCompleteCallback) {
43
+ this._musicCompleteCallback();
44
+ this._musicCompleteCallback = undefined; // 避免重复触发
45
+ }
46
+ }
32
47
 
33
- //@en add AudioSource componrnt to play audios.
34
- //@zh 添加 AudioSource 组件,用于播放音频。
35
- this._audioSource = AudioUtil.addComponent(AudioSource);
36
- this._audioSource.playOnAwake = false
37
48
 
38
- this.AddAudio2()
49
+ private AddAudioShot() {
50
+ const audioNode2 = new Node('__AudioUtil__2');
51
+ this._audioSource.node.addChild(audioNode2);
52
+ audioNode2.name = '__AudioUtil__2';
53
+ this.audioSourceShot = audioNode2.addComponent(AudioSource);
54
+ this.audioSourceShot.playOnAwake = false;
55
+ this.audioSourceShot.loop = false;
56
+ // 监听播放结束事件(仅对非循环 clip 有效)
57
+ audioNode2.on(AudioSource.EventType.ENDED, this.onAudioEndedShot, this);
39
58
  }
40
59
 
41
- AddAudio2() {
42
- let AudioUtil2 = new Node();
43
- this._audioSource.node.addChild(AudioUtil2)
44
- AudioUtil2.name = '__AudioUtil__2';
45
- this._audioSource2 = AudioUtil2.addComponent(AudioSource);
46
- this._audioSource2.playOnAwake = false
47
- this._audioSource2.loop = false
60
+ private onAudioEndedShot() {
61
+ if (this._musicCompleteCallbackShot) {
62
+ this._musicCompleteCallbackShot();
63
+ this._musicCompleteCallbackShot = undefined; // 避免重复触发
64
+ }
48
65
  }
49
66
 
50
67
  public get audioSource() {
51
68
  return this._audioSource;
52
69
  }
53
70
 
54
- /**
55
- * @en
56
- * play short audio, such as strikes,explosions
57
- * @zh
58
- * 播放短音频,比如 打击音效,爆炸音效等
59
- * @param sound clip or url for the audio
60
- * @param volume
61
- */
62
- async playOneShot(sound: AudioClip | string, volume: number = 0.5) {
63
- const v = this.sound_volume
64
- if (sound instanceof AudioClip) {
65
- this._audioSource.playOneShot(sound, v);
66
- }
67
- else {
68
- let clip = await ResourceManager.loadAsset<AudioClip>(BundleConfigName.common, sound, AudioClip)
69
- this._audioSource.playOneShot(clip, v);
70
- }
71
- }
72
-
71
+ // ==================== 音量管理 ====================
73
72
  get sound_volume(): number {
74
- const v = App.storage.getNumber('sound_volume', 1)
75
- return v
73
+ return App.storage.getNumber('sound_volume', 1);
76
74
  }
77
75
  set sound_volume(value: number) {
78
- App.storage.set('sound_volume', value)
76
+ App.storage.set('sound_volume', value);
79
77
  }
80
78
 
81
79
  get music_volume(): number {
82
- const v = App.storage.getNumber('music_volume', 1)
83
- return v
80
+ return App.storage.getNumber('music_volume', 1);
84
81
  }
85
82
  set music_volume(value: number) {
86
83
  this._audioSource.volume = value;
87
- App.storage.set('music_volume', value)
84
+ App.storage.set('music_volume', value);
88
85
  }
86
+
87
+ // ==================== 背景音乐控制 ====================
89
88
  /**
90
- * @en
91
- * play long audio, such as the bg music
92
- * @zh
93
- * 播放长音频,比如 背景音乐
94
- * @param sound clip or url for the sound
95
- * @param volume
89
+ * 播放背景音乐(支持完成回调)
90
+ * @param params.path 音频路径
91
+ * @param params.bundle 资源包名(可选)
92
+ * @param params.loop 是否循环(默认 false)
93
+ * @param params.volume 音量(默认使用 music_volume)
94
+ * @param params.callback 播放完成回调(仅在 loop=false 时有效)
96
95
  */
97
- async play(sound: AudioClip | string, volume: number = 1.0) {
98
- volume = this.music_volume;
99
- if (sound instanceof AudioClip) {
100
- this._audioSource.clip = sound;
101
- this._audioSource.play();
102
- this.audioSource.volume = volume;
103
- }
104
- else {
105
-
106
- if (!this._audioSource.playing) {
107
- let clip = await ResourceManager.loadAsset<AudioClip>(BundleConfigName.common, sound, AudioClip)
108
- this._audioSource.clip = clip;
109
- this._audioSource.loop = true
110
- this._audioSource.play();
111
- this.audioSource.volume = volume;
112
- }
96
+ async play(params: {
97
+ path: string;
98
+ bundle?: string;
99
+ loop?: boolean;
100
+ volume?: number;
101
+ callback?: () => void
102
+ }) {
103
+ try {
104
+ const clip = await this.loadAudioClip(params.bundle, params.path);
105
+ this._audioSource.stop(); // 停止当前播放
106
+
107
+ this._audioSource.clip = clip;
108
+ this._audioSource.loop = params.loop ?? false;
109
+ this._audioSource.volume = params.volume ?? this.music_volume;
110
+
111
+ // 设置完成回调(仅非循环时有意义)
112
+ this._musicCompleteCallback = (!params.loop && params.callback) ? params.callback : undefined;
113
113
 
114
+ this._audioSource.play();
115
+ } catch (e) {
116
+ console.error(`[AudioUtil] Failed to load or play music: ${params.path}`, e);
114
117
  }
115
118
  }
116
119
 
117
- /**
118
- * stop the audio play
119
- */
120
120
  stop() {
121
121
  this._audioSource.stop();
122
+ this._musicCompleteCallback = undefined;
122
123
  }
123
124
 
124
- /**
125
- * pause the audio play
126
- */
127
125
  pause() {
128
126
  this._audioSource.pause();
129
127
  }
130
128
 
131
- /**
132
- * resume the audio play
133
- */
134
129
  resume() {
135
130
  this._audioSource.play();
136
131
  }
137
132
 
138
-
139
- async playJump(sound: AudioClip | string, volume: number = 1.0) {
140
- if (sound instanceof AudioClip) {
141
- this._audioSource2.clip = sound;
142
- this._audioSource2.play();
143
- this._audioSource2.volume = volume;
144
- }
145
- else {
146
- let clip = await ResourceManager.loadAsset<AudioClip>(BundleConfigName.common, sound, AudioClip)
147
- this._audioSource2.clip = clip;
148
- this._audioSource2.loop = false
149
- this._audioSource2.play();
150
- this._audioSource2.volume = volume;
133
+ // ==================== 音效播放 ====================
134
+ /** 播放一次性音效(不可控,使用 playOneShot) */
135
+ async playShot(params: {
136
+ path: string;
137
+ bundle?: string;
138
+ volume?: number;
139
+ isMusic?: boolean;
140
+ complete?: () => void;
141
+ }) {
142
+ try {
143
+ const clip = await this.loadAudioClip(params.bundle, params.path);
144
+ const volume = params.volume ?? this.sound_volume;
145
+ if (params.isMusic) {
146
+ this.audioSourceShot.stop(); // 停止当前播放
147
+ this.audioSourceShot.clip = clip;
148
+ this.audioSourceShot.loop = false;
149
+ this.audioSourceShot.volume = volume
150
+ // 设置完成回调(仅非循环时有意义)
151
+ this._musicCompleteCallbackShot = (params.complete) ? params.complete : undefined;
152
+ this.audioSourceShot.play();
153
+ } else {
154
+ this._audioSource.playOneShot(clip, volume);
155
+ }
156
+ } catch (e) {
157
+ console.error(`[AudioUtil] Failed to play shot sound: ${params.path}`, e);
151
158
  }
152
159
  }
153
160
 
154
- /**
155
- * stop the audio play
156
- */
157
- stopJump() {
158
- this._audioSource2.stop();
161
+
162
+ // ==================== 音效控制(仅对 clip + play 模式有效,当前 playOneShot 无效)====================
163
+ stopShotMusic() {
164
+ this.audioSourceShot.stop();
165
+ }
166
+ pauseShotMusic() {
167
+ this.audioSourceShot.pause();
168
+ }
169
+ resumeShotMusic() {
170
+ this.audioSourceShot.play();
171
+ }
172
+
173
+ // ==================== 工具方法 ====================
174
+ private async loadAudioClip(bundle: string | undefined, path: string): Promise<AudioClip> {
175
+ return await ResourceManager.loadAsset<AudioClip>(
176
+ bundle || BundleConfigName.common,
177
+ path,
178
+ AudioClip
179
+ );
159
180
  }
160
181
  }
@@ -40,13 +40,13 @@ export class App {
40
40
  /**消息 */
41
41
  static get message(): EventManager { return this.instance._message };
42
42
  /**声音 */
43
- static get sound(): AudioUtil { return this.instance._sound };
43
+ static get audio(): AudioUtil { return this.instance._audio };
44
44
  /**声音 */
45
45
  static get tools(): Tools { return this.instance._tools };
46
46
  /**对象池 */
47
47
  static get pool(): EffectSingleCase { return this.instance._pool }
48
48
  /**资源管理 */
49
- static get res(): ResourceManager { return this.instance._res }
49
+ static get asset(): ResourceManager { return this.instance._asset }
50
50
 
51
51
  _gui: LayerUI;
52
52
  _http: HttpManager;
@@ -55,10 +55,10 @@ export class App {
55
55
  _timeManager: TimeManager;
56
56
  _language: LanguageManager;
57
57
  _message: EventManager;
58
- _sound: AudioUtil;
58
+ _audio: AudioUtil;
59
59
  _tools: Tools;
60
60
  _pool: EffectSingleCase;
61
- _res: ResourceManager;
61
+ _asset: ResourceManager;
62
62
 
63
63
  private static instance: App | null = null;
64
64
  public static get Ins(): App {
@@ -89,10 +89,10 @@ export class App {
89
89
  self._gui = new LayerUI();
90
90
  self._http = new HttpManager();
91
91
  self._message = new EventManager();
92
- self._sound = new AudioUtil();
92
+ self._audio = new AudioUtil();
93
93
  self._tools = new Tools();
94
94
  self._pool = EffectSingleCase.instance;
95
- self._res = ResourceManager.instance;
95
+ self._asset = ResourceManager.instance;
96
96
 
97
97
  if (EDITOR) { return }//编辑器环境,不执行下面逻辑
98
98
  //Logger.setLevel(ELoggerLevel.Error);
@@ -125,17 +125,6 @@ export class App {
125
125
  static async PreloadDir(bundleName: string, dirName: string, pre: Function) { return ResourceManager.preloadDir(bundleName, dirName, pre) }
126
126
  static async LoadDir(bundleName: string, dirName: string, type: any, pre: Function) { return ResourceManager.loadDir(bundleName, dirName, type, pre) }
127
127
 
128
- //音乐
129
- static async PlayOneShot(sound: AudioClip | string, volume: number = 1) { this.sound.playOneShot(sound, volume) }
130
- static async Play(sound: AudioClip | string, volume: number = 1.0) { this.sound.play(sound, volume) }
131
- static async Stop() { this.sound.stop() }
132
- static async Pause() { this.sound.pause() }
133
- static async Resume() { this.sound.resume() }
134
- static MusicVolume(volume: number) { this.sound.music_volume = volume }
135
- static SoundVolume(volume: number) { this.sound.sound_volume = volume }
136
- static GetMusicVolume() { return this.sound.music_volume }
137
- static GetSoundVolume() { return this.sound.sound_volume }
138
-
139
128
  /**
140
129
  * ================事件===================
141
130
  */
@@ -36,13 +36,13 @@ declare global {
36
36
  /**消息 */
37
37
  const message: EventManager
38
38
  /**声音 */
39
- const sound: AudioUtil;
39
+ const audio: AudioUtil;
40
40
  /**工具类 */
41
41
  const tools: Tools;
42
42
  /**对象池 */
43
43
  const pool: EffectSingleCase;
44
- /**资源管理 */
45
- const res: ResourceManager
44
+ /**资源加载 */
45
+ const asset: ResourceManager
46
46
 
47
47
  /**当前所在bundle名称 */
48
48
  const bundleName: string;
@@ -123,16 +123,6 @@ declare global {
123
123
  function GetOpenWindowsConfig(): IBundleConfig[];
124
124
  /** 显示加载转圈*/
125
125
  function OpenLoading(is_show: boolean);
126
- /**=======================================✅✅音乐======================= */
127
- function PlayOneShot(sound: string, volume?: number);
128
- function Play(sound: string, volume?: number);
129
- function Stop();
130
- function Pause();
131
- function Resume();
132
- function MusicVolume(volume: number);
133
- function SoundVolume(volume: number);
134
- function GetMusicVolume(): number;
135
- function GetSoundVolume(): number;
136
126
 
137
127
  /**=======================================✅✅常用工具======================= */
138
128
  // function TwoBezier(param1, param2, param3, param4);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cc-component/cc-core",
3
- "version": "1.6.6",
3
+ "version": "1.6.9",
4
4
  "engine": ">=3.8.6",
5
5
  "description": "系统组件添加常用扩展方法",
6
6
  "main": "index.ts",