开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑
! J' |, V) W. [2 ^) p$ t
: T- r3 N0 A2 T3 m) f  c: D1 ]/ p$ f
最近在研究JS 做了一个简单的逻辑来播放声音
" |& F5 J5 P" Z3 ~* B; B3 I+ R+ L
  1. var pit = 1;//初始化音高(速度)$ H/ w# l9 Y3 ~; F0 c3 N/ u
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]# Q2 S' w1 l  p& q3 ?0 A
  3. function create(ctx, state, train) {# P' t1 Z6 b* {4 c/ |: p
  4.     state.number = new Array();; L6 S" S$ D9 k+ k) o$ n8 t# N4 W: c! e
  5.     state.soundsspeed = 0;//初始化速度4 [; j9 n* x/ L" F6 {
  6.     state.speedsub = 0;# ^3 Z9 v9 c2 C# s+ {; V/ N
  7.     for(let i = 0; i < 100; i++){8 p/ C! [( }- i1 B; }
  8.         state.number[i]=0;//初始化数组
    , L5 `6 z9 D4 K; r+ X9 ?
  9.     }
    % Q2 N, z8 x% Q8 t6 S4 g2 k0 Y/ k
  10. }
    % ]- K. s0 }5 Q5 J

  11. $ J0 s0 n% l, s! a7 s% m' `
  12. function render(ctx, state, train) {
    4 w4 s& s( Y6 p% I
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动& [% _& ]3 H3 B7 j# @9 z# R
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)
    ) F, `4 N/ a  W
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    ( U( T+ J7 k/ u
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差+ s8 y% W' Z% \: U
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    ; u: d* u! @! y. o. H
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作+ |2 {0 E  `8 Z/ k3 K, @7 }+ |
  19.         for (let i = 0; i < train.trainCars(); i++) {9 E+ G. E& q% ^; u  H
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    + S! v( Z/ }1 ]  _: I
  21.             if(state.speedsub<-1){//如果车辆减速
      D% t  c, s/ A. i  C8 `# S
  22.                 ctx.setDebugInfo("shache",1);//记录刹车4 R. `( f2 d) k% {" v8 B9 O
  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% H2 N! H1 U, v$ ]4 E7 {
  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- z& q# X& y4 w& ^
  25.             }else if(state.speedsub>1){//如果车辆加速
    ! s+ w( z' `. P8 S2 D2 P
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    # p% a: p: o3 M' X! |1 [
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    & h" ~: B) v( o  Z) U/ H! _: O
  28.             }3 r& l# M9 d3 [0 ?2 ?! O
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声8 p% j  r6 f/ S  p. U
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    9 r0 y4 i+ p+ L) a# X# f
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    ( j; a" x  ~' j0 V  ?+ E; E
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右% {* J( c& d" k6 f
  33.             }) J$ N2 P" i$ |% w7 {5 H
  34.             if(train.speed()*20*3.6>5){
    : B3 A0 f; H4 p( ]; m: r
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声( q) ^1 |% D2 ^' {. K" Z5 u& n5 l
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声
    % K: W$ C$ M+ ]3 h0 N0 A
  37.             }8 v! i6 c$ B( Q9 o5 E' ~+ [3 d' f
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    7 Z! l  A( Z9 s2 d' L: m1 j
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    + Y$ Y1 d; _% ]# `
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声5 B6 t6 K  O, X* L9 }6 H" A' Q5 N
  41.             }8 h" D3 o2 P: o# B/ m% l, Q* Z
  42.         }
    8 ], g8 c$ ^5 {
  43.     }0 f% S9 U4 @6 g% Z5 k9 k# R7 h& _% }
  44.     state.soundsspeed = train.speed();//更新速度
    * A  K" e$ v# j# q  {& ]7 e9 a
  45.     for(let i=0;i<4;i++){
    1 g) z; o" D) w- i, h
  46.         ctx.setDebugInfo(i+"=",state.number[i]);' i( i, H, i; y
  47.     }
    6 N/ u+ d: C% N+ ^$ ^) \
  48. }
    5 V+ f+ P( i9 B4 r  s( M
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
      H% D7 s% P0 u5 j* F: M; X1 z
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    4 s8 s0 ]; R9 E/ F# C, l+ n! L
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放$ k6 A3 C8 @% Y9 W, I
  52.         nu = Timing.elapsed()+long;   //更新播放时间% ~* F/ \* F$ y" y' |3 H
  53.     }
    : O/ ?% ^( f1 I- Q
  54.     return nu;//返回新的播放时间" x# k1 B# K" r' m; ?! n/ Z' ?; o
  55. }! ^4 B$ c  L) K3 t, ?! R
  56. function grnn(min, max) {//随机小数
    5 c% n6 E, n  m, \( E& s
  57.     return  Math.random()*(max-min)+min;0 x5 y# B, H8 w* Q* K7 i
  58. }. e- M: h" y9 Y, z- b
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    ; T. _: j; w" g. Q9 s6 h
  60.     // 获取列车从车库开出的距离
    3 @' }) \# o0 `2 @5 _$ r
  61.     let railProgress = train.railProgress();* x, ~" y) z1 W  N' r, `2 `$ v
  62.     // 获取当前轨道的索引  p3 Z9 L% W+ `5 a
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    ; i% s# z2 j- a! V) o
  64.     // 检查当前轨道索引是否有效5 O6 y9 s4 x8 u% L2 ~% W
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {. s2 p8 f$ X- r" Z/ C
  66.         // 获取当前路径数据对象
      g& F* e3 V  o, f& r
  67.         let currentPathData = train.path().get(currentRailIndex);; U4 Z* O! w1 H8 e( J
  68.         // 获取当前轨道使用的自定义轨道名称3 ]% v. |1 U+ U6 p& y: v: q
  69.         let trackModelKey = currentPathData.rail.getModelKey();
    8 g$ g! h( a: b1 M
  70.         return trackModelKey;$ q5 }) [: A, \$ O3 k
  71.     }
    * Y3 E3 j( l! ?" D0 E* w
  72.     return null; // 或者是一个默认值
    ( Q; p0 f8 }  d4 E* z" U
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错: A( h  R% E# K; G0 x& W) 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
) O6 m: T7 u" k1 M: g2 hbve声音要方便一些吧,他有可视化可预览的编辑工具

, Y+ J1 g0 r$ p4 q  g9 i; R* H嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 : G# g6 P( ^& z3 n( i6 u

4 L& z  C) I6 d相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑
7 X" C3 \9 L. |+ l. D9 c) @
huliawsl 发表于 2024-5-17 21:12
- X7 H3 N# O% M8 d( G' w: l相较于此,我还是认为bve格式会更简单

7 c. g' e; R% a  w9 l🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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