开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 % w$ x/ P4 F  M5 R! y, i6 F& j

' U8 J9 b  x& _# m6 G/ c& Y- K6 S* s$ A1 N* T
最近在研究JS 做了一个简单的逻辑来播放声音
3 d8 d) E4 b" n& F
  1. var pit = 1;//初始化音高(速度)
    / @0 p+ d& R& \! N
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    ( \. L* ~: v: a; p( I
  3. function create(ctx, state, train) {
    ( S1 K' J0 ^9 w5 T" f6 V" h
  4.     state.number = new Array();6 b  S6 t. J  f% ~# Y
  5.     state.soundsspeed = 0;//初始化速度
    " a+ j0 k$ D1 n* Y; h, h+ e
  6.     state.speedsub = 0;
    ; p. v4 e1 q1 B
  7.     for(let i = 0; i < 100; i++){9 b9 k+ m6 U+ m4 v3 Z8 c! l
  8.         state.number[i]=0;//初始化数组
    & c4 T- x: Z# u$ J3 u, @
  9.     }
    " T+ d8 Q. D5 [# L
  10. }
    " b9 S2 H3 O+ o. T8 p6 `* Q
  11. 8 O  ?: @+ I6 f" a! }3 w' u7 x
  12. function render(ctx, state, train) {
      ?/ \" p, u% L5 Q; G9 M1 t
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    2 d" |% a1 @7 B
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)
    9 x5 d/ P& M: S9 h1 \3 O" u
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称    5 L$ g$ T$ x$ a; J8 E
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差" G2 E7 a) I% X; d6 W" A
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)+ X" p) e& M, J8 D: E
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作) P0 U, K1 S1 s) w" h
  19.         for (let i = 0; i < train.trainCars(); i++) {
    7 f, d' d7 K' c2 t( i5 z$ ^
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
      {" S$ d, k- ?+ }$ K& R7 }8 `
  21.             if(state.speedsub<-1){//如果车辆减速
    6 S9 p  L: [9 S$ ^% h$ w7 L  j. W
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
      t; P% [  a7 H0 ~& k( s1 H
  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
    . S2 D& K9 w) D) U( ?
  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 F9 S( m& F& e# a
  25.             }else if(state.speedsub>1){//如果车辆加速
    : D! B' y$ M( i3 U  b
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    . Z5 U' z. |- g& q5 s
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声0 o3 D/ _; Y6 p" g: [3 b
  28.             }
    2 |; h) r: T# @! n
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声4 ?1 F" C4 S/ x1 g# E
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声( ?% J; U- {4 {9 Q7 V5 j' L7 [' A
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启; E  N8 W0 B1 L$ n
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右% I5 H) \& J% x1 v7 `9 m+ g
  33.             }
    ) a& L" Q) m( @. Y7 A/ @0 e' v* X
  34.             if(train.speed()*20*3.6>5){
    + q- g9 t9 f* i1 p" R: _9 T$ G
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声4 ]2 e& V" [* \6 j
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声' X; ?4 P  t  e- \. }% @' V: F' A
  37.             }# e; J8 A' Z) d6 j
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    3 h/ z& b; g$ M* X2 g1 \
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    % L% N' W* s. P2 c  y) z! k
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    6 @3 b5 g! O2 D
  41.             }
    $ |: t+ b- y" W) Y$ S" P
  42.         }( V! O5 S+ _8 f
  43.     }4 ]7 n3 Y; O7 `/ K4 D
  44.     state.soundsspeed = train.speed();//更新速度: Q5 W/ Q' }7 P. @
  45.     for(let i=0;i<4;i++){, m4 E/ w* o# b& o
  46.         ctx.setDebugInfo(i+"=",state.number[i]);: o& R& v2 b; N% V3 O
  47.     }
    $ @+ `: g4 X& r' F& `7 A: y
  48. }& c' q. D7 t# x4 _7 k
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    " z! m+ N$ o/ j: T. J
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    ) x! ?5 g5 [  o+ v7 L- l
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放& B+ W4 M0 ?+ y0 ^" Z- U
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    ; {  e5 o+ H1 R6 D
  53.     }5 v4 J0 P8 P5 z: w2 z/ w$ M! ]
  54.     return nu;//返回新的播放时间
    - C* x3 P/ Y: L9 o
  55. }8 A$ S$ r- u& q. {3 _0 d
  56. function grnn(min, max) {//随机小数0 L! l" R' ~  H& d
  57.     return  Math.random()*(max-min)+min;6 s; F" [% a, [# e% M/ N
  58. }9 J- A9 n* E9 o) ~0 n7 ]
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    ) m( K: C% V( z
  60.     // 获取列车从车库开出的距离# d( E! k8 @: d! u, \5 q/ ]" G: V
  61.     let railProgress = train.railProgress();0 X. L2 }* }2 R  \1 @' p
  62.     // 获取当前轨道的索引5 q, F5 |$ y0 l( W  B- ^
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    ' z" r- l5 D$ X6 f
  64.     // 检查当前轨道索引是否有效+ p6 c* W1 u; ^. G; Q
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    ! O5 k7 e; W. ]4 x( ]  T
  66.         // 获取当前路径数据对象
    ) L, E! _: k1 e( z* o7 r
  67.         let currentPathData = train.path().get(currentRailIndex);
    / Y; I2 v& @' V$ S, p& M' |/ H
  68.         // 获取当前轨道使用的自定义轨道名称
    8 T5 u, P, ?3 Q3 A1 n8 I
  69.         let trackModelKey = currentPathData.rail.getModelKey();) S' r# \3 u  X# J" C
  70.         return trackModelKey;% J" U" A( u4 j5 G2 ~
  71.     }8 R0 r1 B0 `. K6 S
  72.     return null; // 或者是一个默认值
    ! v& i- {" |, O% f2 P! z8 H: W1 C
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错' x9 J% d" O& d6 C5 T/ f! o
有事加我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  I: Q& O. v3 `& H
bve声音要方便一些吧,他有可视化可预览的编辑工具

1 R" u) ^& q: e, Z8 u& z* i嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 % V8 Z  T" b& O: [
8 S/ u; \7 }3 W" `5 o" Y# V. \
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 ; r% u& K& g' D3 t
huliawsl 发表于 2024-5-17 21:12
) d4 ~7 r- ~/ B+ C" I0 n相较于此,我还是认为bve格式会更简单

$ q* l% B& m2 A' ^% J🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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