开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 # [% g3 j, y4 ~9 _4 g

9 ?1 z. V5 f2 z. ]; q, ]2 c" Q5 L! e# a/ n+ G7 R
最近在研究JS 做了一个简单的逻辑来播放声音
% P4 [) X: W. H) |. ?, n6 J& _# S9 B
  1. var pit = 1;//初始化音高(速度)) L- K$ N6 F7 c: M) W# Z% E8 B- c
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    + K8 W; v. w# p1 s) n
  3. function create(ctx, state, train) {
    ! N2 t/ b9 \1 i5 T+ y, G
  4.     state.number = new Array();# m6 \8 x. _5 ^. j' B4 D
  5.     state.soundsspeed = 0;//初始化速度; X' m2 H( C7 v, [% f4 C
  6.     state.speedsub = 0;
      r9 ?$ ~9 V" _! H7 l- ]
  7.     for(let i = 0; i < 100; i++){
    $ }& d, p! P4 V4 r
  8.         state.number[i]=0;//初始化数组
    5 k" ~1 l( b1 [+ I  ]% p/ Y. G
  9.     }
    7 k" }+ Y2 `! E. i- D# X8 n) I. a
  10. }- r, q0 E" ?% v" c, R0 |, Q
  11. & V3 h  x  [, n  I1 D
  12. function render(ctx, state, train) {* x6 h: J; Y; h: ?/ k% d
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动, r/ x, Q  _8 D4 f  n
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)
    3 T& h8 W1 g/ d; h) O( Z- b
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称    : t. @4 V7 ?2 w! B9 E3 }) `
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差) x4 V& |9 M  P2 {( Q
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)1 K) s1 T& D  K" `. r( _
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作8 |  t/ C8 }8 X8 j6 {+ z& V
  19.         for (let i = 0; i < train.trainCars(); i++) {- l% N  E, ~: b' [
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    5 B1 ?& D, v3 n* b; v1 a  a7 t, e3 I. |
  21.             if(state.speedsub<-1){//如果车辆减速
    : m6 m. X% R: G6 A# n* I. N0 v
  22.                 ctx.setDebugInfo("shache",1);//记录刹车3 A2 G% n/ Y- a% d" U9 J5 h0 k( O3 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! i, ^/ t4 R6 c1 w
  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
    2 x4 W+ W+ ^- N* g6 g. K
  25.             }else if(state.speedsub>1){//如果车辆加速
    ) B- N+ p9 v+ J/ ~+ m
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    / p3 R& W% ^$ v$ |7 z
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    7 J9 C, G6 w- }, o) V# |0 N9 _
  28.             }
    ; N- V+ N( B& f8 o
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声
    7 A: z3 b# d3 x8 D4 U% [- q7 N
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    , E" C# o2 \: H9 e1 I
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    7 w0 H2 c5 Y8 G2 d0 x; y2 d
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    ! X) X/ e" }5 j% {/ }  r' I8 S; w. [
  33.             }+ q8 {/ f( g3 j
  34.             if(train.speed()*20*3.6>5){
    5 U1 |# \3 [6 |+ I8 k9 `6 C
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声
    * ]8 _5 h6 P0 a6 U) ?0 b
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声' y3 V& P/ p  Y% r
  37.             }
    6 e+ s1 C& G5 {2 H, e; e
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    . g  ?. W& d9 h% U* w
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    ; I0 j6 \8 F% U2 ?) N! Z  l
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声+ Q5 Y8 F: a: o1 Z" c. g3 Z
  41.             }7 T0 o( e9 [( p4 {$ J
  42.         }3 O# s8 o$ r3 ~- w+ U* U
  43.     }9 z0 g( q6 Z9 u0 d( B. u
  44.     state.soundsspeed = train.speed();//更新速度
    4 ]  j4 k6 Z! r/ v  N8 ^, Z, {  i
  45.     for(let i=0;i<4;i++){
    5 i6 c( i0 ?% }% ~( u8 Q* \% o" _
  46.         ctx.setDebugInfo(i+"=",state.number[i]);# {) i) o. f3 p3 ~
  47.     }
    0 g8 S4 I, U! E3 M' c
  48. }0 Q, h- j' a  Y
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    # i2 g. N) g+ M8 c* F8 U
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    $ ]# o1 p2 [9 ?  a1 Q
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放# [9 p, G- K5 X7 N  O
  52.         nu = Timing.elapsed()+long;   //更新播放时间9 e4 `& r: W; q0 M
  53.     }
    1 C* }! E, e: f( m( Q
  54.     return nu;//返回新的播放时间9 w/ i" a  P* a  M7 A
  55. }1 J. o, a6 E# Z  U
  56. function grnn(min, max) {//随机小数
    ) N5 N3 l# ^# u$ p
  57.     return  Math.random()*(max-min)+min;3 J  ?4 f$ X) O7 M' D5 v
  58. }
    , t1 v8 A/ ]+ g6 J0 K' u
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    ( _8 C$ z; A  _5 C
  60.     // 获取列车从车库开出的距离
    9 o) i+ I$ n! v" @1 Z' e
  61.     let railProgress = train.railProgress();
    ' t5 S3 `' `" u& j7 M0 \- t0 x! g
  62.     // 获取当前轨道的索引, w7 G* i* y3 I$ D
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);. w* ^2 R" x: s0 e- d
  64.     // 检查当前轨道索引是否有效
    . Z; L! i& z. J! w# `* R
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {( G! X2 ]) W1 K  b
  66.         // 获取当前路径数据对象) C1 G: z! Z$ {4 ?6 ^- K/ K
  67.         let currentPathData = train.path().get(currentRailIndex);8 Z+ \( r2 P. P% A3 m& E
  68.         // 获取当前轨道使用的自定义轨道名称
    * E- ?2 Z0 {; _4 j
  69.         let trackModelKey = currentPathData.rail.getModelKey();% E- ^& @0 u; P( p. h) r6 h) S/ n
  70.         return trackModelKey;3 _$ [2 S* d9 H8 i7 i$ D
  71.     }
    ) s9 o2 C% k+ R1 T( K5 p5 h! r. m
  72.     return null; // 或者是一个默认值1 F6 u+ S8 M8 ?/ H4 p7 z1 ?
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
# @" c+ p1 m4 Z2 u1 R
有事加我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  a9 U3 Y/ }8 Q/ p
bve声音要方便一些吧,他有可视化可预览的编辑工具
! m, a3 y9 S4 D3 M! l. f' q  H6 X
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
" B6 s$ y9 Q6 q+ H) U
7 ~0 x! P$ @% m相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 7 b/ X; m) K6 E# Q
huliawsl 发表于 2024-5-17 21:12, Q9 [$ n; T8 @
相较于此,我还是认为bve格式会更简单

7 X  }/ k) X5 R$ H/ ^% Z8 h( Z🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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