开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 ) ^5 g9 }; z( ^7 K7 y! L. l

1 L. z5 d: V% R: e5 G
- m( {0 v6 ?* ^% W7 W$ l最近在研究JS 做了一个简单的逻辑来播放声音' Q4 V1 u$ D6 A. t$ J
  1. var pit = 1;//初始化音高(速度)* O9 b$ B5 _0 t6 c; n# o0 T
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    & V9 Y/ T. n7 }5 F$ _- r- F
  3. function create(ctx, state, train) {. s/ H; C+ J) [" ]3 Z+ f6 [7 ~
  4.     state.number = new Array();0 V% v4 l6 i% U6 m
  5.     state.soundsspeed = 0;//初始化速度
    + X/ t* {- g; l7 s- @/ \
  6.     state.speedsub = 0;
    ( p  m1 P- J2 N4 D; p" @
  7.     for(let i = 0; i < 100; i++){6 ?  L+ C/ P2 l+ A6 d
  8.         state.number[i]=0;//初始化数组
    3 s" D0 u+ ^; J% R3 Q: t
  9.     }: p2 r* T% N# H& N) u# d
  10. }
    * F3 A5 K) t$ Q; R8 q8 x* ]# k
  11. " t* C2 l# q+ G  _) ]
  12. function render(ctx, state, train) {
    ( o4 y( {0 R) d/ U+ r2 b+ ]. i
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    % B; c' X1 i# y/ A$ w" W- q
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)8 p: k( J+ X. L* \2 J5 B/ j  N4 Q$ B9 K
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    - d7 L% F3 Y  R" ~
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差
    # I/ v1 q) m; `! V: W3 n* N) f# F
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)1 q6 r5 [8 s1 Q5 Z
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    ) c4 x, W/ n% c' l* Y: X/ ~
  19.         for (let i = 0; i < train.trainCars(); i++) {
    ! l4 U) ~2 R/ n
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    9 o$ A% N# K! c9 Y$ a! n( ^
  21.             if(state.speedsub<-1){//如果车辆减速
    2 U" j) ^" _* y
  22.                 ctx.setDebugInfo("shache",1);//记录刹车% k; w7 i4 O( G( X* {6 F
  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. q% I( i, c9 f- Q" c- ^1 f, S
  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 J* G  V! ]: {$ k4 I) l, G
  25.             }else if(state.speedsub>1){//如果车辆加速3 ?6 x6 [8 i% d- S; I3 ^
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    # o2 u* T* i1 v2 O, s  S: R
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    # M8 i3 H# P) q
  28.             }2 ~+ T+ C) D/ ]/ u3 D5 z
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声0 r2 q. F( ^& m: U# U6 @
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    ) n* M6 ?9 Q$ W; J8 W1 g  O
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启" N: l3 e/ R; F( T- I
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    , {2 Z+ ~7 Z. O* V. w7 M
  33.             }
    2 l, @5 Q  F" H" C/ F. O
  34.             if(train.speed()*20*3.6>5){& ?  u& k& m" j  W  }1 p7 `
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声  B& _5 `+ P- U1 M, J. R' B
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声
    $ Y# Y" T# r2 P! s9 Z
  37.             }2 O2 f+ O. L+ f# c8 V' i
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    ; S4 b, W; x9 {& g- P
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    1 O( R- h: e7 r1 z( X, l4 d, J
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    , `4 Q- D! E& ?( o
  41.             }
    . a7 N9 q. Y& X: C: `
  42.         }
    & b0 g/ E) V$ R( U# ^$ H
  43.     }: n3 f7 I3 t3 m" l4 n1 A2 L
  44.     state.soundsspeed = train.speed();//更新速度  }  W- x4 P" y( c& b% a
  45.     for(let i=0;i<4;i++){9 A, U) Y/ @/ d. y
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    & }( k: R) x9 \+ @. _5 A, @
  47.     }# V  S2 j$ Y8 I* D, I  l4 Z+ O
  48. }( b" G0 M2 f, S5 d0 U
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间* d# V% q/ ?" p. x, K  `; @
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    * Q2 J/ _0 ?7 _/ L  J& \' P
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放# b: P# ~) q8 {7 w$ ]9 R
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    " b/ ]% F5 u$ T/ B
  53.     }. y) d. c% F, |4 W( T& g, y
  54.     return nu;//返回新的播放时间
    $ M5 N4 l; \+ Y* U
  55. }6 `- `, y- p# W2 T
  56. function grnn(min, max) {//随机小数9 Z; Z) q* }5 K1 }6 @1 c
  57.     return  Math.random()*(max-min)+min;
    2 c5 R. l* U& x4 X8 u* Y7 V6 R2 {
  58. }
    . E* P. S, {+ S! c( l2 u& a5 }) U9 \  u
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    2 [# W' D3 y7 m; P4 L  ?
  60.     // 获取列车从车库开出的距离
    . h  g, l3 Y& N$ H2 H. ~6 P
  61.     let railProgress = train.railProgress();' _- ?+ v9 e1 m8 O# N' k, M, y, R
  62.     // 获取当前轨道的索引
    5 l& ?- y0 x( j, X3 P; c; r$ u) b% [
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    . r$ U- T/ K6 E4 q  y( g$ @4 I
  64.     // 检查当前轨道索引是否有效
    ' M* I% T# D, L* E
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {" o% `1 c( e: ?$ ]" g
  66.         // 获取当前路径数据对象6 v2 g: q3 g7 m# x0 [
  67.         let currentPathData = train.path().get(currentRailIndex);, C8 c9 E) I, e) y' m# L
  68.         // 获取当前轨道使用的自定义轨道名称
    4 s' K( @% c3 q( O0 O' b* n6 E1 O
  69.         let trackModelKey = currentPathData.rail.getModelKey();/ h% \( e& Y+ O+ O5 [
  70.         return trackModelKey;
    5 p' D2 l& X. G9 g2 `
  71.     }
    / ^0 {. J1 G: W  H( V0 F" X4 g
  72.     return null; // 或者是一个默认值
    4 E5 l. {% F, U, v! ]# i
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错- G5 {0 A4 O! Z- S8 ^5 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
$ j; p, k1 R# b  l( A0 abve声音要方便一些吧,他有可视化可预览的编辑工具
/ c& B7 A- R3 W* W/ ?
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑
2 r+ B! h, v: T- M' j/ ]. W9 \4 a/ ~0 |, Z
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑
, q( {" z1 i3 z" L! |2 t
huliawsl 发表于 2024-5-17 21:12% L2 e6 d3 K6 G0 U
相较于此,我还是认为bve格式会更简单

: I1 Y4 t- t& K0 T0 O🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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