<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] 所謂邊界檢測簡單來說就是給運動物體限定一個范圍,從而實現某些動畫效果。在 Canvas 中,大部分情況下都會把物體運動范圍設置為整個畫布,有時候也可以是畫布的一部分。 ![](https://img.kancloud.cn/69/39/693944651ec599a9d8d131f6eef2a27a_420x396.png =200x) 如上圖,假設有一個小球,其中心坐標為(x,y),那么此時的邊界檢測代碼為: ```js if (ball.x < ball.radius) { // "碰到" 左邊界時做什么 } else if (ball.x > cnv.width - ball.radius) { // "碰到" 右邊界時做什么 } else if (ball.y < ball.radius) { // "碰到" 上邊界時做什么 } else if (ball.y > cnv.height - ball.radius) { // "碰到" 下邊界時做什么 } ``` 接下來從以下四個方向介紹邊界檢測 - 邊界限制 - 邊界生成 - 邊界環繞 - 邊界反彈 ## 邊界限制 邊界限制指的是通過邊界檢測的辦法來限制物體的運動范圍,使其無法超出這個運動范圍,而只在限制的范圍內運動。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>邊界線制</title> <script src="./tool.js"></script> <script src="./ball.js"></script> </head> <body> <canvas id="canvas" width="480" height="300" style="border: 1px solid gray; display: block; margin: 0 auto;"></canvas> <script> window.onload = function () { let cnv = document.getElementById('canvas') let cxt = cnv.getContext('2d') let ball = new Ball(cnv.width / 2, cnv.height / 2) ball.fill(cxt) let key = tools.getKey() // 添加鍵盤事件 window.addEventListener('keydown', function (e) { cxt.clearRect(0, 0, cnv.width, cnv.height) // 根據 key.direction 的值,判斷物體移動方向 switch (key.direction) { case 'up': ball.y -= 3 checkBorder() ball.fill(cxt) break case 'down': ball.y += 3 checkBorder() ball.fill(cxt) break case 'left': ball.x -= 3 checkBorder() ball.fill(cxt) break case 'right': ball.x += 3 checkBorder() ball.fill(cxt) break default: checkBorder() ball.fill(cxt) } }, false) // 定義邊界檢測函數 function checkBorder () { if (ball.x < ball.radius) { // "碰到" 左邊界時做什么 ball.x = ball.radius } else if (ball.x > cnv.width - ball.radius) { // "碰到" 右邊界時做什么 ball.x = cnv.width - ball.radius } else if (ball.y < ball.radius) { // "碰到" 上邊界時做什么 ball.y = ball.radius } else if (ball.y > cnv.height - ball.radius) { // "碰到" 下邊界時做什么 ball.y = cnv.height - ball.radius } } } </script> </body> </html> ``` ## 邊界環繞 邊界環繞指的是當物體從一個邊界消失后,它就會從對立的邊界重新出現,從而形成一種環繞效果。 語法: ```js if (ball.x < -ball.radius) { // 小球 "完全超出" 左邊界時 } else if (ball.x > cnv.width + ball.radius) { // 小球 "完全超出" 右邊界時 } else if (ball.y < -ball.radius) { // 小球 "完全超出" 上邊界時 } else if (ball.y > cnv.height + ball.raidus) { // 小球 "完全超出" 下邊界時 } ``` 注意這里的 “完全超出” 的含義,當小球完全超出邊界時,此時小球在畫布外面,如下圖所示: ![](https://img.kancloud.cn/03/a0/03a0bc09fa9e1b227f0dba71ea619749_413x414.png =200x) ## 邊界生成 邊界生成,指的是物體完全超出邊界后,在最開始的位置重新生成。這種技巧可用于創建噴泉及各種粒子特效。例如在噴泉效果中,水滴不斷地飛濺出來,飛出邊界后又重新加入到水流的源頭。這樣物體的數量就是固定不變的,不用擔心因物體數量過多而影響瀏覽器性能。 語法: ```js if (ball.x < -ball.radius || ball.x > cnv.width + ball.radius || ball.y < -ball.radius || ball.y > cnv.height + ball.radius // ... ) ``` 注意這里用的是 "或" 運算。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>邊界生成</title> <script src="./tool.js"></script> <script src="./ball.js"></script> </head> <body> <canvas id="canvas" width="480" height="300" style="border: 1px solid gray; display: block; margin: 0 auto;"></canvas> <script> window.onload = function () { let cnv = document.getElementById('canvas') let cxt = cnv.getContext('2d') // 定義一個用來存放小球的數組 balls let balls = [] // n 表示小球數量 let n = 50 // 生成 n 個小球,其中小球的 color、vx、vy 都是隨機值 for (let i = 0; i < n; i++) { // 球心坐標為 Canvas 中心,color 為隨機顏色值 let ball = new Ball(cnv.width / 2, cnv.height / 2, 5, tools.getRandomColor()) // ball.vx 和 ball.vy 取值都是 -1 ~ 1 之間的任意數 ball.vx = Math.random() * 2 - 1 ball.vy = Math.random() * 2 - 1 balls.push(ball) }; (function frame () { window.requestAnimationFrame(frame) cxt.clearRect(0, 0, cnv.width, cnv.height) balls.forEach(function (ball) { // 邊界檢測 if (ball.x < -ball.radius || ball.x > cnv.width + ball.radius || ball.y < -ball.radius || ball.y > cnv.height + ball.radius ) { ball.x = cnv.width / 2 ball.y = cnv.height / 2 ball.vx = Math.random() * 2 - 1 ball.vy = Math.random() * 2 - 1 } ball.fill(cxt) ball.x += ball.vx ball.y += ball.vy }) })() } </script> </body> </html> ``` ![](https://img.kancloud.cn/fc/dd/fcdd748232b6ee72dd4412267c7778fc_641x405.gif =300x) ## 邊界反彈 邊界反彈,指的是物體觸碰到邊界之后就會反彈回來。偽代碼如下: ```js if (ball.x < ball.radius) { // 碰到左邊界 ball.x = ball.radius vx = -vx } else if (ball.x > canvas.width - ball.radius) { // 碰到右邊界 ball.x = canvas.width - ball.radius vx = -vx } else if (ball.y < ball.radius) { // 碰到上邊界 ball.y = ball.radius vy = -vy } else if (ball.y > canvas.height - ball.radius) { ball.y = canvas.height - ball.radius vy = -vy } ``` 下面是一個多球反彈的效果: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>多球反彈</title> <script src="./tool.js"></script> <script src="./ball.js"></script> </head> <body> <canvas id="canvas" width="480" height="300" style="border: 1px solid gray; display: block; margin: 0 auto;"></canvas> <script> window.onload = function () { let cnv = document.getElementById('canvas') let cxt = cnv.getContext('2d') // 定義一個用來存放小球的數組 balls const balls = [] const n = 10 // 小球數量 // 生成 n 個小球,其中小球的 color、vx、vy 都是隨機值 for (let i = 0; i < n; i++) { let ball = new Ball(cnv.width / 2, cnv.height / 2, 8, tools.getRandomColor()) ball.vx = (Math.random() * 2 - 1) * 3 ball.vy = (Math.random() * 2 - 1) * 3 balls.push(ball) }; (function frame () { window.requestAnimationFrame(frame) cxt.clearRect(0, 0, cnv.width, cnv.height) balls.forEach(function (ball) { ball.x += ball.vx ball.y += ball.vy if (ball.x < ball.radius) { // 碰到左邊界 ball.x = ball.radius ball.vx = -ball.vx } else if (ball.x > canvas.width - ball.radius) { // 碰到右邊界 ball.x = canvas.width - ball.radius ball.vx = -ball.vx } else if (ball.y < ball.radius) { // 碰到上邊界 ball.y = ball.radius ball.vy = -ball.vy } else if (ball.y > canvas.height - ball.radius) { ball.y = canvas.height - ball.radius ball.vy = -ball.vy } ball.fill(cxt) }) })() } </script> </body> </html> ``` ![](https://img.kancloud.cn/73/22/7322bc416d417c345a208efcc53a817f_641x405.gif =300x) 可以看到,對于多物體運動,一般情況下都是采取以下三個步驟進行處理: 1. 定義一個數組來存放多個物體 2. 使用 for 循環生成單個物體,然后添加到數組中 3. 在動畫循環中,使用 forEach() 方法遍歷數組,從而處理單個物體
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看