开启左侧

给点播放声音的新思路

[复制链接]
Harlotte 作者认证 2024-5-17 06:00:22

还没有账号?赶快去注册吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑
0 S( l: w2 R! i+ Z1 U/ ?2 Q5 c6 `" |/ H$ [4 z4 i6 k* _1 C
: _  A" E  K+ s; }$ C( K& S- W- v3 K
最近在研究JS 做了一个简单的逻辑来播放声音1 w6 R7 c4 y2 `$ B) Q
  1. var pit = 1;//初始化音高(速度)& M9 i6 U, E# ^; o3 G
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]" R; r) V' s0 W# E6 e2 ~
  3. function create(ctx, state, train) {  J; Z$ w' F9 P8 F
  4.     state.number = new Array();% `2 S  J9 D) U$ F4 F( P$ n
  5.     state.soundsspeed = 0;//初始化速度
    : U6 e/ {' G- o7 W  G& M* D" K
  6.     state.speedsub = 0;
    # l; h3 D5 ]& h. O* r0 f5 F5 ~
  7.     for(let i = 0; i < 100; i++){, F8 d* Z. F% G$ J( q+ j" k* i, A  ^
  8.         state.number[i]=0;//初始化数组
    # {: V$ L6 B4 f+ N3 u- ~
  9.     }, ^3 D, J% {2 _' w
  10. }
    ! d3 J% F8 ]! u3 d+ e+ r+ l- q

  11. % Q, W& F( v) O% V/ ]- U& J$ c1 j% \
  12. function render(ctx, state, train) {( R: {, F2 Z0 U+ U; s4 @
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动, H" c% [1 ~9 G1 k7 ?) b) g8 L# A
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)- a, E  h* B: S
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    5 W" T+ R. {! I. l
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    0 m& ^4 l& @; ^% r" Z
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)+ Q1 ~/ w5 ^2 @0 p9 X# R
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    1 O9 X3 @3 c. p0 k
  19.         for (let i = 0; i < train.trainCars(); i++) {
    $ k; f9 [" K- t6 Y3 |$ B- _
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    5 X: X$ O9 E( q0 i2 ?) u
  21.             if(state.speedsub<-1){//如果车辆减速9 ?  N! r3 _8 ?" y" P! [# Q- C
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    9 ?# Q2 I6 s  Z( D0 L/ s. G
  23.                 state.number[0]=sound(ctx,"mtr:df5g_shache",i,soundspos.braking1,pit,state.number[0],16,0.03+train.speed()*20*3.6/800);//更新返回时间 播放刹车声在转向架13 F* V8 B& }+ m  z0 ?( d
  24.                 state.number[0]=sound(ctx,"mtr:df5g_shache",i,soundspos.braking2,pit,state.number[0],16,0.03+train.speed()*20*3.6/800);//更新返回时间 播放刹车声在转向架2' `4 f' N, r' U- e
  25.             }else if(state.speedsub>1){//如果车辆加速
    4 _8 K1 G/ T8 a8 v; T
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    2 A1 C5 c, [% p$ W& a
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声* o. Y+ a8 Y$ b( f0 j( ?
  28.             }
    2 l8 ?6 P6 s; t6 A& k3 j
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声6 e$ _1 l0 c/ k6 @5 F
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    - i# C- \1 C. V5 ~1 g% k  P
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启/ z/ K: n3 g' T
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    ) T& b* Y; S4 U: q7 i& A7 q! x
  33.             }8 Y, ~1 P& a: i! ^+ ~/ s7 Z1 ~3 _2 c
  34.             if(train.speed()*20*3.6>5){
    9 r2 W. r4 [) L" W! w4 p- V% X/ U
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声
    0 U4 w1 X+ k6 n4 i  U8 P) `: L
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声% y- b" ~; y$ z  D
  37.             }2 L9 W/ T' v* J( {6 o
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    6 F7 b( ]- \9 o. s( `, h  `
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声8 F; L0 ^" {2 Z- u- s7 I% E1 T
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声% v# U0 y) q! y  Q
  41.             }. o" S3 {# x5 G" [# h8 {5 ]% e
  42.         }
    5 r1 ~$ {1 R! G  T4 j6 g
  43.     }
    ! d7 v/ y/ d* ~! [
  44.     state.soundsspeed = train.speed();//更新速度
    4 ?( X- `( s% K9 n: X2 f9 l8 l9 z
  45.     for(let i=0;i<4;i++){: p: T- n: Q5 G8 a
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    ' p+ l4 S' q3 D  w
  47.     }
    6 u! Q' V3 ]4 Y; f
  48. }$ i7 c2 Y3 N) O( A6 Y  P/ a9 ^
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    ; @! V( S) N  p% J! [8 Y
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    4 z9 A) T5 s1 ^0 O; a4 G, p" V
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    $ u8 x4 F6 U8 e; J
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    & T. n) l4 {* s# y
  53.     }( D% l& \  U1 S6 t. V
  54.     return nu;//返回新的播放时间, S+ p; Y( \% |# g, H1 H0 Z
  55. }" U9 q- X1 V9 a: |+ r9 w
  56. function grnn(min, max) {//随机小数& c5 ^, ]4 I( X( ]6 Q% e& x% a0 e# R. b
  57.     return  Math.random()*(max-min)+min;
    ; T5 T% q7 }& J1 g9 ^
  58. }! g2 V4 A7 E& ^/ l3 l
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    ! ?$ I$ p: d  }! f+ Q# m% m$ t5 N
  60.     // 获取列车从车库开出的距离
    3 G' _( y# A6 J: L
  61.     let railProgress = train.railProgress();
    * K& \1 s4 n, K1 }! Z( C! A
  62.     // 获取当前轨道的索引
    : R& L, d. v1 o- p  ~- x
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    # E( U! Z1 D/ Q
  64.     // 检查当前轨道索引是否有效% ^# t' b3 x6 M' a1 U' k& j" Y* [
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    / |8 G( D  c& E# A" B
  66.         // 获取当前路径数据对象& p! `# ^. `$ x8 K1 ~% K
  67.         let currentPathData = train.path().get(currentRailIndex);
    & _* W# R4 q1 ?" x2 p$ Z
  68.         // 获取当前轨道使用的自定义轨道名称/ T9 I8 N; y+ u5 O% ?
  69.         let trackModelKey = currentPathData.rail.getModelKey();7 ^/ m( F2 u& }* M( c
  70.         return trackModelKey;4 o. l) u* X1 E0 N, c  V
  71.     }
    0 J/ \+ r3 m/ }1 U3 @( v' \! X
  72.     return null; // 或者是一个默认值
    6 r! Q  r' }/ Q; \- o0 Q
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错. d( B! m, k8 F' ]
有事加我QQ: 3435494979
要什么名字 作者认证 2024-5-17 17:04:29
bve声音要方便一些吧,他有可视化可预览的编辑工具
LG STUDIO(原CLARSC)成员,制作MTR追加hmmsim/openbve列车及线路,如果有事请通过QQ联络
楼主 Harlotte 作者认证 2024-5-17 19:17:25
要什么名字 发表于 2024-5-17 17:04
5 x+ K$ _% V( `bve声音要方便一些吧,他有可视化可预览的编辑工具

0 p% \3 f( P, R" [. y* ~" W0 X, G嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
) ^* }2 ]1 A: x, ?0 K
: j! F% c: G3 w7 R1 @相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 7 r1 R  `& M$ e' T! s# H. d" C
huliawsl 发表于 2024-5-17 21:12
$ X! f3 j: F8 B% C相较于此,我还是认为bve格式会更简单

3 }1 g# j& H( }* Y" Y* u8 l🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表