开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 ; _4 ]. ^1 {" J; D9 n# e2 q

( s8 O8 U# a8 s" c8 z/ a8 [( c) h" V! ~$ x& I( P2 B
最近在研究JS 做了一个简单的逻辑来播放声音
+ O. w8 N6 e2 l6 c8 L5 o; F
  1. var pit = 1;//初始化音高(速度)6 U% o5 t+ p# W6 P
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]! E& y5 ^% i6 D+ d, B
  3. function create(ctx, state, train) {
    9 U% a7 f# k" ?6 Y& D
  4.     state.number = new Array();4 ^5 D" V+ m, z$ ?/ y) q
  5.     state.soundsspeed = 0;//初始化速度
    0 H$ g8 G: _! C+ r4 Z* X1 V  _
  6.     state.speedsub = 0;
    ( U6 |# h; A3 b% D
  7.     for(let i = 0; i < 100; i++){
    0 u- I9 ^- B7 K1 J
  8.         state.number[i]=0;//初始化数组8 I/ O) l+ [( H, Q: c# q
  9.     }
    ; ]2 d) A2 N' c. K& a, j; C; V
  10. }8 m. s( q7 K& o0 ]
  11. $ V7 Q* w$ o( `3 v8 ]5 Z- h5 i
  12. function render(ctx, state, train) {
    1 E9 p% ]6 P8 ?9 K$ f) d% j
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    % _: Z' O  H  c: w$ S+ U3 I
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)
    - Q' @" m2 U$ m- v% A4 V  I+ g
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    & G$ u1 x6 S& z/ W6 E
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差, C/ A0 n$ |2 e
  17.     ctx.setDebugInfo("speedsub=",state.speedsub): a; ^3 J9 J, Z; ?
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作; A9 U+ c: c: v' ^
  19.         for (let i = 0; i < train.trainCars(); i++) {4 ~5 Q% E: m% _# Q8 S/ h; _4 r
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启0 x5 [9 M1 [8 m6 |3 s) X
  21.             if(state.speedsub<-1){//如果车辆减速( m- j1 n$ R0 K7 O5 R0 T' ?
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    6 S6 ]) `/ n' c5 `, K) k& w) @
  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
    & |; r/ v# w3 G1 F- h! ?
  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);//更新返回时间 播放刹车声在转向架24 W0 k/ R- O7 H8 T7 _$ ^* p6 s3 `- y
  25.             }else if(state.speedsub>1){//如果车辆加速
    9 T; o+ H5 }. i; X* _
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速, I9 ?  O& F/ Z: o& U
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声! ]- v% m6 Z' U4 G( \0 g
  28.             }
    3 A% p0 M, }* B- j/ e( w: ~
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声
    , p% n$ `! r+ m. u8 O
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声$ o: N9 Q" v1 g: h
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    7 S2 o% v7 o/ A( F; `* d
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    5 s/ r/ X$ U4 q2 s
  33.             }
    ) ?: F( X) P7 _# ?7 J, l: V$ L( h# S
  34.             if(train.speed()*20*3.6>5){% k  P9 c/ U4 H! a6 w5 z
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声
    ' Q& y! a2 v' D3 D1 r& o& ?, R
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声
    0 a% k9 g4 O5 p8 U* T" \5 n
  37.             }% S7 Q7 X0 l8 ^9 G7 b
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    - E3 {% k* I  g* d) O% i
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    ) Q9 y1 _+ Y! p$ r1 P4 N
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声- G: L0 W9 Q9 c) C1 M* D+ D) Y
  41.             }
    - H) S( B- t/ I% M. X# H
  42.         }
    , f* _2 b. P" w
  43.     }
    / g! p3 G- j1 G- C
  44.     state.soundsspeed = train.speed();//更新速度: a- G6 O- }# c8 }2 q7 g
  45.     for(let i=0;i<4;i++){
    # B- m0 l" R0 P* S8 z/ P
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    7 t7 }( c! \  V: a
  47.     }1 l& z* {9 s) C+ x
  48. }
    9 F5 B( @# M0 P" g; f6 \- F
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间& c! t/ Y, }* |8 S& O/ }$ i
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    6 a/ C- X& f3 V' V1 p" ?2 M
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    % `" H: o! `- \' W4 V% I0 X
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    3 r  @+ W/ V+ }3 \* Z  w
  53.     }
    . j: J  B6 x- e+ }. _- Y8 j3 k
  54.     return nu;//返回新的播放时间
    ; V8 _. h8 u' v8 M9 m  O# N. y9 g1 x
  55. }
    ! J  y( T, T! u& M" W
  56. function grnn(min, max) {//随机小数
    0 N& ], R* c3 C& P, h% {" j
  57.     return  Math.random()*(max-min)+min;
    % @4 a& p& I( z
  58. }" Y$ A5 m! G) Q
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的% c2 U, {4 O: c) l1 Y4 _' `- z
  60.     // 获取列车从车库开出的距离' n8 Z) N2 t3 h; ^; @# @/ ^
  61.     let railProgress = train.railProgress();) U9 }1 l  C/ A0 `# G, C
  62.     // 获取当前轨道的索引- N0 g3 _- o& I1 _; e# O
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    ; m% C5 @2 w# ?  \' T6 Z
  64.     // 检查当前轨道索引是否有效- i3 m5 a5 Y2 N4 A: Z( S- k4 {
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {! k7 X/ x3 n- [; p7 f6 [
  66.         // 获取当前路径数据对象8 x) V: |3 M& n( B3 ~. X% z
  67.         let currentPathData = train.path().get(currentRailIndex);: e' p. k4 k5 j8 m8 J
  68.         // 获取当前轨道使用的自定义轨道名称2 K" ~- x. I" T+ \: K) z) W
  69.         let trackModelKey = currentPathData.rail.getModelKey();5 y) J  _: w3 c; b
  70.         return trackModelKey;$ q! [# f1 n, F; d( c
  71.     }
    4 A. ]9 U. O, T
  72.     return null; // 或者是一个默认值. C" b! H4 G8 [+ `! \0 y
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
! x' C8 E' g" ]5 ^
有事加我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; h2 F; g5 N7 s" ]3 q7 e- [( C0 G
bve声音要方便一些吧,他有可视化可预览的编辑工具

- P  z4 S1 }8 b+ o7 X; S嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
) H) r2 ]5 C( e, b' D% ]7 J5 C# v( `3 o) `7 X
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 2 d; C. _! y3 a0 o+ C
huliawsl 发表于 2024-5-17 21:12
! |- i6 S1 p3 Z# @$ D1 M8 E相较于此,我还是认为bve格式会更简单
/ l3 Y: w9 g* A; U4 M. b
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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