国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

《每周一點canvas動畫》——角度反彈

sf_wangchong / 2994人閱讀

摘要:每周一點動畫代碼文件在上一節(jié)我們介紹了高級的坐標(biāo)旋轉(zhuǎn)方法,我們只需要知道物體的位置,通過設(shè)定每一幀需要旋轉(zhuǎn)的角速度通過公式就可以計算出做圓周運動時物體的下一個坐標(biāo)位置。思路有了,我們需要把它轉(zhuǎn)化成平面來做角度反彈。

每周一點canvas動畫代碼文件

在上一節(jié)我們介紹了高級的坐標(biāo)旋轉(zhuǎn)方法,我們只需要知道物體的位置,通過設(shè)定每一幀需要旋轉(zhuǎn)的角速度,通過公式

newX = x*cos - y*sin;
newY = y*cos + x*sin;

就可以計算出做圓周運動時物體的下一個坐標(biāo)位置。本節(jié)的內(nèi)容與上一節(jié)的內(nèi)容息息相關(guān)。所以,務(wù)必把上一節(jié)的內(nèi)容弄懂了,再來看這一節(jié)你就不會那么吃力了。這也應(yīng)該是本系列最難的一部分吧!請收下我的膝蓋。。。

在前面的章節(jié)中我們寫了很多的小動畫,大部分的動畫中,為了限制物體的活動范圍,當(dāng)物體與canvas畫布邊界接觸的時候,我們都設(shè)定了一個反彈系數(shù)bounce,讓物體有種撞上墻壁的感覺。但是現(xiàn)實環(huán)境中不僅僅只有水平或豎直方向的平面,更多的是不同傾斜度的表面。那么,當(dāng)物體撞擊上這樣的表面我們該如何處理呢?物體反彈后的速度大小,還有方向該如何計算呢?下面我們就來一一討論這些問題。

1.概念解析

如果,你對前面的文字描述不理解,沒關(guān)系。看下圖,我會通過圖形來形象的描述。比如,現(xiàn)在我們有個斜平面,物體以一定的速度朝著斜面運動。

沒有現(xiàn)成的公式可以直接讓物體按照我們想象的從斜面反彈。這似乎是個很復(fù)雜的問題,那你有沒有想過,既然斜面不好做,何不把它轉(zhuǎn)到平面來做呢!我們最擅長的就是平面的反彈了。

思路有了,我們需要把它轉(zhuǎn)化成平面來做角度反彈。那我們需要做哪些事情呢?不賣關(guān)子了,我們所要做的所有事情就是把整個系統(tǒng)包括物體,包括平面全部旋轉(zhuǎn)的平面,做完反彈處理后,再旋轉(zhuǎn)回去。這就意味著,我們需要旋轉(zhuǎn)斜面,旋轉(zhuǎn)物體的坐標(biāo),并且還要旋轉(zhuǎn)物體的速度。

這里我隨便設(shè)置了一個中心點(圖中虛線與實線相交的部分),讓其圍繞這個中心點旋轉(zhuǎn)至平面。此時速度也做了相應(yīng)的旋轉(zhuǎn),圖中清晰的顯示出了速度的方向。接下來,你應(yīng)該就很熟悉了,既然到了水平面做反彈就很容易。反彈后的速度方向如下圖:

下一步,就是把整個系統(tǒng)旋轉(zhuǎn)回去,也就是還原整個系統(tǒng)到初始位置

如果你對它的真實性表示懷疑,這里我們它旋轉(zhuǎn)前與旋轉(zhuǎn)恢復(fù)后的兩幅圖做個疊加

是不是跟你想象的完全一樣呢?

2.代碼實現(xiàn)

首先我們,新建一個類文件line.js,它的作用和其他的類文件一樣,就是畫一條線。這里我就不列出來了,你可以去代碼文件中找到這個文件的代碼。先上效果圖

具體代碼如下,首先引入類文件


   
   
   

然后是初始化我們需要的元素

小球的引入我就不解釋了,Line有4個參數(shù)(x1,y1,x2,y2),表示從(x1,y1)位置開始,至(x2,y2)位置畫一條線。在代碼中是從(0,0)到(300,0),也就是畫了一條長度為300的水平直線。然后,把它移動到(50, 300)的位置,并讓其傾斜了一個角度。這樣你就看到我們圖中的斜線了。

下一步,就是我們的核心了

(function drawFrame(){
               window.requestAnimationFrame(drawFrame, canvas);
               context.clearRect(0, 0, canvas.width, canvas.height);
               
               //球體運動
               ball.vy += gravity;            
               ball.x += ball.vx;                //初始為0,小球豎直往下落
               ball.y += ball.vy;
               
               //獲取小球體與線的相對位置
               var x1 = ball.x - line.x,
                   y1 = ball.y - line.y,
                   
                   //旋轉(zhuǎn)坐標(biāo)
                   x2 = x1 * cos + y1 * sin,
                   y2 = y1 * cos - x1 * sin,
                   
                   //旋轉(zhuǎn)速度
                   vx1 = ball.vx * cos + ball.vy * sin,
                   vy1 = ball.vy * cos - ball.vx * sin;
            
               
               //如果小球與斜面碰撞
               if(y2 > -ball.radius){
                   y2 = -ball.radius;              //重設(shè)小球的位置
                   vy1 *= bounce;                  //反彈
               }
               //
               x1 = x2 * cos - y2 * sin;           //位置旋轉(zhuǎn)回去,注意公式變化
               y1 = y2 * cos + x2 * sin;
               ball.vx = vx1 * cos - vy1 * sin;    //速度旋轉(zhuǎn)回去
               ball.vy = vy1 * cos + vx1 * sin;
               ball.x = line.x + x1;               //小球位置變化
               ball.y = line.y + y1;
               
               ball.draw(context);
               line.draw(context);
               
}())

注意代碼中,旋轉(zhuǎn)回去的坐標(biāo)旋轉(zhuǎn)公式公式發(fā)生了變化。

3.代碼優(yōu)化

注意上部分代碼中,我們發(fā)生坐標(biāo)旋轉(zhuǎn)是在下面的條件下:

 if(y2 > -ball.radius){
       //...
  }

那上面的代碼就有很大的問題了,我們在每一幀都做了坐標(biāo)旋轉(zhuǎn),再旋轉(zhuǎn)回去。其實完全沒有必要,所以代碼修改如下:

...
    var x1 = ball.x - line.x,
        y1 = ball.y - line.y,
        y2 = y1*cos - x1*sin;
        
   
    if(y2 > -ball.radius){                       //只有當(dāng)小球與平面接觸時才做旋轉(zhuǎn)
           var x2 = x1*cos + y1*sin;             //旋轉(zhuǎn) x 坐標(biāo)
                      
           vx1 = ball.vx*cos + ball.vy*sin;      //旋轉(zhuǎn)速度
           vy1 = ball.vy*cos - ball.vx*sin;
                      
            y2 = -ball.radius;
            vy1 *= bounce;
                      
           //所有東西旋轉(zhuǎn)回去
           x1 = x2*cos - y2*sin;
           y1 = y2*cos + x2*sin;
           ball.vx = vx1*cos - vy1*sin;
           ball.vy = vy1*cos + vx1*sin;
           ball.x = line.x + x1;
           ball.y = line.y + y1;
}
4.邊界問題

注意到在上面的效果中,當(dāng)小球超出了斜面依然保持運動。而不是我們想象的掉落到地面上。為了修正這個問題,我們需要用到前面章節(jié)介紹的兩個物體之間的邊界檢測方法,你應(yīng)該很熟悉。

//動畫循環(huán)中
var bounds = line.getBounds(),
if( ball.x + ball.radius > bounds.x && ball.x - ball.radius < bounds.x + bounds.width){
    if(y2 > -ball.radius){
       //....
    }
}

效果如下:

5.更多動效

1.用鼠標(biāo)控制斜面的角度

2.多斜面撞擊

6.總結(jié)

本章的重點公式就是一個坐標(biāo)旋轉(zhuǎn)

newX = x*cos - y*sin;
newY = y*cos + x*sin;

//旋轉(zhuǎn)回去
newX = x*cos + y*sin;
newY = y*cos - x*sin;

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79952.html

相關(guān)文章

  • 周一canvas動畫》——森林與星海

    摘要:每周一點動畫代碼文件在上一節(jié)每周一點動畫物理效果中,我們介紹了維環(huán)境下的速度與加速度效果。與二維系統(tǒng)中的效果如出一轍。二叉樹二叉樹的類文件名為。與簡單樹的原理不一樣,二叉樹的原理是采用遞歸的方法實現(xiàn)樹枝與樹干的繪制。 每周一點canvas動畫代碼文件 在上一節(jié)《每周一點canvas動畫》——3D物理效果中,我們介紹了3維環(huán)境下的速度與加速度效果。這一節(jié),我們繼續(xù)介紹另外兩個物理效果:重...

    seanlook 評論0 收藏0
  • 周一canvas動畫》——速度與加速度(2)

    摘要:重力加速度在這一部分我們介紹加速度中比較特別的一個重力加速度。重力加速度其實是由兩個物體間的引力形成的,到后面我們專門會有一個章節(jié)來介紹萬有引力,并且將它運用于我們的動畫之中。 在上一節(jié)中我們介紹了速度的基本概念,包括沿坐標(biāo)軸的速度,和更普適的任意方向的速度,在文章的最后我們做了一個鼠標(biāo)跟隨的示例,以及通過改變物體的rotation屬性做了一個關(guān)于速度的擴展。通過上一節(jié)的學(xué)習(xí)你會發(fā)現(xiàn)我...

    ZweiZhao 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<