Harlotte 发表于 2024-5-6 21:18:52

关于随机摇晃、车轮转动、判断轨道类型、使用js完成音效播放的JS代码分享

随便写了点丰富了一些,我发这些代码分享的帖子会是顺承关系,请尽量阅读最新的帖子来参考。

以下是我的一些代码,有些地方没有用文档里给的东西,但实现效果类似,后期我可能会考虑替换,也欢迎各位尝试。
以下代码欢迎各位借鉴,转移并改编什么的,下面的我自己写的函数和逻辑可能对你有用。
音频播放部分目前因为一些未知的原因还不可用,正在积极探讨,此部分逻辑可用但没有实际效果。
var rms = ModelManager.loadPartedRawModel(Resources.manager(), Resources.idRelative("df5g.obj"), null);//抄的
var models = uploadPartedModels(rms);//抄的
var r=0;//初始化摇晃幅度
var pid=1.12; //轮子直径
var d=-0.446434+0.01; //轮子距原点纵轴距离
var s1=3.1358; //轮子距原点横距离1
var s2=1.80722; //轮子距原点横距离2
var pit = 1;//初始化音高(速度)
var yao=0.1;//摇晃幅度限制
var yao1=0.01;//车速对摇晃幅度的影响幅度

function create(ctx, state, train) {
    state.r = 0.0;
    state.speed = 0;
    state.number=new Array();
}

function render(ctx, state, train) {
    if(r==0&&grnn(0,800)-train.speed()/10<5&&train.speed()>0){//计算随机摇晃
      r=grn(0,yao+train.speed()*yao1);
    }else if(r>0.1){
      r=r-Math.abs(grnn(0,0.15));
    }else if(r<-0.1){
      r=r+Math.abs(grnn(0,0.15));
    }else{
      r=0;
    };
    if(train.speed()-state.speed>=0){//计算轮子转动
      if(train.isReversed()){
          state.r = state.r - train.speed() / ( pid * Math.PI ) * 360 * Timing.delta() * 20;
      }else{
          state.r = state.r + train.speed() / ( pid * Math.PI ) * 360 * Timing.delta() * 20;
      }
      }else if(train.speed()-state.speed==0){
      state.r = state.r;
      sound(ctx,"mtr:df5g/shache",i,0,0,0,pit,state.number,16,0.05);
    };
    let mat = new Matrices();
    let mat2 = new Matrices();
    mat.rotateZ(dtrd(r));
    mat2.rotateZ(dtrd(r)/5);
    for (let i = 0; i < train.trainCars(); i++) {
      ctx.drawCarModel(models["bogie_frame"], i, mat2);
      ctx.drawCarModel(models["bogie_frame_1"], i, mat2);
      ctx.drawCarModel(models["coupler"], i, mat);
      ctx.drawCarModel(models["decorations"], i, mat);
      ctx.drawCarModel(models["doors"], i, mat);
      ctx.drawCarModel(models["frame"], i, mat);
      ctx.drawCarModel(models["shell"], i, mat);
      if(train.isReversed()){
            ctx.drawCarModel(models["light_2"], i, mat);
            ctx.drawCarModel(models["light_11"], i, mat);
      }else{
            ctx.drawCarModel(models["light_1"], i, mat);
            ctx.drawCarModel(models["light_21"], i, mat);
      };
    };
    for (let i = 0; i < train.trainCars(); i++) {//加载轮子
      let mat33 = new Matrices();
      mat33.translate(0,d,0);
      mat33.translate(0,0,s1);
      mat33.pushPose();
      mat33.rotateX(dtrd(state.r));
      ctx.drawCarModel(models["wheel"], i, mat33);
      mat33.popPose();
      mat33.translate(0,0,s2);
      mat33.pushPose();
      mat33.rotateX(dtrd(state.r));
      ctx.drawCarModel(models["wheel"], i, mat33);
      mat33.popPose();
      mat33.translate(0,0,s2);
      mat33.pushPose();
      mat33.rotateX(dtrd(state.r));
      ctx.drawCarModel(models["wheel"], i, mat33);
      mat33 = new Matrices();
      mat33.translate(0,d,0);
      mat33.translate(0,0,-s1);
      mat33.pushPose();
      mat33.rotateX(dtrd(state.r));
      ctx.drawCarModel(models["wheel"], i, mat33);
      mat33.popPose();
      mat33.translate(0,0,-s2);
      mat33.pushPose();
      mat33.rotateX(dtrd(state.r));
      ctx.drawCarModel(models["wheel"], i, mat33);
      mat33.popPose();
      mat33.translate(0,0,-s2);
      mat33.pushPose();
      mat33.rotateX(dtrd(state.r));
      ctx.drawCarModel(models["wheel"], i, mat33);
    };
    ctx.setDebugInfo("r=",state.r);
    ctx.setDebugInfo("dtrd(r)=",dtrd(state.r));
    pit = 1.0 + train.speed() / 4;//计算音高(速度)
    let gmk = getCurrentTrackModelKey(ctx,state,train);//获取当前轨道的自定义轨道名称
    ctx.setDebugInfo("rail=",gmk);
    if(train.isOnRoute()){//如果工作
      for (let i = 0; i < train.trainCars(); i++) {
            sound(ctx,"mtr:df5g/engine2",i,0,0,0,pit,state.number,16,1);//播放常见的声音,最后一个是轮播时常,单位是秒,推荐是音频的一半左右
            sound(ctx,"mtr:df5g/engine",i,0,0,0,pit,state.number,16,1);//同上
            if(gmk.indexOf("horn")){
                sound(ctx,"mtr:df5g/horn",i,0,0,0,pit,state.number,16,5);//播放鸣笛声,单位是秒,推荐是5秒左右,可以根据需要调整 我这里是因为音频不合适循环播放,实际音频在1s左右
            }
      }
    }
    state.speed=train.speed();//更新速度
}



function uploadPartedModels(rawModels) {//直接搬过来的,上传模型
    let result = {};
    for (it = rawModels.entrySet().iterator(); it.hasNext(); ) {
      entry = it.next();
      entry.getValue().applyUVMirror(false, true);
      result = ModelManager.uploadVertArrays(entry.getValue());
    }
    return result;
}


function grn(min, max) {//随机小数正负
    if(Math.random()>=0.5){
      returnMath.random()*(max-min)+min;
    }else{
      return0-Math.random()*(max-min)+min;
    }
}


function grnn(min, max) {//随机小数
      returnMath.random()*(max-min)+min;
}


function getCurrentTrackModelKey(ctx, state, train) {//获取当前轨道的自定义轨道名称,让ai写的
    // 获取列车从车库开出的距离
    let railProgress = train.railProgress();
    // 获取当前轨道的索引
    let currentRailIndex = train.getRailIndex(railProgress, true);
    // 检查当前轨道索引是否有效
    if (currentRailIndex >= 0 && currentRailIndex < train.path().size()) {
      // 获取当前路径数据对象
      let currentPathData = train.path().get(currentRailIndex);
      // 获取当前轨道使用的自定义轨道名称
      let trackModelKey = currentPathData.rail.getModelKey();
      return trackModelKey;
    }
    return null; // 或者是一个默认值
}


function dtrd(degrees) {//角度转弧度
    return degrees * Math.PI / 180;
}


function sound(ctx,name2,i,xx,yy,zz,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    if(Timing.elapsed()>nu){
      ctx.playCarSound(name2 , i , xx , yy , zz , ll , pit);
      nu = Timing.elapsed()+long;
    }else{
      nu = Timing.elapsed();
    }
}


hhwilk 发表于 2024-5-7 16:09:45

b站会出教程吗?

Harlotte 发表于 2024-5-7 19:04:29

hhwilk 发表于 2024-5-7 16:09
b站会出教程吗?

等我捣鼓完了会出

hhwilk 发表于 2024-5-7 20:50:20

Harlotte 发表于 2024-5-7 19:04
等我捣鼓完了会出

OK,非常期待:D

ShentongMetro 发表于 2024-5-9 16:53:28

巨!话说能不能做出外轨超高之类的
(我们这边一直有问题,dh直接不显示了

Harlotte 发表于 2024-5-9 18:31:37

ShentongMetro 发表于 2024-5-9 16:53
巨!话说能不能做出外轨超高之类的
(我们这边一直有问题,dh直接不显示了 ...

按理来说是可以的((
页: [1]
查看完整版本: 关于随机摇晃、车轮转动、判断轨道类型、使用js完成音效播放的JS代码分享