开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑
  u+ y6 |6 ]! J9 I2 H1 ]6 ]  Q) M# h) ~2 ^4 ^. e1 ?, U: A
5 i0 g& l  k3 q& X. K. Z
最近在研究JS 做了一个简单的逻辑来播放声音4 V/ f) q+ }/ I2 M8 D& @* \
  1. var pit = 1;//初始化音高(速度)
    ! Y) J8 N- }0 b. I" [6 s
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    4 N$ r. Q& A; v7 T; k' O
  3. function create(ctx, state, train) {2 |) I) X( Z& u8 D9 v
  4.     state.number = new Array();
    9 ?6 S$ b2 s7 d! G) |+ Y) d0 g  c
  5.     state.soundsspeed = 0;//初始化速度
    ( w# m7 J5 S& o3 Q4 u. y2 ~+ P
  6.     state.speedsub = 0;; j( _! J6 i1 \/ X. I' ^  y6 ^
  7.     for(let i = 0; i < 100; i++){7 J+ z) G2 `, x' E& Z7 b* A' c
  8.         state.number[i]=0;//初始化数组9 S/ a1 H/ K# ^$ i3 E
  9.     }; v$ |4 y- V& ^. `: c6 ~
  10. }1 k/ @9 I$ c: h. K) W, K& U# ?7 }( r

  11. 4 M+ G- [. Q  H# t
  12. function render(ctx, state, train) {- R+ X. a9 l& ^5 @6 G* z3 D9 H
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动% S: F4 g( p( `
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)- ?* U5 O! c6 a4 M
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    9 s: d  C; ~/ [* O
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差8 U" z/ s2 c9 ?3 |  [
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)2 a: D4 C: N1 P5 R% j$ Z
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    3 L7 R, g* H- ~8 h1 T$ P
  19.         for (let i = 0; i < train.trainCars(); i++) {5 i- E+ ?! \! v: a/ p8 w6 q9 W- |
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    - A# O- H6 H# n$ K. W
  21.             if(state.speedsub<-1){//如果车辆减速, `. e1 m7 i3 u9 \7 q$ H" h( p
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    7 u4 X, Q) h$ `  d! V/ C1 h
  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);//更新返回时间 播放刹车声在转向架1
    0 C4 H9 ~: k, s& G
  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( y3 |" o; s  y% V4 H
  25.             }else if(state.speedsub>1){//如果车辆加速
      ^4 V, Q: w) B: P6 s1 C& J
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速0 }7 L0 y5 w2 g5 F, y/ [
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声7 q3 a( h: }# l& F+ d
  28.             }" W+ z0 q' _4 J5 b( e
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声" J+ M  B, X& g' Y' T8 g
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声& a( \- ^( `5 T  a" i5 O/ |" B- Q# G$ W
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    - u% |2 y2 y. L  W" b: [0 _1 m/ E# E6 L
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右: ~6 m, M4 v# p: Z$ [% Y
  33.             }
    ! Y6 {2 ~! I! t" w) ?1 r
  34.             if(train.speed()*20*3.6>5){
    8 N6 ^; P' X+ {- j7 d2 b
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声- K: s4 f9 ?0 c
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声
    # o) R( _9 |$ D  a3 H
  37.             }: y9 e' c  e' i) X9 F* I% t, h9 e+ _
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    , }0 c% w8 c$ Z
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    2 L% E. _& M8 n5 N5 E. o, @( H( i& x
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    " F0 S" B: u( {6 S/ ~% d1 c- V' \
  41.             }
    : }% y. e" U0 u1 i. [
  42.         }
    2 S7 B) [, A/ z; K1 T3 x  [
  43.     }8 W5 v$ w$ N' K' T
  44.     state.soundsspeed = train.speed();//更新速度
    # U" J0 e' d! z4 O* ^1 \. k
  45.     for(let i=0;i<4;i++){3 H8 K- @" u/ p) @
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    1 q$ E! ]0 O* j; R' k. {7 _
  47.     }+ n# a2 x; h, z: I! _3 I+ V3 e
  48. }
    . ?. @% q6 U9 Y6 y4 f  q6 L
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间; Z& k- e/ ^9 H2 V
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间5 s6 C) c+ q9 q  X
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放) |$ `' h1 D6 p0 C; R( Z: e3 u
  52.         nu = Timing.elapsed()+long;   //更新播放时间9 S  ~* _) Y5 G3 y" r
  53.     }4 \6 O6 o4 n" o! l/ W8 f8 |' C
  54.     return nu;//返回新的播放时间( q1 Q/ I1 B! k" }  r
  55. }7 ~6 K3 o0 U, h% F7 c
  56. function grnn(min, max) {//随机小数
    % Y$ W% S7 [  P7 T. x
  57.     return  Math.random()*(max-min)+min;; ^7 h, ~2 h  n0 n7 T0 |
  58. }3 X& G* v% R1 C( Q9 i
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    % D$ w: x4 l* b/ ~* G  d# N
  60.     // 获取列车从车库开出的距离
    # L9 P" u" o0 s" ?6 ?
  61.     let railProgress = train.railProgress();: }+ g% x! d2 H1 h. V
  62.     // 获取当前轨道的索引
    " o  h. ~) J/ @& Y# |
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);% k- k& F! W4 W( X+ Z
  64.     // 检查当前轨道索引是否有效
    0 q7 W6 Q; ?. D3 z1 X3 \
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    ' `; I$ h. _7 `$ R7 X( l3 I
  66.         // 获取当前路径数据对象
    , i4 |9 s1 P+ S) s
  67.         let currentPathData = train.path().get(currentRailIndex);* s" X  j( B. A" G3 X
  68.         // 获取当前轨道使用的自定义轨道名称9 f7 i& }7 d/ @+ u1 Y9 G! h8 p/ c! @
  69.         let trackModelKey = currentPathData.rail.getModelKey();& g. N' x- u4 o9 K) u
  70.         return trackModelKey;
    - J% p( k% r" C" ^
  71.     }, p: f5 z. \( z9 L: W( K
  72.     return null; // 或者是一个默认值4 `+ I( d+ y6 M4 ^* G
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
- G& P# ^. m3 d& V' c& S4 q: e
有事加我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
! Z7 K* _! F9 z1 R; ^1 wbve声音要方便一些吧,他有可视化可预览的编辑工具
- e; t: C6 w' ^. ^( _
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
  f# b8 U  l% c
+ o9 }5 x& j3 P( N$ N6 u; P相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑
- I5 t0 |" x' w  `* d1 d
huliawsl 发表于 2024-5-17 21:12
( }, @; _  _& m8 M9 w相较于此,我还是认为bve格式会更简单
" X+ u8 n, N* {
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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