开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑 ' @3 a" W3 H$ Y$ R" b4 n7 k1 f- ^
9 @6 ?$ E; t. \/ m' z+ @! V

. p; @- ?' r% L# D& k! t最近在研究JS 做了一个简单的逻辑来播放声音' t% \% W4 A6 H- c) ~
  1. var pit = 1;//初始化音高(速度)# ?' T5 c9 q! u, z+ w& O) l/ `
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]
    ; c( M1 ?" ~* p6 ~4 X  Y
  3. function create(ctx, state, train) {
    ! w3 C: D2 X8 R) v1 Q# x
  4.     state.number = new Array();
    - U, X, u6 U; h$ ?9 [4 q
  5.     state.soundsspeed = 0;//初始化速度
    ) G) E  N% E  e6 x3 [# o% B  d
  6.     state.speedsub = 0;
    ; p9 l! E2 w! Z- `, n
  7.     for(let i = 0; i < 100; i++){5 N8 j4 A2 J5 W. ?% k9 P" S  S( g
  8.         state.number[i]=0;//初始化数组
    2 k" h% s# e: e
  9.     }
    / j# O: z; q0 u6 \5 Y# X5 X# w. q, E
  10. }
    % H0 l& ^8 W" H$ I! t
  11. # C) Y7 q- i. b1 |% |" q
  12. function render(ctx, state, train) {
    2 E: Z4 `1 H" z7 m* W
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动
    + Q1 m% b% s6 q# z3 M1 k
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)0 }" G0 u0 }& @- O0 `) {7 q& X
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    * l5 v4 |. \, M
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差3 y) q6 i) {0 h
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
      o3 J" G) w/ W
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作
    9 Z4 }" h! H3 Q: a: y' ?- J& U
  19.         for (let i = 0; i < train.trainCars(); i++) {
    ( `- c6 E- e! M2 ^' f; q1 M
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启
    , g9 @; K2 K8 J! M7 A
  21.             if(state.speedsub<-1){//如果车辆减速9 w4 w4 U3 z9 v0 h% T
  22.                 ctx.setDebugInfo("shache",1);//记录刹车
    7 K6 d" \% _, a9 v% j
  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$ X8 _9 O' j0 A. b' X
  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  N  q/ t2 p/ Q  H
  25.             }else if(state.speedsub>1){//如果车辆加速
    5 n, e1 Q( v0 ]9 f; r! p& t
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    - w$ q3 j; o6 ?1 f. G# S' k% f
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声
    5 S, `- d9 x" D0 k2 K6 i2 v; [2 B
  28.             }
    + e3 j4 @! I: p( k/ q& Y2 e; `
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声
    & M1 O  P* i; y7 S/ `3 c4 [1 F; |
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声
    % A. I9 m: z% u/ Q
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    2 q2 W5 F8 |. L7 |9 D4 Z. s' F( c
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
    6 r( l! w4 [2 E" C- e9 y
  33.             }
    / r1 a2 e5 b4 f( a' E& E" w5 ~# Q
  34.             if(train.speed()*20*3.6>5){. e# {) d1 H/ T1 P
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声' L6 V' M: _1 Q
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声) C1 v* r. J4 |1 F2 A0 |5 S1 }5 ]
  37.             }
    3 n+ I3 V- Q7 `3 V0 q& Y3 d
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){8 G- Q; a, b0 L) D( H& \
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声" ^# ]" _! g8 D
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声
    9 _8 H1 W$ u) f. s, G% R
  41.             }
    " Z5 X3 ]% X, [5 Q4 @; O9 t& Y, R/ A
  42.         }; U/ W; B* h4 l$ Y
  43.     }
    8 v+ }; k% y& \
  44.     state.soundsspeed = train.speed();//更新速度; c0 B* f6 Q2 \; m
  45.     for(let i=0;i<4;i++){
      @' \8 J) j* P8 c
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    0 W8 G/ o& \) ?% k
  47.     }
    * W& g# }/ l8 u- i7 Q
  48. }
      ?- M# B- D, W
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    8 i  F# Q& R& I8 |$ D( R5 F
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
      B* T4 G& b+ U. j0 V, |
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    + M' A, b' D* v8 r2 o* w3 p; o
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    - s0 M( y; F9 ~* {* Z( l% X
  53.     }% F5 B+ ]# F6 G- v, j4 [* @# Z& y
  54.     return nu;//返回新的播放时间
    / I  F  H: f. K
  55. }; n% x1 j2 ^7 p0 f" p+ P' N1 A
  56. function grnn(min, max) {//随机小数
    / T9 `/ y0 |9 C3 b' V
  57.     return  Math.random()*(max-min)+min;; }( {0 k0 h* f3 S* }
  58. }2 X' B9 t' P/ W* u$ r* U
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    0 j# B, j3 U& r6 Y: `2 D2 i
  60.     // 获取列车从车库开出的距离7 f# \- N" l# M7 _  _) A% I$ c, j
  61.     let railProgress = train.railProgress();
    : l$ P* K6 ~% L
  62.     // 获取当前轨道的索引
    8 M4 b! p# |4 [" s
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);) t+ c& b1 S+ C4 p$ ]9 [
  64.     // 检查当前轨道索引是否有效
    3 i2 N& K% ~/ K- i0 d0 s) o" b
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {, k: K3 a4 g* r8 W
  66.         // 获取当前路径数据对象: |' u2 F' q7 t; Z
  67.         let currentPathData = train.path().get(currentRailIndex);
    ( C( r% d  y& a8 V/ z$ I
  68.         // 获取当前轨道使用的自定义轨道名称
    ' i4 _: b/ H# d! P* Y4 m
  69.         let trackModelKey = currentPathData.rail.getModelKey();7 ?6 C  ~9 u, |$ ]$ r# ]
  70.         return trackModelKey;
    3 M  s8 r: I3 \
  71.     }
    5 u; p( ~! s) D' p1 R) V
  72.     return null; // 或者是一个默认值
    0 u  e. O; J4 s8 C# ^& Y1 m( t* x
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错) W( }# P0 D" y
有事加我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
; _, s6 s+ Z$ Z4 {. sbve声音要方便一些吧,他有可视化可预览的编辑工具
+ P" c" f4 ~' |. l  Z
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 * n6 p& V/ t7 D/ B* B  Q: d2 d
, w6 Q8 T1 q" N+ K( P
相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 % Z% b$ c% P/ K$ h) n* G
huliawsl 发表于 2024-5-17 21:12
' I2 `% ]# F/ J$ A- z6 o" f( K2 @相较于此,我还是认为bve格式会更简单
$ o5 A6 h+ i- ~( P  _) a* i! B8 y; {8 w
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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