Harlotte 发表于 2024-5-18 15:28:16

雨刮器的代码分享

这是一个好久前就完成的项目 但是一直没发 今天发出来跟大家分享一下,其中我还为它添加了声音。
请注意 有些全局变量我没有在这里声明,声明部分在main函数中,如单独使用须声明。


var wipersmodels = uploadPartedModels(ModelManager.loadPartedRawModel(Resources.manager(), Resources.idRelative("df5g_wipers.obj"), null));//抄的
var wipersounds = ["mtr:df5g_wiper1" , "mtr:df5g_wiper2"];
function create(ctx, state, train) {
    state.wipersrot = 45;//旋转度数
    state.wipersrotlast = 45;//上一次旋转度数
    state.wipersrottarget = 0;//目标度数
    state.wiperstime = 0;//计时器
    state.wipersstarttimelast = 0;//上一次计时器
    state.wiperstarttime = 0;//开始时间
    state.wiperrun = 0;//运行状态
    state.number = new Array();
    for(let i = 0; i < 100; i++){
      state.number=0;//初始化数组
    }
}

function render(ctx, state, train) {
    ctx.setDebugInfo("wipers=",1);
    ctx.setDebugInfo("wipersrot=",state.wipersrot);
    ctx.setDebugInfo("wiperrun=",state.wiperrun);
    ctx.setDebugInfo("wiperstarttime=",state.wiperstarttime);
    ctx.setDebugInfo("wipertarget=",state.wipersrottarget)
    ctx.setDebugInfo("sound=",wipersounds)
    let mata = new Matrices();
    let matrot4f = new Matrix4f();
    for(j = 0; j < 4; j++){
      mata = new Matrices();
      MatricesTranslateVector3f(mata,wiper.pos);
      mata.rotateZ(dtrd(-state.wipersrot)*wiper.rot);
      for(let i = 0; i < train.trainCars(); i++){
            ctx.drawCarModel(wipersmodels],i,mata);
      }
      matrot4f = new Matrix4f();
      matrot4f.rotateZ(dtrd(-state.wipersrot+22.5)*wiper.rot);
      matrot4f.translate(0,wiper.dir*wiperlong,0);
      mata = new Matrices();
      MatricesTranslateVector3f(mata,vectadd(wiper.pos,matrot4f.getTranslationPart()));
      for(let i = 0; i < train.trainCars(); i++){
            if(state.wiperrun==1){
                state.number=sound(ctx,wipersounds,i,matrot4f.getTranslationPart(),1,state.number,12,1);//播放雨刮声
            }
            ctx.setDebugInfo(4*i+j+10+"=",state.number);
            ctx.drawCarModel(wipersmodels],i,mata);
      }
    };
    if(state.wiperrun == 1){
      if(state.wipersrottarget == 45){//向另一侧缓动
            state.wipersrot = smoothEnds(0,45,state.wiperstarttime,state.wiperstarttime + wiperspeedcoefficient,state.wiperstime);
            ctx.setDebugInfo("wiperDO=",1);
      }else if(state.wipersrottarget == 0){//要回到原始位置
            state.wipersrot = smoothEnds(45,0,state.wiperstarttime,state.wiperstarttime + wiperspeedcoefficient,state.wiperstime);
            ctx.setDebugInfo("wiperDO=",2);
      }
      state.wipersrotlast = state.wipersrot;
      state.wipersstarttimelast = state.wiperstime;
    };
    if(train.isOnRoute()){
      if(MinecraftClient.worldIsRaining()){
            state.wiperrun = 1;
            if(state.wipersrot == 45){
                state.wipersrottarget = 0;
                state.wiperstarttime = state.wiperstime;
                ctx.setDebugInfo("wiperCH=",1);
            }else if(state.wipersrot == 0){
                state.wipersrottarget = 45;
                state.wiperstarttime = state.wiperstime;
                ctx.setDebugInfo("wiperCH=",0);
            }
      }else{
            state.wiperrun = 0;

                state.wipersrot = smoothEnds(state.wipersrotlast,0,state.wipersstarttimelast+0.5,state.wipersstarttimelast + wiperspeedcoefficient * 0.8 * state.wipersrotlast / 45+0.5,state.wiperstime);
      }
    }
    state.wiperstime += Timing.delta();//计时器增加
    ctx.setDebugInfo("wipertime=",state.wiperstime);
}

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 smoothEnds(startValue, endValue, startTime, endTime, time) {//从隔壁抄的原本被用于车门缓动的函数
    if (time < startTime) return startValue;
    if (time > endTime) return endValue;
    let timeChange = endTime - startTime;
    let valueChange = endValue - startValue;
    return valueChange * (1 - Math.cos(Math.PI * (time - startTime) / timeChange)) / 2 + startValue;
}

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

function vectadd(v1,v2){//向量相加
    return new Vector3f(v1.x()+v2.x(),v1.y()+v2.y(),v1.z()+v2.z());
}

function MatricesTranslateVector3f(mat,vect){
    mat.translate(vect.x(),vect.y(),vect.z());
}

function sound(ctx,name2,i,vect,pit,nu,ll,long){//播放声音pit是音高(速度) nu是一个数组,用来记录播放时间,ll是音频响度,long是循环播放时间
    if(Timing.elapsed()>nu){//如果时间超过了播放时间
      ctx.playCarSound(Resources.id(name2) , i , vect.x() , vect.y() , vect.z() , ll , pit);//播放
      nu = Timing.elapsed()+long;   //更新播放时间
    }
    return nu;//返回新的播放时间
}

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


页: [1]
查看完整版本: 雨刮器的代码分享