开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 1 N: P0 P) s( }9 \; U7 a7 m& V
6 S1 ^& @" r* k" w1 N; I

9 r/ h# Q. B; D* j( B3 b- ^* w& f0 |最近在研究JS 做了一个简单的逻辑来播放声音
  o; q, R7 L9 w
  1. var pit = 1;//初始化音高(速度)
    + |4 ^6 R; r8 ^+ M! X
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]9 \& d0 L/ D1 G( F
  3. function create(ctx, state, train) {
    & ]( I; A2 K0 y. `5 u: _5 n  ~
  4.     state.number = new Array();8 |, ^  }) m# m& |
  5.     state.soundsspeed = 0;//初始化速度8 Z9 i1 D. V7 H# ^3 v# p
  6.     state.speedsub = 0;
    1 t/ x* ]0 E, i, `" Z  s$ G& d
  7.     for(let i = 0; i < 100; i++){
    8 d( I' ^3 |# Y3 [0 o$ e7 ]+ G. L7 f
  8.         state.number[i]=0;//初始化数组
    % _3 B6 ?6 Y& g& V
  9.     }
    , Y% \# d1 r& r, K
  10. }
    - ?! {& [' x2 J
  11. / l, l; |8 _* f% z2 q
  12. function render(ctx, state, train) {, {( n/ A: w2 G* l/ g* z6 J
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    ! o  n9 g) N/ f9 F0 a4 l( `- G
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)( ?% h' x- n* G4 S' u& A
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    ( l* `$ D, z3 m& |& [4 D$ v. G
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    6 e" i6 _; R0 B1 h* s
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)2 m5 u. U% o# z$ o/ q5 X3 q
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作7 E) `& f# w3 g
  19.         for (let i = 0; i < train.trainCars(); i++) {  J4 N6 }! l* G; A
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    : Z+ ~% I4 b2 W
  21.             if(state.speedsub<-1){//如果车辆减速: u6 M) }1 V7 @0 r
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    ! `& {. p7 Y$ \
  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
      D* m9 o7 `( l4 P( E4 n* I! m2 z
  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
    7 @9 K  ~2 X( m9 ]  X% z0 w9 C
  25.             }else if(state.speedsub>1){//如果车辆加速
    0 D/ C+ O- J1 F7 h; ?6 G* g: F
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速6 S1 V9 ^( v1 A& w1 c& p7 l+ `6 ~
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    1 v, C* n# t8 u' S5 ]' p
  28.             }$ k: c( Y' U/ Q, s1 Q0 A, U/ c' R
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声" J: b' p$ p0 {) [
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    7 }' |" r/ U' W! X  w; U
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    9 X: D. s+ ~- Y( J- T( G7 c
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右* R  y$ y: ]  k9 G/ Z2 \
  33.             }
    : X0 W) U( P# v+ c4 [; n, M
  34.             if(train.speed()*20*3.6>5){
    ) n# @/ A: a9 b: N" T" Q
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声4 Z+ F1 j$ `3 F- r# _# W7 |
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声0 I1 l6 I# V$ R- ~/ i4 P
  37.             }
      J3 y3 }5 X. Z$ I" K) m) `. T; L- u8 c
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    1 A9 _0 Q( W7 p' S
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    " P  Q) `! X; R
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    ; j0 u9 z3 l6 p3 v- X/ y" [
  41.             }; b* v/ E8 w' F6 u- d6 C; X
  42.         }
    " l. y$ k7 f. a; }
  43.     }$ S+ D8 V9 B4 k" {, r: X% s8 r
  44.     state.soundsspeed = train.speed();//更新速度
    ( M2 @$ P2 K% [1 j/ d4 v. o
  45.     for(let i=0;i<4;i++){4 L/ F( J$ t/ M* p2 W1 q3 k
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    , K4 v' b  @# [: y% d! f% g
  47.     }) N9 R( k+ i( X2 u1 P# B
  48. }4 K& R8 w: U2 j8 \
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间% d4 d! G6 E  w# F3 ?, H
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    , @% T* s. ~% @7 v
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放( ?  Y4 v0 e6 z- D5 D; \
  52.         nu = Timing.elapsed()+long;   //更新播放时间/ `' c3 E% T5 G+ }$ {1 j
  53.     }
    # c) `6 Q0 M, }4 N# z& m& g
  54.     return nu;//返回新的播放时间
    ' h  s& k) s0 U3 @# X; j" [0 ]
  55. }; k, @( y4 O# W* I2 F; O# o" l
  56. function grnn(min, max) {//随机小数6 j' ^* l2 L1 i" s+ T" ]
  57.     return  Math.random()*(max-min)+min;) D' W/ k# y. `' F: w: e
  58. }1 e0 L' E5 f3 L: [; Y9 [+ h
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的+ S( B1 V" K* q& A! E* s' l
  60.     // 获取列车从车库开出的距离
    & H. V2 i( \2 J' W) F
  61.     let railProgress = train.railProgress();, X+ L. G" z) c$ S& w/ W$ S
  62.     // 获取当前轨道的索引! i8 h1 L9 }8 ^8 E
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    - w" t8 ^, ~. i3 `7 X9 {
  64.     // 检查当前轨道索引是否有效3 d$ v( Q' u8 V% h' {
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {& W) n8 ?$ I( [# O4 ]- E
  66.         // 获取当前路径数据对象" P. t4 U$ j2 g' r7 G$ `2 I
  67.         let currentPathData = train.path().get(currentRailIndex);
    0 g9 m# b& h- e$ C( y
  68.         // 获取当前轨道使用的自定义轨道名称
    $ h" Y, d/ G6 N5 t: e" L, r3 S8 B% X" A
  69.         let trackModelKey = currentPathData.rail.getModelKey();2 f! N8 P# c0 K' a
  70.         return trackModelKey;3 d7 u$ g! y, c8 l& x+ a
  71.     }
    # @$ x4 _: L! p; w
  72.     return null; // 或者是一个默认值2 L% D  r+ p" e5 h1 [
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
' {2 c" Z6 |, l" w( T- Y1 P( y
有事加我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( E+ \7 y6 {, \: C3 k
bve声音要方便一些吧,他有可视化可预览的编辑工具
" |" K9 i- S! P" g
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
* R/ g) T1 z/ Z+ @/ @6 X% i6 f5 q7 I, r# _! M* o
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑   f# H' V1 M- v+ Y( M
huliawsl 发表于 2024-5-17 21:12
2 T; A/ R/ P; C, s8 @相较于此,我还是认为bve格式会更简单

9 W& h% K3 M7 N$ P8 b9 g/ z4 I🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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