在 JavaScript 中使用增量时间进行比率平滑是有问题的

问题描述

平滑的工作原理如下:

某些变量 v一个目标 t。每一个刻度,v 都会根据一个比率朝着 t 前进。例如,比率为 2:3 或 ⅗ 将使用此公式:

v=(v*3+t*2)/5; 

在这里,您将变量相乘以得出比率,然后将其全部除以得出平滑比率。 t 可以根据需要修改v 将处理平滑和输出

所以你有增量时间。您选择一个目标帧率并从那里开始。我自己想通了,所以我可能对某些术语有误,但无论如何。在一帧中,平滑将进行 ⅖,这意味着您还有 ⅗。在两帧中,您将得到 ⅗×⅗ 的余数。我想:不过,我怎么能做到这一点呢?然后我就像“哦等等,你可以利用这些力量。”所以我只是想使用 insertRatioHere**deltaTime 并将其乘以当前状态和目标状态之间的差异。起初是这样的

v=t-v+(v*(0.6**delta))

但这并没有真正奏效,所以我尝试了很多不同的公式,并进行了微小的改动,但都没有奏效。这是我当前的测试代码

<HTML>
    <head>
        <title>delta</title>
    </head>
    <body>
        <canvas id=myCanvas width=400 height=300 style="background-color:white;"></canvas>
        <script>
        var ctx=myCanvas.getContext("2d");
        var time={first:new Date(),Now:new Date(),delta:new Date()};
        time.since=time.Now-time.first;
        time.delta=time.delta.getTime();
        const frame=1000/60;
        var lag=100;//change between 0,frame,100 and other values when desired
        var BoxA={xPos:200,yPos:150,xAccel:0,yAccel:0,xSpeed:0,ySpeed:0,speed:0};
        var BoxB={xPos:200,speed:0};
        var keysDown=[];
        var keyBind={upA:{key:87,on:false},leftA:{key:65,downA:{key:83,rightA:{key:68,upB:{key:38,leftB:{key:37,downB:{key:40,rightB:{key:39,on:false}};
        var varLog=[];
        addEventListener("keydown",whenKeyDown);
        addEventListener("keyup",whenKeyUp);
        tick=setInterval(tickBoxA,lag);
        tick=setInterval(tickBoxB,frame);
        function tickBoxA()
            {time.Now=new Date();
            time.delta=time.Now-time.first-time.since;
            time.since=time.Now-time.first;
            if(keysDown.includes(keyBind.upA.key)){
                if(!keyBind.upA.on){keyBind.upA.on=true}
            }else{keyBind.upA.on=false}
            if(keysDown.includes(keyBind.leftA.key)){
                if(!keyBind.leftA.on){keyBind.leftA.on=true}
            }else{keyBind.leftA.on=false}
            if(keysDown.includes(keyBind.downA.key)){
                if(!keyBind.downA.on){keyBind.downA.on=true}
            }else{keyBind.downA.on=false}
            if(keysDown.includes(keyBind.rightA.key)){
                if(!keyBind.rightA.on){keyBind.rightA.on=true}
            }else{keyBind.rightA.on=false}
            BoxA.xAccel=(keyBind.rightA.on-keyBind.leftA.on)*3*((keyBind.upA.on-keyBind.downA.on!=0)?Math.sin(45):1);
            BoxA.xSpeed=BoxA.xAccel-BoxA.xSpeed+(BoxA.xSpeed*0.9**(time.delta/frame));
            //BoxA.xSpeed=BoxA.xAccel+BoxA.xSpeed-(BoxA.xSpeed*0.9**(time.delta/frame));
            //BoxA.xSpeed=BoxA.xAccel+(BoxA.xSpeed-BoxA.xAccel*0.9**(time.delta/frame));
            //BoxA.xSpeed=BoxA.xAccel+(BoxA.xAccel-BoxA.xSpeed*0.9**(time.delta/frame));
            BoxA.yAccel=(keyBind.downA.on-keyBind.upA.on)*3*((keyBind.rightA.on-keyBind.leftA.on!=0)?Math.sin(45):1);
            BoxA.ySpeed=BoxA.yAccel-BoxA.ySpeed+(BoxA.ySpeed*0.9**(time.delta/frame));
            BoxA.speed=Math.sqrt((BoxA.xSpeed**2)+(BoxA.ySpeed**2));
            BoxA.xPos+=BoxA.xSpeed*(time.delta/frame);
            BoxA.yPos+=BoxA.ySpeed*(time.delta/frame);
            render()}
        function tickBoxB()
            {if(keysDown.includes(keyBind.upB.key)){
                if(!keyBind.upB.on){keyBind.upB.on=true}
            }else{keyBind.upB.on=false}
            if(keysDown.includes(keyBind.leftB.key)){
                if(!keyBind.leftB.on){keyBind.leftB.on=true}
            }else{keyBind.leftB.on=false}
            if(keysDown.includes(keyBind.downB.key)){
                if(!keyBind.downB.on){keyBind.downB.on=true}
            }else{keyBind.downB.on=false}
            if(keysDown.includes(keyBind.rightB.key)){
                if(!keyBind.rightB.on){keyBind.rightB.on=true}
            }else{keyBind.rightB.on=false}
            BoxB.xSpeed=(BoxB.xSpeed*9+(keyBind.rightB.on-keyBind.leftB.on)*3*((keyBind.upB.on-keyBind.downB.on!=0)?Math.sin(45):1))/10;
            BoxB.ySpeed=(BoxB.ySpeed*9+(keyBind.downB.on-keyBind.upB.on)*3*((keyBind.rightB.on-keyBind.leftB.on!=0)?Math.sin(45):1))/10;
            BoxB.xPos+=BoxB.xSpeed;
            BoxB.yPos+=BoxB.ySpeed;
            render()}
        function whenKeyDown(keyDownEvent){
            check=keyDownEvent.keyCode;
            if(keysDown.findindex(isSame)==-1)
                {keysDown.push(keyDownEvent.keyCode)}}
        function whenKeyUp(keyUpEvent){
            check=keyUpEvent.keyCode;
            keysDown.splice(keysDown.findindex(isSame),1)}
        function isSame(num){return num==check}
        function render()
            {ctx.clearRect(0,400,300);
            ctx.fillStyle="#F00";
            ctx.fillRect(BoxA.xPos,BoxA.yPos,20,20);
            ctx.fillStyle="#0F0";
            ctx.fillRect(BoxB.xPos,BoxB.yPos,20);
            varLog.length=0;
            varLog.push("Time:              "+time.since);
            varLog.push("Delta:             "+time.delta);
            varLog.push("Frame accuracy:    "+time.delta/frame);
            varLog.push("Standard framerate is 60FPS");
            varLog.push("Red Box target X:  "+BoxA.xAccel);
            varLog.push("Red Box current X: "+BoxA.xSpeed);
            varLog.push("Red Box target Y:  "+BoxA.yAccel);
            varLog.push("Red Box current Y: "+BoxA.ySpeed);
            varLog.push("Red Box speed:     "+BoxA.speed);
            varLog.push("The red Box is trying to handle smooth");
            varLog.push("acceleration in delta time");
            varLog.push("and yeah I messed up");
            varLog.push("Green Box speed X: "+BoxB.xSpeed);
            varLog.push("Green Box speed Y: "+BoxB.ySpeed);
            varLog.push("Green Box speed:   "+BoxB.speed);
            varLog.push("The green Box works as desired at 60FPS");
            varLog.push("Keys pressed:      "+keysDown);
            varLog.push("Red=WASD,green=↑←↓→");
            ctx.font="15px Courier";
            ctx.fillStyle="#000";
            for(run=0;run<varLog.length;run++){ctx.fillText(varLog[run],(run+1)*15)}}
        </script>
    </body>
</html> 

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)