开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑
! ~' a- u  Q6 ~8 s
1 R. @, u' x9 E# k" \2 L. G  C  \; K. Q
最近在研究JS 做了一个简单的逻辑来播放声音
0 E  `" y6 y/ l. H( n: P
  1. var pit = 1;//初始化音高(速度)  I5 x  y: F! u& [$ @$ _
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    0 Z2 ?4 H/ x5 c! [" p) o& s& q
  3. function create(ctx, state, train) {
    , V5 v, e3 N* _- ^: K& v  _  S4 q
  4.     state.number = new Array();
    % K4 c: E8 W$ M2 f7 W' {/ \
  5.     state.soundsspeed = 0;//初始化速度# x1 c; A. G+ I% H$ ^4 @' |
  6.     state.speedsub = 0;, P/ F6 Q& I& }3 ?6 g3 L# `
  7.     for(let i = 0; i < 100; i++){
    / ~% R" {, Q0 M/ y
  8.         state.number[i]=0;//初始化数组: [' A* h( K7 t, ?
  9.     }' `' g1 Z: P2 K6 Y3 |" k
  10. }
    9 U  z$ v0 y; x7 B" e
  11. ( ^6 c+ i8 z1 x% F
  12. function render(ctx, state, train) {
    4 r( ]) G4 P; c% U+ ~
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动. I6 Z: @5 O- _2 [8 u, g
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)
    ( x; }# O$ o8 B' r4 G- c
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    : ^3 d; @" `2 }1 u
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差7 c$ p7 z  Z1 }9 X2 l
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)% {7 F9 s/ A) P; j# ~
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    ! q* k5 p6 e* U2 E$ c( J& V+ D
  19.         for (let i = 0; i < train.trainCars(); i++) {, U- `; K5 w* c1 h+ x
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    & ]/ J- a( v0 J- w
  21.             if(state.speedsub<-1){//如果车辆减速1 }9 F  V4 x7 h
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    % h2 m7 U$ N. N6 Y! {
  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
    + V/ ~/ y( |7 K4 d3 O3 y  ~- 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
    ) X( t: j; t, s+ B
  25.             }else if(state.speedsub>1){//如果车辆加速
      J+ X" a; T' I0 _
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速' W$ I' ]* ]5 C# a1 N' g3 Y
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    9 J2 Y/ @1 k! y2 Q; ^
  28.             }" _5 N7 @8 i, U* y, S
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声& Q' S9 q7 m% I, F/ X$ x  k
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声, L9 Q$ {2 ]7 |3 O2 h2 T- g/ k4 i
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    % N& ^* f% l& p( K7 G8 _: ], F+ ?- [
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右, n/ K5 s- r/ `2 X" T. Z1 s; z
  33.             }6 ~$ D4 t* a& R0 S2 W; {4 [$ M3 W
  34.             if(train.speed()*20*3.6>5){3 j/ H+ f2 j/ G
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声
    + i4 p! y# S1 S! B3 K5 e) Q
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声
    5 D( A2 Z1 `3 {* U& K9 n
  37.             }
    1 h5 f; K5 A. k( G) O. E  \  H
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){: @: v8 q& o+ Y, U! z4 {  [2 m
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声, a* ?" t6 @4 M" i- f
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    0 i- f6 B7 i, U' a
  41.             }/ ]0 q( h7 ~0 R5 X
  42.         }5 ?" V# h, W) z, o! n1 Y( H
  43.     }) M; o$ a; ?5 [2 s
  44.     state.soundsspeed = train.speed();//更新速度+ N- n5 p+ U) @. m( n" c9 x
  45.     for(let i=0;i<4;i++){
      [, p! ]9 T1 ]6 A* Y8 G2 U
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    % B. ~6 p9 T0 s* H
  47.     }/ z1 e4 `! E% o8 k3 w% p5 G
  48. }
    6 o0 r1 b/ K4 d+ _! v6 m
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    $ c; ]8 P$ ?0 ?( |- Q- B
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    ; l) I6 y8 _5 S+ j8 _* I
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放" V' T, c4 B& \6 S
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    4 Y$ Z7 c4 Q  e" `
  53.     }( i) O  V( A! Q
  54.     return nu;//返回新的播放时间
    0 |, G: s8 f; J. W
  55. }
    ( v6 y. n) }) y) O+ d; m
  56. function grnn(min, max) {//随机小数- ?) X) K" z5 ^: B) Q( x: L
  57.     return  Math.random()*(max-min)+min;* R9 J! Q, M! M, S- J
  58. }
    ! L7 U3 w  d: G7 l  ?9 u, z3 j* [
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的1 E: j' F% B$ }  m* [* J! W
  60.     // 获取列车从车库开出的距离
    8 ^% c) K% i4 l2 Y: _& h% t# p
  61.     let railProgress = train.railProgress();
    ! x) ?7 o3 v: Z2 j1 \3 v1 r, w4 p
  62.     // 获取当前轨道的索引' J- H/ W7 ~1 H6 {/ I( S$ n
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    / p# E, C) s$ O- ?* X0 L, c4 O! g* o
  64.     // 检查当前轨道索引是否有效5 e- d+ M9 \8 K. ?3 `
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {' {' l! I/ }, n8 R$ ?: }0 l" f# |
  66.         // 获取当前路径数据对象) o" h3 R3 q: @& ~+ q3 ]5 t
  67.         let currentPathData = train.path().get(currentRailIndex);$ b2 o) }$ A3 w5 f/ T' u  S% C$ r
  68.         // 获取当前轨道使用的自定义轨道名称3 A# L+ _4 Q- N) O" S) U  ^! Q  q. E
  69.         let trackModelKey = currentPathData.rail.getModelKey();
    ! r  t3 }. Y- O% j  b8 z9 I
  70.         return trackModelKey;& _9 F, T2 N2 c+ q6 Q
  71.     }+ q; T5 U/ T) \" [3 K
  72.     return null; // 或者是一个默认值. G0 @5 t8 c) ]! y. ^- h
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
5 k, P# B2 G) a! S; P5 A( j2 d6 ^, W8 J
有事加我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:046 g, f0 w. P' F1 J
bve声音要方便一些吧,他有可视化可预览的编辑工具
& e; S$ T7 V1 [7 v1 H$ g( p0 W
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 ( w' l" }; U' I* S( l$ c
! ~6 c2 V) _% W( y$ q$ j
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑
" ]9 G0 c, j7 f5 f3 p. w2 T7 i
huliawsl 发表于 2024-5-17 21:12
% K( B/ K, V/ @3 h相较于此,我还是认为bve格式会更简单

+ D- Y* F  }+ Y0 c🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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