开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑
1 d2 c: p: T! Y3 a6 _% v+ d- i7 e& I" `& k) ]+ ~+ @
6 @0 C/ {% n) V" q% o, F
最近在研究JS 做了一个简单的逻辑来播放声音
/ W4 r2 w' v& r+ [
  1. var pit = 1;//初始化音高(速度)
    / _0 u* v" v: P+ q5 P
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    : I( S0 H' W' h( H
  3. function create(ctx, state, train) {
    % f5 n! p4 \. {+ d! E/ {
  4.     state.number = new Array();
    4 ?4 f! |3 n9 q$ _; z( w; \* w! l
  5.     state.soundsspeed = 0;//初始化速度
    ; C- f' W' n$ S% Z0 M  F
  6.     state.speedsub = 0;, m: ^8 \" A+ \  _0 M
  7.     for(let i = 0; i < 100; i++){7 E3 s; e' R3 @, V9 b7 n
  8.         state.number[i]=0;//初始化数组
    6 n6 y: ^6 j7 Y+ g- _
  9.     }% l. M5 h  L. |6 m5 s; `$ R1 B3 E3 Y
  10. }3 M# B4 V) V% M" Q
  11. ) E% t& V) o2 C7 Z0 D- F
  12. function render(ctx, state, train) {8 A* a" ?. I- }
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动" j3 K2 Y" I! i' K2 h
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)
    9 {* c* N  W, W) e
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称    / J9 x  Q& K! l+ E; [1 n
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    0 T8 j7 G8 B7 V- p" I# s) _! l
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    , F8 ~5 T7 U2 C
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作+ V* O. U( O5 K6 t
  19.         for (let i = 0; i < train.trainCars(); i++) {
    1 I3 `  e& V9 e1 Z$ x
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    % G! n$ L( g0 @6 ^) s* ^& w
  21.             if(state.speedsub<-1){//如果车辆减速
    : U1 E! ^- p3 z/ w0 K9 q2 o7 {: K
  22.                 ctx.setDebugInfo("shache",1);//记录刹车* y( t/ a( l3 O6 i6 b/ 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) {! n6 f5 A9 n9 G& h$ Z& G7 e
  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" U/ x2 |$ Y3 u0 h* ?
  25.             }else if(state.speedsub>1){//如果车辆加速
    6 g! p9 `' `$ g0 M& ^% o
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    # F' l* p; ]( k3 \) O/ A" \- K
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    ' `. v# A& Z9 u- L
  28.             }
    . ]  {4 [  j5 d1 |9 d2 _! B
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声: n. o! L$ K' g  G* d) Z0 X
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
      u( w* P% _! B6 b& S" \
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    5 O" d2 m3 U7 m! T) ~( a
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    1 v1 N1 p- w/ m7 h+ a; G
  33.             }- p# ^$ M4 j1 A) s
  34.             if(train.speed()*20*3.6>5){
    ( g% D1 q) ?3 m: `) r% b
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声; k! q6 p8 ]# y
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声$ W* ]4 I, q1 `6 u
  37.             }. j1 a! P$ H( F" s/ @
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    2 p; R3 Q4 h8 s5 }5 E
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    . s" D; u, ~$ @: `
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    7 C' ?1 N5 l1 J  x. F" J6 B
  41.             }
    2 [! G/ t2 \. U' O* o. h, l% G7 A
  42.         }
    . n+ r( H6 N* H- g
  43.     }
    $ x2 {4 a% _$ F( a/ ^
  44.     state.soundsspeed = train.speed();//更新速度
    & X- ^1 I8 U" S; J! F6 U( m5 o
  45.     for(let i=0;i<4;i++){
    . r  d& O* O. o0 P
  46.         ctx.setDebugInfo(i+"=",state.number[i]);+ B4 R2 H! O! e8 q' C1 ]$ S
  47.     }% O4 j9 F: Q9 }' W" H$ @; |9 h* q' c
  48. }
    0 U# m2 X+ V; c' ]
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间  ~9 \/ [' i: {. B
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间! S) \6 l3 O5 L3 e  p- j
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放* ?8 w6 ~" m) M4 @
  52.         nu = Timing.elapsed()+long;   //更新播放时间8 K+ W1 M2 e, X# I4 v) o
  53.     }0 t, H( a, y# r9 ]2 ?
  54.     return nu;//返回新的播放时间
    4 u% L0 Q+ ]. p( J; S6 ^$ |
  55. }5 f# r' d1 _! i: E
  56. function grnn(min, max) {//随机小数; G( @. |4 ~. F+ `% L' N; f0 G, ]
  57.     return  Math.random()*(max-min)+min;, l" h- j4 n3 C- l( s0 h
  58. }0 m' c* G3 x6 S  F! g7 f$ F' _0 P
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的. x- L0 Y$ K4 i( }6 G8 H
  60.     // 获取列车从车库开出的距离# g# M$ M' R2 _- c/ d2 \
  61.     let railProgress = train.railProgress();  ^8 G0 h$ d: ^( C% T$ g$ @
  62.     // 获取当前轨道的索引
    , u- r) v3 a9 v& P' K9 W
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);' u  ?4 B2 o7 T) W. U/ W% J" s
  64.     // 检查当前轨道索引是否有效
    5 J. Y1 Q! |0 a0 _# w9 {
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
    ' [0 s2 k' b, J- s- q8 F3 A
  66.         // 获取当前路径数据对象- T: o' j+ U7 M8 {+ A3 I7 Q$ W8 V
  67.         let currentPathData = train.path().get(currentRailIndex);
    / w, t. m( q, r% B) p: }5 P
  68.         // 获取当前轨道使用的自定义轨道名称. Q( U: ?$ w9 J0 r; o
  69.         let trackModelKey = currentPathData.rail.getModelKey();
    - W4 L! _+ s* }# a
  70.         return trackModelKey;$ r) R: Z: R! |7 I, ?* ~
  71.     }) Y& U2 _% F  E' _3 |$ O, z& A$ L, s  g
  72.     return null; // 或者是一个默认值% P' r2 F# x( |; C2 u
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错# G8 V; d( x! X% O! J9 q
有事加我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
+ Q4 [. Z( m0 p9 T% Ybve声音要方便一些吧,他有可视化可预览的编辑工具
& n4 ~0 J* U! K0 H
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 3 o+ L2 B; ?, i
! o( _, _/ x7 [- }
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 % n9 Q( R6 I: M& s* Z
huliawsl 发表于 2024-5-17 21:12
  M# }- m% \! m9 o6 ^相较于此,我还是认为bve格式会更简单

7 y6 B4 C8 _+ p/ I) R/ P( O, w" R+ U🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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