[add] first
This commit is contained in:
81
assets/scripts/core/audio/music-compose-random.ts
Normal file
81
assets/scripts/core/audio/music-compose-random.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { _decorator, Component, Node, AudioClip, AudioSource, random, randomRangeInt, math, CCFloat } from 'cc';
|
||||
import { Sound } from './sound';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('MusicComposeRandom')
|
||||
export class MusicComposeRandom extends Component {
|
||||
|
||||
@property([AudioClip])
|
||||
clips: AudioClip[] = [];
|
||||
|
||||
@property([CCFloat])
|
||||
probability: number[] = [];
|
||||
|
||||
@property
|
||||
time: number = 0;
|
||||
|
||||
@property
|
||||
least_count = 1;
|
||||
|
||||
@property
|
||||
smooth: number = 0.1;
|
||||
|
||||
_selects: number[] = [];
|
||||
_curs: number[] = [];
|
||||
_t: number = 0;
|
||||
_audios: AudioSource[] = [];
|
||||
|
||||
start () {
|
||||
|
||||
for (let i = 0; i < this.clips.length; i++) {
|
||||
var as = this.node.addComponent(AudioSource);
|
||||
as.clip = this.clips[i];
|
||||
as.volume = 0;
|
||||
as.loop = true;
|
||||
as.play();
|
||||
this._audios.push(as);
|
||||
this._curs.push(0);
|
||||
this._selects.push(1);
|
||||
}
|
||||
|
||||
this.randomPlay();
|
||||
|
||||
}
|
||||
|
||||
update (deltaTime: number) {
|
||||
|
||||
if (this._t > this.time) {
|
||||
this._t -= this.time;
|
||||
this.randomPlay();
|
||||
}
|
||||
|
||||
this._t += deltaTime;
|
||||
|
||||
for (let i = 0; i < this._audios.length; i++) {
|
||||
this._curs[i] = math.lerp(this._curs[i], this._selects[i], deltaTime * this.smooth);
|
||||
this._audios[i].volume = this._curs[i] * Sound.volume;
|
||||
}
|
||||
}
|
||||
|
||||
randomPlay () {
|
||||
|
||||
var count = 0;
|
||||
for (let i = 0; i < this.clips.length; i++) {
|
||||
if (Math.random() < this.probability[i]) {
|
||||
this._selects[i] = 1;
|
||||
count++;
|
||||
} else {
|
||||
this._selects[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count === 0) {
|
||||
var select_one = randomRangeInt(0, this.clips.length);
|
||||
this._selects[select_one] = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
9
assets/scripts/core/audio/music-compose-random.ts.meta
Normal file
9
assets/scripts/core/audio/music-compose-random.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "5c45cffc-3075-4ad0-8d98-b9581a9d7fdd",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
44
assets/scripts/core/audio/music-compose-state.ts
Normal file
44
assets/scripts/core/audio/music-compose-state.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { _decorator, Component, Node, AudioClip, AudioSource, math, CCFloat } from 'cc';
|
||||
import { Msg } from '../msg/msg';
|
||||
import { Sound } from './sound';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('MusicComposeState')
|
||||
export class MusicComposeState extends Component {
|
||||
|
||||
@property([AudioClip])
|
||||
clips: AudioClip[] = [];
|
||||
|
||||
@property
|
||||
smooth: number = 0.1;
|
||||
|
||||
@property(CCFloat)
|
||||
selects: number[] = [];
|
||||
|
||||
_curs: number[] = [];
|
||||
|
||||
_audios: AudioSource[] = [];
|
||||
|
||||
|
||||
start () {
|
||||
|
||||
for (let i = 0; i < this.clips.length; i++) {
|
||||
var as = this.node.addComponent(AudioSource);
|
||||
as.clip = this.clips[i];
|
||||
as.volume = 0;
|
||||
as.loop = true;
|
||||
as.play();
|
||||
this._audios.push(as);
|
||||
this._curs.push(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update (deltaTime: number) {
|
||||
for (let i = 0; i < this._audios.length; i++) {
|
||||
this._curs[i] = math.lerp(this._curs[i], this.selects[i], deltaTime * this.smooth);
|
||||
this._audios[i].volume = this._curs[i] * Sound.volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
assets/scripts/core/audio/music-compose-state.ts.meta
Normal file
9
assets/scripts/core/audio/music-compose-state.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "12b52917-bf92-4f63-a506-d86d58d0ac87",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
65
assets/scripts/core/audio/music-compose-value.ts
Normal file
65
assets/scripts/core/audio/music-compose-value.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { _decorator, Component, Node, AudioClip, AudioSource, math, CCFloat } from 'cc';
|
||||
import { Msg } from '../msg/msg';
|
||||
import { Sound } from './sound';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('MusicComposeValue')
|
||||
export class MusicComposeValue extends Component {
|
||||
|
||||
@property([AudioClip])
|
||||
clips: AudioClip[] = [];
|
||||
|
||||
@property([CCFloat])
|
||||
weight: number[] = [];
|
||||
|
||||
@property
|
||||
smooth: number = 0.1;
|
||||
|
||||
_selects: number[] = [];
|
||||
|
||||
_curs: number[] = [];
|
||||
|
||||
_audios: AudioSource[] = [];
|
||||
|
||||
_value = 0;
|
||||
|
||||
start () {
|
||||
|
||||
Msg.on('music_level_by_speed', this.setValue.bind(this));
|
||||
|
||||
for (let i = 0; i < this.clips.length; i++) {
|
||||
var as = this.node.addComponent(AudioSource);
|
||||
as.clip = this.clips[i];
|
||||
as.volume = 0;
|
||||
as.loop = true;
|
||||
as.play();
|
||||
this._audios.push(as);
|
||||
this._curs.push(0);
|
||||
this._selects.push(1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
onDestroy () {
|
||||
Msg.off('music_level_by_speed', this.setValue.bind(this));
|
||||
}
|
||||
|
||||
setValue (speed: number) {
|
||||
|
||||
this._value = speed;
|
||||
for (let i = 0; i < this.clips.length; i++) {
|
||||
if (this.weight[i] <= this._value) this._selects[i] = 1;
|
||||
else this._selects[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update (deltaTime: number) {
|
||||
for (let i = 0; i < this._audios.length; i++) {
|
||||
this._curs[i] = math.lerp(this._curs[i], this._selects[i], deltaTime * this.smooth);
|
||||
this._audios[i].volume = this._curs[i] * Sound.volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
assets/scripts/core/audio/music-compose-value.ts.meta
Normal file
9
assets/scripts/core/audio/music-compose-value.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "0abe69b2-2d2a-477b-9c64-88af107b58ce",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
14
assets/scripts/core/audio/sound-actor.ts
Normal file
14
assets/scripts/core/audio/sound-actor.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { _decorator, Component, Node, CCString } from 'cc';
|
||||
import { Sound } from './sound';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('SoundActor')
|
||||
export class SoundActor extends Component {
|
||||
|
||||
@property(CCString)
|
||||
sfx_name: string | undefined;
|
||||
|
||||
onEnable () {
|
||||
Sound.addSfx(this.node, this.sfx_name!);
|
||||
}
|
||||
}
|
||||
9
assets/scripts/core/audio/sound-actor.ts.meta
Normal file
9
assets/scripts/core/audio/sound-actor.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "5127f939-6be8-4e58-b66b-a60f28045f6e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
69
assets/scripts/core/audio/sound-enable-play.ts
Normal file
69
assets/scripts/core/audio/sound-enable-play.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { _decorator, Component, Node, find, AudioSource, Vec3, CCString } from 'cc';
|
||||
import { Msg } from '../msg/msg';
|
||||
import { Sound } from './sound';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('SoundEnablePlay')
|
||||
export class SoundEnablePlay extends Component {
|
||||
|
||||
@property(CCString)
|
||||
sfx_name: string | undefined;
|
||||
|
||||
@property
|
||||
enable_distance: boolean = false;
|
||||
|
||||
@property
|
||||
max_distance = 6;
|
||||
|
||||
@property
|
||||
max_sound = 1.0;
|
||||
|
||||
@property
|
||||
min_sound = 0.5;
|
||||
|
||||
@property
|
||||
relate_height: boolean = false;
|
||||
|
||||
@property
|
||||
max_height = 10;
|
||||
|
||||
_audioSource: AudioSource = Object.create(null);
|
||||
|
||||
_distance_percent = 1;
|
||||
|
||||
_volume = 1;
|
||||
|
||||
__preload () {
|
||||
this._audioSource = this.node.addComponent(AudioSource);
|
||||
Sound.addSfx(this.node, this.sfx_name!);
|
||||
if (this.relate_height) {
|
||||
var height = this.node.worldPosition.y;
|
||||
if (height > this.max_height) height = this.max_height;
|
||||
this._volume = height / this.max_height;
|
||||
if (this._volume > this.max_sound) this._volume = this.max_sound;
|
||||
if (this._volume < this.min_sound) this._volume = this.min_sound;
|
||||
}
|
||||
}
|
||||
|
||||
onEnable () {
|
||||
this._audioSource.play();
|
||||
}
|
||||
|
||||
onDisable () {
|
||||
this._audioSource.stop();
|
||||
}
|
||||
|
||||
update (deltaTime: number) {
|
||||
|
||||
/*
|
||||
if (actor_main.target && actor_main.target.worldPosition) {
|
||||
var dis = Vec3.distance(this.node.worldPosition, actor_main.target.worldPosition);
|
||||
if (dis >= this.max_distance) dis = this.max_distance;
|
||||
this._audioSource.volume = Sound.volume * (1 - dis / this.max_distance) * this._volume * Sound.volume_load;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
9
assets/scripts/core/audio/sound-enable-play.ts.meta
Normal file
9
assets/scripts/core/audio/sound-enable-play.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "aaf92701-f993-4e5d-8212-7a3b2dd81779",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
216
assets/scripts/core/audio/sound.ts
Normal file
216
assets/scripts/core/audio/sound.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Node, AudioSource } from "cc";
|
||||
import { Save } from "../../logic/data/save";
|
||||
import { Msg } from "../msg/msg";
|
||||
import { Res } from "../res/res";
|
||||
import { Game } from "../../logic/data/game";
|
||||
import { ResCache } from "../res/res-cache";
|
||||
|
||||
export class Sound {
|
||||
|
||||
private static _sfxAudio: AudioSource;
|
||||
private static _bgmAudio: AudioSource;
|
||||
|
||||
public static volumeSound: number = 0.5;
|
||||
|
||||
public static volumeMusic: number = 1;
|
||||
|
||||
public static sceneMusicPercent: number = 1;
|
||||
|
||||
public static _volumeLoad = 1;
|
||||
public static _sourcePoolCount = 30;
|
||||
public static _pool: AudioSource[] = [];
|
||||
|
||||
private static _templateSource: Node;
|
||||
private static _poolRoot: Node;
|
||||
|
||||
private static currentBGMName = '';
|
||||
|
||||
public static init (): void {
|
||||
|
||||
// Initialize sound prefab.
|
||||
const prefab = ResCache.Instance.getPrefab('sound');
|
||||
|
||||
const soundNode = Res.inst(prefab, Game.Instance._poolNode);
|
||||
this._sfxAudio = soundNode.getChildByName('sfx')?.getComponent(AudioSource)!;
|
||||
this._bgmAudio = soundNode.getChildByName('bgm')?.getComponent(AudioSource)!;
|
||||
|
||||
// Init pool.
|
||||
this._poolRoot = soundNode.getChildByName('pool_root')!;
|
||||
this._templateSource = soundNode.getChildByName('template')!;
|
||||
for (let i = 0; i < this._sourcePoolCount; i++) this.addPool();
|
||||
|
||||
// Init sound volume.
|
||||
let volume = Save.Instance.get('sfx_volume');
|
||||
if (volume === undefined) volume = 1;
|
||||
this.volumeSound = volume;
|
||||
|
||||
// Init sound music.
|
||||
let volumeMusic = Save.Instance.get('sfx_volume_music');
|
||||
if (volumeMusic === undefined) volumeMusic = 1;
|
||||
this.volumeMusic = volumeMusic;
|
||||
|
||||
this.Refresh();
|
||||
|
||||
Msg.on('sli_sound', this.setVolume.bind(this));
|
||||
Msg.on('sli_music', this.setVolumeMusic.bind(this));
|
||||
|
||||
Msg.bind('sound_load', this.onLoad, this);
|
||||
Msg.bind('sound_load_end', this.onLoadEnd, this);
|
||||
}
|
||||
|
||||
private static addPool () {
|
||||
var newNode = Res.instNode(this._templateSource, this._poolRoot);
|
||||
this._pool.push(newNode.getComponent(AudioSource)!);
|
||||
}
|
||||
|
||||
public static setVolume (volume: number) {
|
||||
this.volumeSound = volume;
|
||||
this._sfxAudio.volume = this.volumeSound;
|
||||
Save.Instance.set('sfx_volume', volume);
|
||||
}
|
||||
|
||||
public static setVolumeMusic (volume: number) {
|
||||
this.volumeMusic = volume;
|
||||
this._bgmAudio.volume = this.volumeMusic;
|
||||
Save.Instance.set('sfx_volume_music', volume);
|
||||
}
|
||||
|
||||
private static Refresh () {
|
||||
this._sfxAudio.volume = this.volumeSound;
|
||||
this._bgmAudio.volume = this.volumeMusic;
|
||||
}
|
||||
|
||||
public static playLoop (key: string, volumeMultiply: number = 1): number {
|
||||
|
||||
//find unused.
|
||||
let index = -1;
|
||||
for (let i = 0; i < this._pool.length; i++) {
|
||||
if (this._pool[i].clip === null) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add new one.
|
||||
if (index === -1) {
|
||||
this.addPool();
|
||||
index = this._pool.length - 1;
|
||||
}
|
||||
|
||||
Res.loadAudio(`sound/${key}`, (err, asset) => {
|
||||
if (err) {
|
||||
throw new Error(`Can not find sound resource : sound/${key}`);
|
||||
}
|
||||
if (asset) {
|
||||
this._pool[index].clip = asset;
|
||||
this._pool[index].volume = this.volumeSound * volumeMultiply;
|
||||
this._pool[index].loop = true;
|
||||
this._pool[index].play();
|
||||
}
|
||||
});
|
||||
|
||||
return index;
|
||||
|
||||
}
|
||||
|
||||
public static offing (index: number): void {
|
||||
this._pool[index].stop();
|
||||
this._pool[index].loop = false;
|
||||
this._pool[index].clip = null;
|
||||
}
|
||||
|
||||
public static on (key: string, volumeMultiply: number = 1): void {
|
||||
Res.loadAudio(`sound/${key}`, (err, asset) => {
|
||||
if (asset) {
|
||||
this._sfxAudio.playOneShot(asset, this.volumeSound * volumeMultiply * this.sceneMusicPercent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static addSfx (node: Node, key: string, volume: number = 1) {
|
||||
Res.loadAudio(`sound/${key}`, (err, asset) => {
|
||||
if (err) {
|
||||
throw new Error(`Can not find sound resource : sound/${key}`);
|
||||
}
|
||||
if (asset) {
|
||||
if (!node.isValid) return;
|
||||
let source = node.getComponent(AudioSource)!;
|
||||
source.clip = asset;
|
||||
source.loop = true;
|
||||
source.volume = volume * this._volumeLoad;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static off (key: string) {
|
||||
|
||||
}
|
||||
|
||||
public static onBGM (key: string): void {
|
||||
|
||||
if (this.currentBGMName == key) return;
|
||||
this.currentBGMName = key;
|
||||
|
||||
Res.loadAudio(`sound/${key}`, (err, asset) => {
|
||||
if (err) {
|
||||
throw new Error(`Can not find sound resource : sound/${key}`);
|
||||
}
|
||||
if (asset) {
|
||||
this._bgmAudio.stop();
|
||||
this._bgmAudio.clip = asset;
|
||||
this._bgmAudio.loop = true;
|
||||
this._bgmAudio.volume = this.volumeMusic;
|
||||
this._bgmAudio.play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static offBGM (key: string): void {
|
||||
this._bgmAudio.stop();
|
||||
this._bgmAudio.clip = null;
|
||||
this._bgmAudio.loop = false;
|
||||
this.currentBGMName = '';
|
||||
|
||||
}
|
||||
|
||||
public static updateBGM () {
|
||||
this._bgmAudio.volume = this.volumeMusic * this.sceneMusicPercent;
|
||||
}
|
||||
|
||||
public static pauseBGM (): void {
|
||||
this._bgmAudio.pause();
|
||||
}
|
||||
|
||||
public static onLoad () {
|
||||
this._volumeLoad = 0;
|
||||
}
|
||||
|
||||
public static onLoadEnd () {
|
||||
this._volumeLoad = 1;
|
||||
}
|
||||
|
||||
}
|
||||
9
assets/scripts/core/audio/sound.ts.meta
Normal file
9
assets/scripts/core/audio/sound.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "89c79466-a85c-4670-9dd8-884dd0ffb2be",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user