开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑
! ]0 U' b% r, c& k
6 j' F6 g% a3 P, A. j5 {3 `. [' H
4 F2 w1 t3 e' F+ N最近在研究JS 做了一个简单的逻辑来播放声音
7 }* B) E- x. e0 c8 g
  1. var pit = 1;//初始化音高(速度). N) G- R8 X) H2 Y( K; y
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]. R& t: L/ D2 S6 |( T
  3. function create(ctx, state, train) {
    8 ~2 C, V; d& I) z5 Q3 G
  4.     state.number = new Array();* h0 T9 R% w0 M
  5.     state.soundsspeed = 0;//初始化速度
    1 ?- t: Z! t3 ?7 ]4 b
  6.     state.speedsub = 0;
    1 j* D$ ~4 Q3 q9 u7 r' ^3 s. }5 V
  7.     for(let i = 0; i < 100; i++){
      K. }* o, v) o
  8.         state.number[i]=0;//初始化数组' Q2 \- M  p, d6 e# d" T# d, I: A  I
  9.     }: A  P; w! m1 r! f- G" |
  10. }
    ( G1 c7 P# U6 p& |9 A4 |" x( V

  11. 5 q+ b0 a7 ]# c# ~" {. S
  12. function render(ctx, state, train) {
    . |+ [$ C  O) H0 ~
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    9 h  z; \. ~+ I% d3 {1 _1 m' B# f
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)7 [2 I! x- c/ l2 A6 C, h3 M; a6 p
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称    1 {9 x3 i. p9 ^, M5 l
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    : n, Y6 q* z. W
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    & e; V# m/ ]- |! w* X; E
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作9 i( O5 Q, U7 v- o& ~$ [$ W. l
  19.         for (let i = 0; i < train.trainCars(); i++) {
    : y  c; H& g: a4 S6 H* u9 r
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    - U3 T) `. [8 w2 i! a3 q8 g" n9 p: p
  21.             if(state.speedsub<-1){//如果车辆减速
    0 ~  }! X4 _& g- ~$ r* W
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    1 S" c. s6 n6 G  L
  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
    ( _8 b6 h$ l# i; N; l+ I
  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& A4 [% F; e# U1 {
  25.             }else if(state.speedsub>1){//如果车辆加速
      o; ]) s9 ~" t* i4 G  I
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    " G9 x7 Z/ P; [7 e( i
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声5 @9 D" c; j2 ?# F
  28.             }
    ) K: }" h8 a  p
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声
    / w3 V( I( Z) h0 E7 l# D
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    ) X$ g2 D% o5 r+ ]; v5 E
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    7 O% L# O) h- w. c7 G
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    / K6 q) B+ ~3 i' B, o$ W
  33.             }
    1 ~( v- `/ m1 I9 a# Q
  34.             if(train.speed()*20*3.6>5){/ Y' g5 t( p9 o, u0 x
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声2 w; [% e& g4 {2 t( W% I) K; F
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声3 _/ A3 O9 Q- G3 A: c
  37.             }
    * `' s/ h- |) ]  }" ?6 I
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){+ M  s; [7 B5 a6 {5 @: e
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    & g. p2 Z# I% w) l$ E7 q
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    + S0 J. P3 q3 F; _2 j
  41.             }
    & U% F& ^# d4 J9 f
  42.         }
    2 m5 q/ t1 i- P
  43.     }
    % A7 M6 q( s3 B
  44.     state.soundsspeed = train.speed();//更新速度/ |. R$ K) E+ M# J& P6 b9 K' I
  45.     for(let i=0;i<4;i++){
    " n1 T0 }+ Y3 w( ~
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    * [( a7 J7 V) k7 d; [' a
  47.     }
    & ~1 Q4 G: e5 h& v0 O* v+ T( B" [  F
  48. }
    ; b9 q: O8 }* c) X5 a$ P) Q# z
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间8 G! @: F1 _* p8 V6 y
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间2 W- |; K1 J  v& _7 m
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放( O4 `0 |* T0 B, T: g3 y8 l" {
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    $ ?) b6 b; H* R
  53.     }+ I! s' o3 W5 b
  54.     return nu;//返回新的播放时间
    $ B: _: }' P5 o+ ~8 G
  55. }$ R# J8 z& p# u% r1 M
  56. function grnn(min, max) {//随机小数
    * e( {: P4 X$ m6 ?. d' k
  57.     return  Math.random()*(max-min)+min;
    " }& ]- w- B' b' X
  58. }  Y5 A6 m5 |- U: u2 F: O
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    3 r7 R' E9 W5 }: q+ a. j
  60.     // 获取列车从车库开出的距离; c0 O7 t! t* i, i% |; I/ G0 n, N
  61.     let railProgress = train.railProgress();: m; I3 O; m6 u4 J/ |+ d
  62.     // 获取当前轨道的索引6 K$ Q# F. X$ H' t8 _, H- {
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);* C7 `; V( \3 a! [" o
  64.     // 检查当前轨道索引是否有效, w- }. H, }8 \; D6 U" v
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    3 ^6 d% b) w+ b% t+ u9 q) z; X
  66.         // 获取当前路径数据对象( y  W- I! `( v2 t
  67.         let currentPathData = train.path().get(currentRailIndex);' U# W0 a. X, B2 E& q0 ?8 {
  68.         // 获取当前轨道使用的自定义轨道名称1 V% Z! C/ K  D/ d6 I( X! `. A' X
  69.         let trackModelKey = currentPathData.rail.getModelKey();
    8 m3 t8 E7 O+ u# u: A
  70.         return trackModelKey;
    9 G* G: m& O0 o* k
  71.     }
    ; S! k$ G8 C! O
  72.     return null; // 或者是一个默认值9 ^( m" o1 i1 R+ C9 t) `! [
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错- y' q$ y) G3 ^% J# ?" d
有事加我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
/ Z. ?1 H" t- |: P8 obve声音要方便一些吧,他有可视化可预览的编辑工具

% P$ z8 k+ i! z+ f. f% |9 Z# R嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 " o2 N" }9 {2 Q5 G- a
, C2 r7 N: b* C/ _
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑
# y- }- p# K/ o/ {0 f$ n' u, b& t
huliawsl 发表于 2024-5-17 21:12
  S- ~8 t) A5 ~1 K相较于此,我还是认为bve格式会更简单

3 A7 \) L, _, l8 j1 x🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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