开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 ! Q% I! P% s' M* {( w0 q
! ]: e* k- {1 z2 [
0 D3 G( i  x) I' k9 ?, N7 i: |8 J
最近在研究JS 做了一个简单的逻辑来播放声音
# N8 A3 K) {  U) o& S2 E8 `5 D
  1. var pit = 1;//初始化音高(速度)
    % |( Z8 Q0 e' T8 s4 L; A& C) v
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
      w; i% ?8 k+ A7 N! j$ A- C
  3. function create(ctx, state, train) {9 l' l, k5 S7 ]  u2 F% b$ Q
  4.     state.number = new Array();, Z: K- m9 h) f0 C$ v8 C" s
  5.     state.soundsspeed = 0;//初始化速度
    ) {9 f; ^2 m# `4 R
  6.     state.speedsub = 0;
    / w9 r3 w  J9 F2 x
  7.     for(let i = 0; i < 100; i++){. I6 V# P) M8 \% y5 \
  8.         state.number[i]=0;//初始化数组
    0 u) M5 I4 _0 B8 x$ ]$ e" l. j
  9.     }3 u# N. K  l# L, S" i# l/ u
  10. }
    3 `6 E' X  [2 f4 o

  11. - v. W2 O/ [; q5 e6 f: N5 o" T
  12. function render(ctx, state, train) {% M0 ]* C1 b: u  m, q. F# Z5 t
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    ' I4 P' j6 t5 H
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)( _: X0 z# A& h! j" E6 u
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称    7 k# X0 _4 w: g3 z/ Z: V" t
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差$ C9 B3 g/ s( H4 Y
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    + o* K% r/ k$ w; o; }; N4 l9 z
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作. H1 a  D4 B( H. U
  19.         for (let i = 0; i < train.trainCars(); i++) {
    ) R6 i3 i- R/ a8 X( m
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    % |# r- I3 O" f0 a' A2 G
  21.             if(state.speedsub<-1){//如果车辆减速
    7 V" i# H6 ^. j# i
  22.                 ctx.setDebugInfo("shache",1);//记录刹车8 d+ V+ w: H- [, u4 K. `
  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! n$ i- w8 }4 d9 z. r
  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" F9 v2 n3 f9 y) v( w
  25.             }else if(state.speedsub>1){//如果车辆加速
    + Z! f; u. }) I- E) m( R! y
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    3 ^. V# q6 M: \: a- W1 H, W& ^
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声, G# d: z1 a2 t( j4 A: u0 G; X- B3 H
  28.             }! _' I) P; d0 O9 S
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声; D& V: _+ i4 n% P3 E- X
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声$ P0 y% A. N7 e5 k$ s$ s5 J
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    3 |  U- E+ Y1 o9 ^$ X  ~4 N- |
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    + @8 ~: Y) ?: P& O! _" C
  33.             }3 x# R; g$ m+ X
  34.             if(train.speed()*20*3.6>5){$ `" d- z( J# U: S3 t
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声, l2 H# x+ h2 f9 ^0 G3 V
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声
    ! b1 ~& m- E0 E. E; E
  37.             }
    ! T) C( ~( p& n1 V1 O
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){0 u7 C* [7 k4 O
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声7 u; H. ?" X5 F% l9 R1 C( {$ y
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    9 y+ |$ V) v, @. Z5 E
  41.             }
    ) w. d7 i: k- A6 A! O$ {; L8 j
  42.         }1 o' j7 |6 S" k3 g
  43.     }/ K2 E; C( d# i$ B9 u
  44.     state.soundsspeed = train.speed();//更新速度$ x! I  `8 e+ Z' ?0 K1 @0 W
  45.     for(let i=0;i<4;i++){
    1 d2 O6 O. W4 `/ [$ v# k  O
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    9 W+ [4 O2 K6 G
  47.     }3 `- l1 ?" E: h$ y" b/ B- N( |
  48. }
    ) h$ l1 C! l5 U7 q! P4 \
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    ) V& y( c- o6 Y  P
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间% D$ k) |" \* [5 @
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放( _5 v+ @% Z; U& e/ V2 h; T
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    : K& q) @  {2 u) V) V
  53.     }4 S' k3 a/ ]7 }# p( q4 s8 n) a
  54.     return nu;//返回新的播放时间! H: d4 R, B% m+ f) G. U
  55. }
    $ D: L$ L& W3 j* I# R; q0 ]. J+ t
  56. function grnn(min, max) {//随机小数
    0 A/ [# k% c+ x( V7 [( J9 \/ H8 a
  57.     return  Math.random()*(max-min)+min;5 ?, J1 {1 n7 m
  58. }
      h3 k+ {& T- V
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的: D& F3 Y' E' ]0 Q
  60.     // 获取列车从车库开出的距离
    * I4 |' J% G5 n/ `2 u% s9 W
  61.     let railProgress = train.railProgress();( t: o& X7 n' K9 A4 Q* Z0 e0 q5 f! r
  62.     // 获取当前轨道的索引
    % w; L; V: i0 X1 [! e
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    5 X" A4 Q- d# m
  64.     // 检查当前轨道索引是否有效
    9 ?/ d0 P# X2 a& S0 r3 J2 U& l) q
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    ' w: A8 h, `  s' ]5 H
  66.         // 获取当前路径数据对象
    # B8 G; b# G2 }; l. w
  67.         let currentPathData = train.path().get(currentRailIndex);) L1 n! f4 k/ ?% k( k$ e! m
  68.         // 获取当前轨道使用的自定义轨道名称
    - L  a* s& h1 A3 |
  69.         let trackModelKey = currentPathData.rail.getModelKey();% Q0 B8 g, o* M2 q
  70.         return trackModelKey;9 k/ a, D* F+ J0 D& S, ~
  71.     }( R3 z- _9 g9 C( H3 S9 K6 _* Y6 G
  72.     return null; // 或者是一个默认值2 c" |! I' [- M, p5 O! N  e  D& r
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
2 Y- i* G6 g9 P) D4 S6 y5 L+ W
有事加我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
0 V# J* _! z0 l) v' A$ [6 Obve声音要方便一些吧,他有可视化可预览的编辑工具

: q! J. n! ?3 M/ ~5 R嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
回复

使用道具 举报

huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
, c1 }# C/ b5 B/ E2 J/ j" t2 G  x" o: a  o% C
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
回复

使用道具 举报

楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 9 d& C6 Q! N: q3 x
huliawsl 发表于 2024-5-17 21:12; Z2 y* e! D; G/ ?
相较于此,我还是认为bve格式会更简单

2 L6 u* U% J; K( G1 J& J# ~( Y🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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