开启左侧

给点播放声音的新思路

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

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

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

×
本帖最后由 Harlotte 于 2024-5-18 15:24 编辑
+ g( i& T3 Y. L. I+ v" B1 b, \+ U: i* o( Z% J( i

# Z$ r/ L1 C- h6 d最近在研究JS 做了一个简单的逻辑来播放声音8 g. r3 [( H9 e. c# V4 }0 Z. P  Y
  1. var pit = 1;//初始化音高(速度)
    0 z# U$ V% n' n0 y. W5 }9 u# d
  2. var wheelsounds = ["mtr:df5g_wheel1","mtr:df5g_wheel2","mtr:df5g_wheel3"]1 {0 u4 L2 g  @: S6 n  m
  3. function create(ctx, state, train) {$ k( j$ Y$ v* ]! \8 N1 x; E, Z
  4.     state.number = new Array();
    0 I6 p  \( ?0 }- b( K" ~- w) B
  5.     state.soundsspeed = 0;//初始化速度
    - y) i" t) P5 c' U
  6.     state.speedsub = 0;
    9 ~, i! I( u  K7 H2 G' C
  7.     for(let i = 0; i < 100; i++){/ H, \& k" u  o8 }% O/ G3 V
  8.         state.number[i]=0;//初始化数组3 Q+ q# O; z) y: w& z$ q
  9.     }8 m. \0 f/ R& y1 p) _
  10. }
    * C# ~& W( m1 k7 I( l

  11. : W2 b2 S$ N3 r# h4 ^
  12. function render(ctx, state, train) {
    0 w8 X$ S/ }& b% k! u- k
  13.     ctx.setDebugInfo("sounds=",1);//记录声音程序已启动" v1 J$ X" A; H; I: ~2 B5 J
  14.     pit = 1 + train.speed() / 40;//更新音高(速度)& P/ ~! k1 ~; D' L( F4 W4 f2 }
  15.     let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称   
    ( [1 g& ^5 M+ v" z) X! i" U
  16.     state.speedsub = (train.speed() - state.soundsspeed) * Timing.delta() * 1000000;//计算速度差' O* y( j& I/ m0 P/ j
  17.     ctx.setDebugInfo("speedsub=",state.speedsub)
    4 F6 I, L! ^8 _
  18.     if(train.isOnRoute()&&gamerunning==1){//如果工作$ S; U; h) i9 {9 A! r! b
  19.         for (let i = 0; i < train.trainCars(); i++) {
    5 f) w& Z; r( x7 `+ \
  20.             ctx.setDebugInfo("soundsrun",1);//记录声音开启1 b4 l/ o7 V0 E, s
  21.             if(state.speedsub<-1){//如果车辆减速
    $ g) [) l, ~* ^# [
  22.                 ctx.setDebugInfo("shache",1);//记录刹车+ ?* m7 J2 p. \) v+ z$ d# u. b
  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+ R, E) I0 ?( ^4 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);//更新返回时间 播放刹车声在转向架20 b8 z0 m7 p6 g; t
  25.             }else if(state.speedsub>1){//如果车辆加速
    % t; C) N; U0 c- h% d! O8 J; `
  26.                 ctx.setDebugInfo("addspeed",1);//记录加速
    , W" n3 L# D4 z9 j# }$ S
  27.                 state.number[2]=sound(ctx,"mtr:df5g_engine",i,soundspos.engine,pit,state.number[2],20,grnn(0.8,1));//播放加速声# H. c0 ^* i& K3 t- b; ?2 w
  28.             }6 q& Z4 G- C: d5 N+ d8 a$ A+ a
  29.             state.number[1]=sound(ctx,"mtr:df5g_engine2",i,soundspos.engine,pit,state.number[1],16,1);//播放怠速声9 F5 ~/ ?# m1 d, P
  30.             if(gmk.indexOf("horn")!=-1){//如果在轨道名称里找到了horn,则播放鸣笛声  O, A6 L( t; H7 [
  31.                 ctx.setDebugInfo("horn",1);//记录鸣笛声开启
    : T& W9 h, [- x
  32.                 state.number[3]=sound(ctx,"mtr:df5g_horn",i,soundspos.horn,1,state.number[3],32,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右) G/ m1 \. m6 b* b6 z6 `! L
  33.             }) k4 B' U  `/ W; V+ Q& f6 B8 p, J
  34.             if(train.speed()*20*3.6>5){
    ) Z* g2 g; x3 A# L: ?
  35.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking2,pit,state.number[4],16,9);//播放普通轮轨声. y6 F- R1 z) z5 G
  36.                 state.number[4]=sound(ctx,"mtr:df5g_wheelrun",i,soundspos.braking1,pit,state.number[4],16,9);//播放普通轮轨声5 v& K2 h3 c9 I& N) k/ f5 G" B) ~
  37.             }! U+ E' \& _6 q8 D! J3 K+ W, L- n
  38.             if(train.speed()>0&&grnn(0,20+train.speed()/30)>19){
    5 ~! z3 h/ U9 ?3 m. X3 w& w, ?
  39.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking2,0.8,state.number[5],32,0.05);//播放撞轨声
    . [+ z. ]9 a0 y  J2 v! @( a# P
  40.                 state.number[5]=sound(ctx,wheelsounds[Math.floor(grnn(0,3))],i,soundspos.braking1,0.8,state.number[5],32,0.05);//播放撞轨声; {- U3 W+ g/ F  h/ `7 o* \9 u: t' k
  41.             }! O' N# ]- C4 P) [
  42.         }
    / `) ~# F9 q# \2 F2 \: P+ _- J) y
  43.     }
    - d, V! _4 K2 }- O$ \. _! H+ W
  44.     state.soundsspeed = train.speed();//更新速度
    ' R6 u6 J- H0 s6 b4 v
  45.     for(let i=0;i<4;i++){
      L9 e2 _; \# z0 E
  46.         ctx.setDebugInfo(i+"=",state.number[i]);
    , @. V) U$ Z0 ~; c  I- G( y6 l8 }
  47.     }
    8 x  w% z9 A0 v" X' S* }: l
  48. }$ _" z. \3 i1 z0 F
  49. function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    8 |# t7 O1 O' L# {9 T
  50.     if(Timing.elapsed()>nu){//如果时间超过了播放时间
    5 B' A. H& c/ T( ]; Y) d) M
  51.         ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
    7 K: h; N6 q9 U
  52.         nu = Timing.elapsed()+long;   //更新播放时间
    6 e9 o' G. y% D$ W
  53.     }6 q; i: C* b! C2 G, N4 I
  54.     return nu;//返回新的播放时间/ d; f8 x  T1 i3 C, b
  55. }0 K4 Q4 W6 P3 I& ?
  56. function grnn(min, max) {//随机小数' x- d5 {* K: ~7 g
  57.     return  Math.random()*(max-min)+min;
    1 U) U/ o; W- p6 U: w( g) s
  58. }- d, H" U" S/ b. Z' F& Z, w# C
  59. function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    ' u/ M, L9 l; r" S& T3 |
  60.     // 获取列车从车库开出的距离9 _+ e' P- j+ i0 a" p
  61.     let railProgress = train.railProgress();
    : q; x6 [1 c) I% p( A
  62.     // 获取当前轨道的索引
    : L5 t) n# I! q0 `  Q( |0 H
  63.     let currentRailIndex = train.getRailIndex(railProgress, true);
    % Z: J/ a5 F4 t! V9 p
  64.     // 检查当前轨道索引是否有效
    7 {: t; n' a$ l
  65.     if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {' q: q% i1 N' {$ v
  66.         // 获取当前路径数据对象
    8 K4 S2 y3 G7 v* i, Y) R# G
  67.         let currentPathData = train.path().get(currentRailIndex);2 t( t- q4 c0 K; ^9 e& G) ]2 Z
  68.         // 获取当前轨道使用的自定义轨道名称
    $ r; i9 B+ m  y; J9 j% L+ \
  69.         let trackModelKey = currentPathData.rail.getModelKey();
    * A& b- Z  X" R  V
  70.         return trackModelKey;
    - z! X9 s+ n$ |0 o4 X" L3 _
  71.     }
    $ N; _; z4 @2 \7 T# ]
  72.     return null; // 或者是一个默认值! R% z  c$ s2 i, w* j  A
  73. }
复制代码
相比bve 用这种方式可以搞更多的逻辑,随机叠加音频,实测效果非常不错5 i. \9 R( n3 l' n
有事加我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:046 k5 O+ ^; z9 z7 f6 p
bve声音要方便一些吧,他有可视化可预览的编辑工具
- a1 r. x% O4 @+ h
嘶 主要是这个把 我懒得学了
有事加我QQ: 3435494979
回复

使用道具 举报

huliawsl 2024-5-17 21:12:04
本帖最后由 huliawsl 于 2024-5-17 22:09 编辑 , o: ?2 `0 \+ E0 U- O% l8 V2 ?

3 i0 p4 ?* P% c* T* T相较于此,我还是认为bve格式会更简单
屑搞3d的 https://space.bilibili.com/403409690
mtrbbs的私信咱很少看 如果需要联系咱可以尝试其他途径
回复

使用道具 举报

楼主 Harlotte 作者认证 2024-5-18 09:21:18
本帖最后由 Harlotte 于 2024-5-18 15:18 编辑 5 M) Y' l) b( x+ {$ L9 {
huliawsl 发表于 2024-5-17 21:120 z, b" x/ e% |+ v
相较于此,我还是认为bve格式会更简单
2 N& r" ~( [2 N8 E6 a
🤔不过吧 这么做花样可以更多倒是
有事加我QQ: 3435494979
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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