开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 : A, p" ~4 }8 C. K0 |

" L2 V" i. Q$ ?3 O# P7 Q* o& \+ u" Q( Z/ L
最近在研究JS 做了一个简单的逻辑来播放声音
2 E% n; \; V5 l, p* P" D
  1. var pit = 1;//初始化音高(速度)+ Q) q6 i& p7 R6 Q( i! b6 Y
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]* x' [2 ]6 j8 Y! f2 ~. u
  3. function create(ctx, state, train) {6 n; H/ r8 `& o' E) Y2 j6 E- i
  4.     state.number = new Array();
    ) Y- A% P* @2 I! J
  5.     state.soundsspeed = 0;//初始化速度. S: P3 R) K/ S5 @$ p7 F
  6.     state.speedsub = 0;9 m& S: B$ z3 v, ]3 l
  7.     for(let i = 0; i < 100; i++){* e' `. ~7 `" F9 Y+ I5 I7 L
  8.         state.number[i]=0;//初始化数组, Z7 n% f% Q& b- b5 h
  9.     }/ Y4 F) G9 @0 f5 t# b, O8 v
  10. }
    7 \2 E) [' {# j. n5 o, M. Q

  11. 6 Z1 d4 p# Y# P
  12. function render(ctx, state, train) {
    , T1 z5 U& l# w' k/ B0 G
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动7 E3 Q- q6 [0 H& q+ v2 A" b. g
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)) N* W( m) M& b6 |9 C: E7 \
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称    : S. n% ^: H+ c8 Z- h+ V2 H/ I
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差  N7 P* r' O6 w4 v% _* J- N- R
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    . o1 L8 R7 U) ]+ O- N  ^
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作; ~3 t: a, e0 k
  19.         for (let i = 0; i < train.trainCars(); i++) {( W1 K9 g/ m/ h! Q0 |, M% B( f
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启6 h. ^; w3 g0 ^8 C; m$ k
  21.             if(state.speedsub<-1){//如果车辆减速) Y1 h1 x2 l9 `  {! Q- G# n! B
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    2 \8 }' ~/ Q+ R
  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# l7 ?% B4 _! A2 \9 w/ k3 c
  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
    ( Y: h7 C+ f) P6 y/ W  i4 i7 R
  25.             }else if(state.speedsub>1){//如果车辆加速$ [% `% G8 K3 f# y
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    ; ?1 n2 r& c8 t/ N' D( C, [6 f
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声2 ^3 ^" ?' j4 n  \, y
  28.             }
    8 m! M" f3 s, ?. {' ?* I
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声* p  r( r- Q) T; N- x; S* y) i# {) \2 p
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声2 j' P, n$ @. O- w3 q
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启7 Q' V; S. h+ \; Y, P. q3 c& s
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    " w7 ?3 S' l0 Y1 o% f  e0 a9 |
  33.             }
    & X/ d) e1 N3 t5 J* [
  34.             if(train.speed()*20*3.6>5){
    6 l5 G( M/ O3 w9 p" E1 b
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声' _, S! G( f. c( i& C. J
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声4 e8 F# i) _* }$ U7 W
  37.             }
    % W+ s/ `% U: D: T+ J; k
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){! K: H3 s6 U5 x; `
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    * V* a. S, M  R
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声6 g; S' S% k: Z# m7 @9 s5 i
  41.             }
    & M$ d  c, C) s3 [) U( d
  42.         }
    + I) w" H1 K5 b* D
  43.     }( h$ y* O# }5 V$ G1 C6 ?
  44.     state.soundsspeed = train.speed();//更新速度
    0 g( ]! O1 i+ [; T  ]# C4 Z0 G% g+ K2 A
  45.     for(let i=0;i<4;i++){
    7 {0 ^$ S: [6 I' P) S% V5 I
  46.         ctx.setDebugInfo(i+"=",state.number[i]);( L& J. U: b* h4 ~& L: }: X
  47.     }. f& n" [" W! @$ [9 G; W
  48. }: n8 S. M( u% {! t' I; p. Z( I  y
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间0 `# k# ]- x7 J& G# G: m" ]+ K
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间7 b0 i0 F! w& v0 g  p
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放8 B! l& g6 W  z. {3 `0 a
  52.         nu = Timing.elapsed()+long;   //更新播放时间& q# ?9 `; _& m; u2 J
  53.     }
    3 W# X! m9 y- q) O% }' t, O0 o
  54.     return nu;//返回新的播放时间
    . J- q- U* s7 _" P( ?  Q/ G2 e
  55. }
      \+ [1 [( z- Z  M" _9 T: i
  56. function grnn(min, max) {//随机小数+ ~' a4 P2 J" s( T2 b; s  O, v$ X6 s
  57.     return  Math.random()*(max-min)+min;
    4 ^0 C4 g: x" l
  58. }7 o% R/ H- t3 T5 D1 o+ H
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的# R+ M7 h" m! B: u- Y+ L% H
  60.     // 获取列车从车库开出的距离0 l; |# W5 u0 N# A; ~8 e- l  J4 b
  61.     let railProgress = train.railProgress();7 b; T4 A$ `& O) K8 T2 r6 B
  62.     // 获取当前轨道的索引- i2 q- T) r. C5 c- G
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    1 x/ X! @( |* X, X
  64.     // 检查当前轨道索引是否有效; H4 |0 r! o) P: b5 @8 S0 n
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {5 w  O) f1 d; D. l! R- ~9 i
  66.         // 获取当前路径数据对象
    6 o" S, {% j6 U! P1 o
  67.         let currentPathData = train.path().get(currentRailIndex);1 Y0 o$ O* D. O$ [4 [3 R8 T6 Z
  68.         // 获取当前轨道使用的自定义轨道名称
    ( g5 ]/ ]" w8 h
  69.         let trackModelKey = currentPathData.rail.getModelKey();  W9 W: ]. n! B
  70.         return trackModelKey;
    # x+ }% }% s) z5 ]' e
  71.     }- ~; Y5 R1 R9 b  g) m
  72.     return null; // 或者是一个默认值& P: |$ i9 b  b7 U+ q3 `& p
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错) @) F* {' f% T
有事加我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
& \' s. P* t/ X2 z: M5 L/ Ebve声音要方便一些吧,他有可视化可预览的编辑工具
1 ]+ w/ @6 k5 d7 X% F  c2 w' J" f/ N
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
+ Y) \! \; J; [% S9 b$ M0 [% _6 n+ T, d5 }
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑
4 f/ K" t5 L* s8 F  n. @
huliawsl 发表于 2024-5-17 21:12
5 G2 Z' R# ]) O0 C+ O: d相较于此,我还是认为bve格式会更简单
. A  {' M" f7 X- B& r1 C: k3 X3 ]
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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