开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 : d& n1 b5 Z6 c- L
+ T' r, V4 I) F1 m& m
, a0 A$ X) C/ k" J+ l# E$ O
最近在研究JS 做了一个简单的逻辑来播放声音
, `3 f* O5 m% b0 `0 o# G0 T
  1. var pit = 1;//初始化音高(速度). N" E5 C, J6 |$ w" r
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]9 ]" x  E7 \2 Z+ O
  3. function create(ctx, state, train) {
    + ]- e) z9 T. a' c3 M# t6 W1 ^
  4.     state.number = new Array();" X$ M9 S% N) e# n
  5.     state.soundsspeed = 0;//初始化速度& e& q4 m8 v% M& o4 r# z$ X) H& q: B
  6.     state.speedsub = 0;; Z3 l2 |. |1 R4 ^1 k
  7.     for(let i = 0; i < 100; i++){5 D' M, W/ d/ J
  8.         state.number[i]=0;//初始化数组* {: k% E( Q4 r, q' E. b
  9.     }
      G. a( {* x% X6 t% \- m
  10. }( A5 l: Q! G/ Q3 I* S& G& r* @( }- S- I

  11. : ]! {  {+ A7 R4 p: d& _/ K
  12. function render(ctx, state, train) {
    4 K6 _6 D& I" v( @
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    6 f/ E* n& o6 y- @5 s
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)+ N1 f2 }8 ?7 a& O6 U* B
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    ' T. ]; O/ l' k4 ?
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差  ]  \% J# r6 |4 K
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    $ A4 t# F) u6 u3 U
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    0 B7 S3 s# x) ]3 |, W8 N; ~8 L) u
  19.         for (let i = 0; i < train.trainCars(); i++) {
    . f  a& n" d6 K' n. B- ^
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    2 P  j( F9 }& T' ]9 y5 H- Z( m% Q5 J: M& G
  21.             if(state.speedsub<-1){//如果车辆减速. L2 D4 e# p2 @2 N& K6 t5 e0 U
  22.                 ctx.setDebugInfo("shache",1);//记录刹车3 C( r5 [' O$ j
  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! C; x' I2 ~; z) ~  l! C+ r
  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);//更新返回时间 播放刹车声在转向架26 e" e$ |5 I5 }* A, v3 w
  25.             }else if(state.speedsub>1){//如果车辆加速$ C) ~) T+ z0 j  D% t4 t
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速1 z3 l8 R( ^0 {; A
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    4 a* n. j. r3 z" h
  28.             }) g+ |/ _9 F7 W0 R/ |7 S- D0 p
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声& R& m1 `' D* x  P6 A( [- p9 {: p% d/ B
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声! m1 t7 V( k5 C. d0 {* W1 \$ I/ g
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启7 D7 x  D8 d" n
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右1 e  W: S( f+ S0 e* h
  33.             }
    6 ^1 Y; C6 n" Q5 U0 k
  34.             if(train.speed()*20*3.6>5){% N  B2 @7 |0 N9 l# w2 h
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声
    7 w. ?/ S* F' p" r( C
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声
    7 r7 c( B( p) a" c9 d$ p6 i. p5 H/ N
  37.             }# z: S9 {, Y# p3 y
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){7 e6 h  Q$ M% L* d1 T! U
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声: i7 |  R/ ~3 P+ `
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声6 h9 r+ h/ z1 i$ g5 _/ M: K$ ]
  41.             }# b) C- n+ g2 u, w  y3 O' A
  42.         }! L( v- z5 q" ^4 d; @6 u- ]& o
  43.     }
    1 t2 {% r: h: s
  44.     state.soundsspeed = train.speed();//更新速度* ?. i, j3 N' g0 Y, J
  45.     for(let i=0;i<4;i++){
    ; j' i9 Z& k2 }8 b: T
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    % V0 Q5 M8 {: k3 |9 c+ C9 y
  47.     }3 h4 i& i8 `* ~/ H- q4 ~
  48. }
    2 E$ r1 k! [1 Q! T' g
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    : s" F; H7 N7 Y) l4 C1 F1 e7 m! Z
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间" P: n$ k: k% v; [- E: H
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    * v6 F& J6 o5 x0 D5 P5 Z
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    * c! n* J9 i+ Y) k& D" }4 \
  53.     }
    8 _+ u( m* w- O* }& n8 r! k
  54.     return nu;//返回新的播放时间* z: O2 C$ b& ]
  55. }
    , B) t# {3 z4 m
  56. function grnn(min, max) {//随机小数
    6 G3 Q" ]1 N' p2 r$ z  {+ i. M9 K4 p
  57.     return  Math.random()*(max-min)+min;* i. {( k/ T8 `' b7 o
  58. }$ s2 w5 ]6 w% J" |9 z. A# H. f
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的+ e, ?! U1 `/ M3 H  Y8 J: C
  60.     // 获取列车从车库开出的距离3 j" V* Y. y3 p* y" p& w' f& c3 n# n
  61.     let railProgress = train.railProgress();
    8 @0 H* H' Q7 e2 b* O+ A. G3 j
  62.     // 获取当前轨道的索引+ C) N: q; i% P( X8 S# R# M
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    & o! x0 u. V; l- H% _: a' W! d
  64.     // 检查当前轨道索引是否有效2 E, z& F: ]. w/ U2 A* B! d3 j  L
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    3 m- `/ e, A2 z) ?: G5 E! O5 @2 a9 G" E9 |
  66.         // 获取当前路径数据对象
    + `! }! c- X0 b, D! s. u- ]$ c) ~
  67.         let currentPathData = train.path().get(currentRailIndex);7 Q7 ~, W. E. A2 V" F+ H
  68.         // 获取当前轨道使用的自定义轨道名称
    " o$ j: M; r& S
  69.         let trackModelKey = currentPathData.rail.getModelKey();' Q. O( R5 a! ]3 u' A6 n! ?2 _
  70.         return trackModelKey;' m  m. K. w% s, @% D" P
  71.     }: }6 V) l/ p' t; t# h( T
  72.     return null; // 或者是一个默认值' G+ t& W/ i! E1 O
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
$ ^( Z/ W7 m2 P% I- A
有事加我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
  w4 ~) y5 G1 B7 s$ l' k: [: tbve声音要方便一些吧,他有可视化可预览的编辑工具
$ Q$ n9 i. k9 s0 k; u
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
+ S7 x/ a1 ~' f9 n) a9 T8 \: E" a0 X* X- W2 N: g
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 3 a" R4 `/ V6 b
huliawsl 发表于 2024-5-17 21:12( Q7 ]" u( t, w3 C+ `
相较于此,我还是认为bve格式会更简单

* P8 t) O! Y8 }, O) [2 `/ G🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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