开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 9 ?  Q2 S4 r0 w" G

0 D5 Z( `7 h) O2 b8 `' g* ^/ D5 ~  T$ C$ ^! C8 w* {
最近在研究JS 做了一个简单的逻辑来播放声音
8 C1 @' r* U2 t# A, I. g5 n
  1. var pit = 1;//初始化音高(速度)
    7 S' `( m( w; J
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]& l% \6 v4 t; T3 t8 Z/ i0 E5 `3 C1 ]
  3. function create(ctx, state, train) {
    5 i5 w; [% w/ c7 C  {+ I" u5 N( w
  4.     state.number = new Array();' h( s) O: _4 b! p2 g
  5.     state.soundsspeed = 0;//初始化速度
    + T# W+ j+ w1 U: Y5 j* }4 V
  6.     state.speedsub = 0;5 x: U5 L: n  ?6 ~+ [8 z% l; H( y
  7.     for(let i = 0; i < 100; i++){+ T/ r9 [/ C, I2 w
  8.         state.number[i]=0;//初始化数组/ x: \* ]; b$ X5 E' j8 @7 p, M
  9.     }
    + G2 c2 v* u3 O* ]2 X$ E
  10. }1 f4 O8 \# N% T& n( a

  11. ' |5 b- |& @, k: k  i! v
  12. function render(ctx, state, train) {
    1 l4 I6 a/ Z! D8 p& E5 |
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动* n9 z* E" |# B5 ~& w
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)
    . `3 F% n& P/ Y7 L1 W& E( G: f7 H
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    $ K" ?* G* P; a+ t- ^. x8 z8 X! L
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    ) j; E9 t' B% }! Q4 _& Z
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    6 T. A# r" P( ~; R
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    - l! c$ @7 O+ A! l' _) [. n, [* H! L
  19.         for (let i = 0; i < train.trainCars(); i++) {
    & g3 ]* l: R7 ^
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    4 s$ t6 M% M/ X
  21.             if(state.speedsub<-1){//如果车辆减速
    ) Y/ Q* H5 C2 i8 G0 L4 A
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    ; H7 N; v$ B/ }% `; I) {
  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
    3 }* Y7 C8 c8 X& A: k
  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
    5 ~8 a" C' z5 K0 m
  25.             }else if(state.speedsub>1){//如果车辆加速
    - j$ T" [4 j0 B( ]2 c0 X, N
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    : e3 O/ N3 N- v1 }. Y" S0 s1 a
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    ! G3 d- M6 H' Q; V3 d, ^$ \
  28.             }
    . o% G/ j$ o! R: A# n" o
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声: Z5 ?/ S% N7 F
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    8 s6 Z# K& Q* j
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    . [; r- H  U  ~# `$ q* E4 s
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右% W& v' w5 e# S( Y! |
  33.             }
    : V+ i9 d( ^5 R& \9 }* ]
  34.             if(train.speed()*20*3.6>5){: R# b7 V  [' ]8 {! a+ v. O4 v7 c
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声4 W; \$ R' P2 U0 Z* M
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声1 |9 `( @! G3 X
  37.             }
    ) ~) }! Q5 e! L, L* w" O6 O- y# ]
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    $ F- G8 s' `9 I( Q4 b$ v
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声$ u5 ^! p' r# b/ X. p5 n
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    8 p9 m3 ?' L/ f, T/ \
  41.             }; r) A+ g& v5 U
  42.         }
    + b( w5 t( q- G4 _7 d
  43.     }! @( H8 L9 j/ o+ y6 e
  44.     state.soundsspeed = train.speed();//更新速度! `$ X, B" b9 r0 F4 G
  45.     for(let i=0;i<4;i++){
    ( q4 F, P5 v- V, Q. x* C, p3 W+ u- K* c
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    8 {! B- E0 c8 Y0 A/ E) F
  47.     }. N7 [5 D. p1 m2 @5 C4 m" `
  48. }
      B" ^. O+ h1 q* V* v4 @( y
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    5 ?6 b, y9 X& e- o/ J; ~- D! g
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    2 s9 ^. H9 H0 g
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    + S* u7 Z( i( F: W/ r1 {  W% X
  52.         nu = Timing.elapsed()+long;   //更新播放时间7 c7 K" k2 K) Y  B% w
  53.     }. L% g' T  n2 [: A- W2 ^* h
  54.     return nu;//返回新的播放时间
    3 Q9 }/ o7 M4 w) j+ `; P- ^
  55. }
    $ f! B1 ?; x0 E' c2 j0 [- P
  56. function grnn(min, max) {//随机小数
    + k* v2 O" h% m! C1 R
  57.     return  Math.random()*(max-min)+min;! y. ]6 c- v/ `$ j( v
  58. }+ G/ q! Q% t- e; @
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    * ^" ^$ ~2 m8 p2 a) Z
  60.     // 获取列车从车库开出的距离6 z# M8 J( I5 k) a! A
  61.     let railProgress = train.railProgress();
    ' w$ _9 |, W& ]
  62.     // 获取当前轨道的索引
    * X# v& j$ D9 e' |. B! b
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    0 B6 x" g; c7 z$ y  f+ n9 [1 r6 w
  64.     // 检查当前轨道索引是否有效7 V0 h5 o' _- B3 M
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {" J3 C! F$ M( m( j
  66.         // 获取当前路径数据对象
    ! f8 }  p9 m1 y2 I& A, m1 f2 o
  67.         let currentPathData = train.path().get(currentRailIndex);' a" J  e% u+ Y0 T
  68.         // 获取当前轨道使用的自定义轨道名称
    , N' q  t2 t7 t0 u
  69.         let trackModelKey = currentPathData.rail.getModelKey();0 v( M. a* D8 L* k; g$ a
  70.         return trackModelKey;3 R' z3 @' \! A! y( A7 Y: H) D
  71.     }) ?$ z$ S: S& m
  72.     return null; // 或者是一个默认值. ~, R& ^0 [( c+ E9 Q
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错" z' Z5 Q9 ?2 w- Q! `5 G- p8 h
有事加我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
$ @- b2 L7 x. g9 Z1 v+ P0 T; Sbve声音要方便一些吧,他有可视化可预览的编辑工具

  T2 H0 X8 ]5 J4 U: \1 i/ w9 x# f嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
回复

使用道具 举报

huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑   J( @3 l2 q$ ?7 w' a$ i0 s: ~

6 ]# i+ z' x+ f( j: e1 N相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
回复

使用道具 举报

楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑
' B. L& ^8 w3 b9 m- w# b) v9 V
huliawsl 发表于 2024-5-17 21:12
# h: q- o& L2 M# ]相较于此,我还是认为bve格式会更简单
$ o3 P6 W0 F. T  {' T% t
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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