开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 % m8 R. k4 |8 B: m$ |3 L$ ?; m
/ b- K& X$ L) T# l! k# a5 G  n6 ^* p
1 N: w- P" l6 y: x4 Y1 B
最近在研究JS 做了一个简单的逻辑来播放声音
/ D# T9 l9 B# E, l& o5 i
  1. var pit = 1;//初始化音高(速度); e; V  H0 ^/ j' i0 w5 ]
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    $ `$ z) {* T$ c# C! Z) m
  3. function create(ctx, state, train) {% k: J( j  k- E$ m" C6 s
  4.     state.number = new Array();
    $ {' ~/ I% X, Q5 c% W
  5.     state.soundsspeed = 0;//初始化速度$ U/ q. T1 W4 [$ Y& `% e# c1 p* F9 f
  6.     state.speedsub = 0;
    + O' W! u1 ^4 S, s4 \! ~6 f  @6 \
  7.     for(let i = 0; i < 100; i++){# K: ^! Z+ |! |' V# I, N4 g
  8.         state.number[i]=0;//初始化数组. o% o0 |" f( a- q/ W% B% C. g5 _( `
  9.     }
    8 B2 u$ p' Y' h8 O
  10. }
    ! N; Q$ P0 Z# z- \
  11. + D2 m+ @% b$ l( S
  12. function render(ctx, state, train) {
    / c/ h! U3 A: V2 }5 E
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动3 C. r; X  B; D4 c
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)9 Q( G; z" J' H  P
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称    ) f" k3 n1 B3 x7 z/ H
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    ) e! Y/ O  `' B, w5 N4 y
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    0 E/ O6 y' T, g6 \% Q2 u
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    3 p" C: W) o0 x/ I& }+ }, h
  19.         for (let i = 0; i < train.trainCars(); i++) {) r4 `# i7 n2 y5 G
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    2 L8 ^! Z0 r6 j# Q) L6 `6 X3 ?; j! s
  21.             if(state.speedsub<-1){//如果车辆减速
    8 k, G# T2 [2 B& Z' Y+ w
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    $ x* [3 R0 O, b2 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);//更新返回时间 播放刹车声在转向架1) n& S( W; S# I% |) G0 o
  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
    / U, D) z' {* U  U1 ?) {! ]/ c& q
  25.             }else if(state.speedsub>1){//如果车辆加速" j, N  U( I% c. B" n8 O( H
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    . g" U0 F0 q- l3 j3 k8 C
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声. v. F2 E: A2 P: u7 C0 F) q: [
  28.             }8 }" U- {  Q- F& ?/ d" ]
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声1 Y. w8 P$ q2 E. d% n  u' M
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    ) Z1 `6 [3 x0 N0 u, j7 `
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    & ^& N5 A5 V* n, [: z
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右0 |9 n2 z+ m  y% c; I& B) v+ Q
  33.             }# a& z1 U$ S5 F7 _- p* Y, f, \$ }
  34.             if(train.speed()*20*3.6>5){( X) l5 ~9 t$ y: Y. y
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声0 e. C" |* Z6 a, }1 C, f* w
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声# B  [5 w5 w9 H1 P1 [5 w! ~
  37.             }
    # u; {, D' K5 T2 G1 e( p  r
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    6 T7 x* C' H6 J# I% X; _
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    8 H. j/ E% M) b. _
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    ; ^" {" A& q" M1 }" |3 |( W
  41.             }* v' D& W% _0 @& H2 N
  42.         }- J0 P8 }+ t, u" Q
  43.     }6 j" c4 O. m0 b1 O" a
  44.     state.soundsspeed = train.speed();//更新速度
    # f7 t( `: u2 w8 _- ~5 X+ j% ?' e
  45.     for(let i=0;i<4;i++){
    ! C7 r. I- ~- Z
  46.         ctx.setDebugInfo(i+"=",state.number[i]);; D0 f! B! C6 ~* X
  47.     }) O. S2 E3 K. }$ k: j  a3 {4 f' O
  48. }, A. _. H2 A; E
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    , ~  @4 m* Q  |' [/ h
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间* V7 ], f0 B% W; ]
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    , \9 D6 d, L! L) D4 X5 C4 p& [3 |
  52.         nu = Timing.elapsed()+long;   //更新播放时间- o( k! g+ D# Z1 A
  53.     }# ]. u  g2 K3 d6 T4 X- d8 Y
  54.     return nu;//返回新的播放时间: E8 z& O& w+ b1 P0 ]4 L
  55. }) |4 Z4 |/ h0 C" V1 K) Z
  56. function grnn(min, max) {//随机小数7 o- {" b6 C) W2 ?9 Y1 J# M& z2 D
  57.     return  Math.random()*(max-min)+min;
    & O* q+ b: f' E$ N0 v2 y' k' {
  58. }" E+ c, W( H1 t! ?
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的9 x- e4 ~1 y( F/ r$ b' Z$ R5 X
  60.     // 获取列车从车库开出的距离
    2 G+ {/ {0 v. O! n! \0 I# z
  61.     let railProgress = train.railProgress();
    ! {0 _2 P( g% S
  62.     // 获取当前轨道的索引
    , @* r( N9 I/ P8 Z2 q
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    ) w4 u& R8 }3 a% b
  64.     // 检查当前轨道索引是否有效
    ( z6 r. J' Q; n, S1 I5 |# z
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    + b6 s5 [" }7 |- a" p% q& l
  66.         // 获取当前路径数据对象# \6 V7 ~8 \- D; c" S- ~- M1 W
  67.         let currentPathData = train.path().get(currentRailIndex);
    2 H& G9 S0 K8 l/ ?+ t$ L; o
  68.         // 获取当前轨道使用的自定义轨道名称. K3 J4 F# s& y( k3 D
  69.         let trackModelKey = currentPathData.rail.getModelKey();
    " {5 }* Z  `2 J' z6 {; I: w  @( ^
  70.         return trackModelKey;$ G8 s+ c( p! }2 E1 ?
  71.     }8 \* Y5 Z& j  q4 [2 d. [
  72.     return null; // 或者是一个默认值
    ( V4 b( K4 J# m; s0 I3 r
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错) Z1 O; e8 N5 b( e" V6 _
有事加我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
) o, ]" j# K+ ibve声音要方便一些吧,他有可视化可预览的编辑工具
* z! }) L# a; s: S% }6 E
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 5 ~+ g' |/ e" Q3 [; T, e

% s  X: S  Q2 n* N7 [6 ]相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 % |9 Z. d0 v  a3 Q$ c1 O4 ^# Q, q
huliawsl 发表于 2024-5-17 21:12% z5 L& s1 E; L5 o* o) P: N
相较于此,我还是认为bve格式会更简单
: \  }* l0 ]: R* t
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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