开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 ! F: O3 Q+ N0 J! ^& j) L
4 O! s( h" [8 Q4 v* r

. }. W) p9 z* L2 h8 f# b4 M. m最近在研究JS 做了一个简单的逻辑来播放声音
4 X" v3 j7 c3 s% s1 x! x  d. y
  1. var pit = 1;//初始化音高(速度)/ Q3 {. E0 B6 d! C/ ?3 z" m$ \- Z; u
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    , S- o: L) e4 \! c1 W9 N
  3. function create(ctx, state, train) {
    ! N0 ~: y$ C( n- ]. P0 }9 \. D
  4.     state.number = new Array();
    ) R: E5 g: E  ?2 ~
  5.     state.soundsspeed = 0;//初始化速度
    : w! H) O) N1 ^% b& F
  6.     state.speedsub = 0;8 q0 m" J8 U! a
  7.     for(let i = 0; i < 100; i++){
    2 F4 S* ~: I: [2 M' n3 l
  8.         state.number[i]=0;//初始化数组
    4 x/ S% q/ n) w" m* |
  9.     }- A  C+ c0 F7 \5 g, m$ z
  10. }
    $ U; J" p; k# E' K4 ]0 ]. H2 h
  11. - n6 S# w& G( q% p/ p" Z# r
  12. function render(ctx, state, train) {
    % V, U" J& G! C' h$ a9 N6 E& b
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    & ~+ |3 h2 m% v! G
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)) m$ y9 v# J! H8 w1 ]% U7 H
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    ; H3 G0 r, y7 b$ F. h
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    2 x" B8 m7 a% u/ c6 T2 c- d
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)5 [8 |) N8 W2 \+ }
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作7 s  s3 Y) T/ P* i5 I
  19.         for (let i = 0; i < train.trainCars(); i++) {5 _! ?! y- y0 Z9 ~& \: B
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启& i% L7 u; Y! Z$ l% S9 x! V
  21.             if(state.speedsub<-1){//如果车辆减速7 }$ `) K  Q$ f( R- K+ O# C
  22.                 ctx.setDebugInfo("shache",1);//记录刹车' m5 a! m" \2 ]' f* Q
  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);//更新返回时间 播放刹车声在转向架10 {0 B% T5 `4 h/ A4 E! N
  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
    7 P- @7 z9 g* ^3 _  S8 c- Q
  25.             }else if(state.speedsub>1){//如果车辆加速
    5 d$ V8 B3 N- T3 R* Q6 f
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    5 a4 `  X) ]& g2 z+ H2 ~: F" ~; n# }; l
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声; g7 ?7 |, p! m" }2 e1 M" G) V7 Y4 v
  28.             }
    ) Y4 ~& `1 k' e" j5 G
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声
    ( C( j8 {" I1 i2 R
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    % T! `$ q- k4 J) O$ a
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    2 Z( U, M4 ]) A+ w0 U  F
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右8 l& Z% h1 H. J: I4 K1 a
  33.             }
    . o$ c) P/ A( l! v
  34.             if(train.speed()*20*3.6>5){
    ( p) b# {- H& }+ m7 `) p7 b
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声! R! ~& M6 }" E. Y" Z
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声- Y# j1 o$ @  z4 u# k' b
  37.             }
    " R9 ^& y' G0 c) E6 k/ h7 F
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){% d7 l6 z% R/ C) W* Y( ]
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声- \" n* l5 f$ K" x! M# z
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声9 {9 f- h0 V3 \  N
  41.             }# J+ A) F0 ]7 J& C4 q4 |
  42.         }4 S: n$ a" o4 I% p* S, K' K8 s
  43.     }9 R( h) ^& |4 J) u
  44.     state.soundsspeed = train.speed();//更新速度7 v; p( k& Z" n+ s7 X
  45.     for(let i=0;i<4;i++){
    7 h, q' W1 X+ r+ E: j( G
  46.         ctx.setDebugInfo(i+"=",state.number[i]);3 S5 w9 O4 F9 m2 y2 L" H) k. O
  47.     }
    / \0 P2 W+ i7 y8 z+ u7 k
  48. }
    * J5 M' p; f0 q% A! t
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    & f3 H+ D# X* X1 a: i9 ~1 s6 [# _
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间( a! P$ T& I# l% W
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    6 f$ w* S( H9 o" @% Z
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    1 P  x  t6 c' r4 S3 R: o& K
  53.     }* V4 y& z5 V& y7 p9 v6 k
  54.     return nu;//返回新的播放时间5 k, n+ H, J+ }5 }8 g
  55. }( h7 J* ]. @. ~* j
  56. function grnn(min, max) {//随机小数8 ]9 Z4 s; I8 ~. ~! b* M
  57.     return  Math.random()*(max-min)+min;
    2 d# [/ t' Y9 ~! E5 S5 B
  58. }  p! L; W# s; b7 P; C7 u- _) }
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的+ i2 n( s9 g" _% n$ H
  60.     // 获取列车从车库开出的距离5 @( }& R9 \8 w* S
  61.     let railProgress = train.railProgress();3 r3 `  P. D0 e" Y: D2 e
  62.     // 获取当前轨道的索引
    " N% G/ t+ Y: X5 I! V
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);  t9 P$ f6 K; d+ r& I
  64.     // 检查当前轨道索引是否有效
    . R/ w$ V1 Z$ R! T1 V+ i4 T
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {; `/ W, t% o0 a# B5 ~
  66.         // 获取当前路径数据对象: b3 f, o$ u3 S( O9 `$ w: W
  67.         let currentPathData = train.path().get(currentRailIndex);8 o$ Y1 h; J) U& a) r  a7 `& s+ c9 b
  68.         // 获取当前轨道使用的自定义轨道名称: Z1 t. g& d7 ?' _1 U4 J( a/ k
  69.         let trackModelKey = currentPathData.rail.getModelKey();8 t+ W8 q8 |* {& \7 e" g$ B9 ^
  70.         return trackModelKey;. T7 V6 I3 P2 D5 j% c
  71.     }
    , ]5 T9 @! g$ n8 _
  72.     return null; // 或者是一个默认值
    2 [; {+ g* g0 B# w+ l* @
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错
1 c9 i7 {) B$ x$ R& K) @: 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:04% Q. L$ _) N0 X  B
bve声音要方便一些吧,他有可视化可预览的编辑工具

6 c$ V% P9 h! s' N嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
* U6 S. q# b& E4 j/ |
$ e/ {2 h4 ^9 K) I" o' U相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 & m/ k4 A2 C  U; `/ u. k; S
huliawsl 发表于 2024-5-17 21:12  d- a# }, J+ N9 @
相较于此,我还是认为bve格式会更简单
2 J* F, w( o1 T9 k5 x& z- Q
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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