Threejs系列–21游戏开发–沙漠赛车游戏【实现音乐加载器,加载进入场景音效】

  • Post author:
  • Post category:其他

Threejs系列–21游戏开发–沙漠赛车游戏【实现音乐加载器,加载进入音效】

序言

本章将实现鼠标点击开始按钮后,加载进入场景的音效。

目录结构

资源目录里面的结构不变,点击传送门快速查看。

|__src
	|__assets
	|__js
	|	|__base		基础类文件夹
	|		|__Camera.js 相机类	
	|		|__Resources.js 构建模型的资源类 
	|	|__geometries	定制的物体类文件夹
	|		|__AreaFenceBufferGeometry.js 栏栅模型
	|		|__AreaFloorBorderBufferGeometry.js 进度条几何体  
	|	|__materials	材质类文件夹
	|		|__Floor.js 地面材质	
	|		|__AreaFence.js	【新增--开始按钮的栏栅材质】
	|		|__AreaFloorBorder.js 进度条着色器 
	|	|__passes	合成器通道文件夹
	|		|__Blur.js	  模糊着色器
	|		|__Glows.js		发光着色器
	|	|__utils	工具类文件夹
	|		|__Sizes.js  画布大小控制类
	|		|__EventEmitter.js 基础事件处理器
	|		|__Time.js  动画刷新 
	|		|__Loader.js 加载器 
	|	|__world	精灵类文件夹
	|		|__Area.js	区域基础类  【新增--点击开始后,加载声音】
	|		|__Areas.js	区域管理类  【新增--声音对象传入区域中】
	|		|__index.js	精灵类	【新增--实例化声音类,传入区域中】
	|		|__Floor.js 地面类
	|		|__Sounds.js 音乐加载类	【新增--声音管理】
	|	|__Application.js	初始化游戏的文件 
	|__index.js		入口
	|__index.css  	小项目,样式一丢丢

代码一览

index.js代码

...
import Sounds from './Sounds.js';

export default class {
    constructor(_options){
        ...
        //设置声音
        this.setSounds();
        ...
    }
    
	...
	
    setAreas(){
        this.areas = new Areas({
            // renderer: this.renderer,
            time: this.time,
            camera: this.camera,
            sounds: this.sounds,   //新增导入声音类
            resources: this.resources
        })
        this.container.add(this.areas.container)
    }
}

Areas.js代码

...

export default class Areas {
    constructor(_options) {
        ...
        //接受存储声音对象
        this.sounds = _options.sounds;
        ...
    }

    ...

    add(_options) {
        const area = new Area({
            // renderer: this.renderer,
            time: this.time,
            camera: this.camera,
            sounds: this.sounds,	//导入声音对象
            resources: this.resources,
            active: true,
            ..._options,
        });

        this.container.add(area.container);
        
        this.items.push(area);

        return area;
    }
}


Area.js代码

...

export default class Area extends EventEmitter{
    constructor(_options){
        ...
        this.sounds = _options.sounds;
        ...
    }

   ...
   
    interact(){
        ...

        //交互开始
        this.trigger('interact');

        //进场声音
        this.sounds.play('uiArea');
    }

    ...
}

Sounds.js代码

import {Howl, Howler} from "howler";

import uiAreaSound1 from '../../assets/sounds/ui/area-1.mp3';

/**
* 声音加载基础类
*/
export default class Sounds{
    constructor(){

        this.items = []

        this.setSettings()
    }
	
	//声音配置
    setSettings(){
        const settings = [
            {
                name: "uiArea",
                sounds: [uiAreaSound1],
                minDelta: 100,
                velocityMin: 0,
                velocityMultiplier: 1,
                volumeMin: 0.75,
                volumeMax: 1,
                rateMin: 0.95,
                rateMax: 1.05,
            }
        ]

        settings.forEach(_settings => this.add(_settings));
    }
	
	//设置主音量
	setMasterVolume()
	
	//静音设置
    setMute(){}
    
	//汽车引擎声音
	setEngine(){}
	
	//组装声音配置
    add(_options){
        const item = {
            name: _options.name,
            minDelta: _options.minDelta,
            velocityMin: _options.velocityMin,
            velocityMultiplier: _options.velocityMultiplier,
            volumeMin: _options.volumeMin,
            volumeMax: _options.volumeMax,
            rateMin: _options.rateMin,
            rateMax: _options.rateMax,
            lastTime: 0,
            sounds: [],
        };

        _options.sounds.forEach(_sound => item.sounds.push(new Howl({src: [_sound]})));
        this.items.push(item);
    }
	
	//计算音量振幅等 加载声音
    play(_name, _velocity = 0){
    	//查找传入的参数是否在配置列表
        const item = this.items.find(_item => _item.name == _name);
        const time = Date.now();
		
		//找到并且上个音乐完成 速率满足个人配置 开始加载音乐
        if(item && time > item.lastTime + item.minDelta && (_velocity == 0 || _velocity > item.velocityMin)){
			// 获取当前传入参数中 多个音乐中的一个
            const sound = item.sounds[Math.floor(Math.random() * item.sounds.length)];
            
            //计算音量并设置
            let volume = Math.min(
                Math.max((_velocity - item.velocityMin) * item.velocityMultiplier, item.volumeMin),
                item.volumeMax
            );
            volume = Math.pow(volume, 2)
            sound.volume(volume);
			
			//计算播放速率并设置
            const rateAmplitude = item.rateMax - item.rateMin;
            sound.rate(item.rateMin + Math.random() * rateAmplitude);
            
            sound.play();

            item.lastTime = time;
        }
    }
}

代码解读

Sounds.js借助howler实现了声音管理。
index.js引入了声音对象,将其最终传入Area.js ,在游戏开始时调用声音加载的方式play()

运行结果

进场声音加载效果


版权声明:本文为weixin_45111820原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。