js實現圓形的碰撞檢測


文章地址:https://www.cnblogs.com/sandraryan/

碰撞檢測這個東西寫小游戲挺有用der~~~

注釋寫的還挺全,所以就不多說了,看注釋

這是頁面結構。wrap存放生成的小球

box是用來檢測的元素

<div class="wrap">
        <!-- 用於做碰撞檢測的一個元素 -->
        <div class="box"></div>
    </div>

css:

 body {
            margin: 0;
            padding: 0;
        }

        .wrap {
            width: 100vw;
            height: 100vh;
            background-color: rgb(228, 243, 248);
        }

        .box {
            width: 70px;
            height: 70px;
            background-color: green;
            border-radius: 50%;
            position: fixed;
            top: 0;
            left: 0;
        }

        .wrap .item {
            position: fixed;
            border-radius: 50%;
        }

js

let wrap = document.querySelector('.wrap');
        let box = document.querySelector('.box');
        // 隨機數函數
        function rn(a, b) {
            return Math.round(Math.random() * (a - b) + b);
        }
        // 創建其他小球的函數
        function create() {
            // 創建div
            let el = document.createElement('div');
            // 從20-100之間隨機一個數作為小球的寬高(要是圓形,所以寬高相同)
            let w = rn(20, 80);
            el.style.width = w + 'px';
            el.style.height = w + 'px';
            // 設置top left值 該元素css有固定定位
            //可以選擇把最大值設置為當前屏幕/父級寬高,然后減去元素最大隨即寬度(80)
            el.style.top = rn(0, 500) + 'px';
            el.style.left = rn(0, 1200) + 'px';
            // 追加item作為類名
            el.className = 'item';
            // 獲取0-1之間的隨機數並取小數點后一位
            let opa = Math.random().toFixed(1);
            // 設置隨機顏色
            // 不能先給一個變量隨機0-254,然后拼接變量,拼接出來red green blue顏色都一樣
            el.color = 'rgba(' + rn(0, 254) + ',' + rn(0, 254) + ',' + rn(0, 254) + ',' + opa + ')';
            el.style.background = el.color;
            // 元素追加給wrap
            wrap.appendChild(el);
        }
        // 利用循環創建20個小球
        function balls() {
            for (let i = 0; i < 20; i++) {
                create();
            }
        }
        balls();
        // box半徑(理論上寫一個就好,是個正方形畫出來的圓嘛~)
        let r1 = box.offsetWidth / 2;
        // 獲取創建的小球們
        let item = document.querySelectorAll('.item');
        // console.log(item);
        // 文檔注冊鼠標移動事件
        document.onmousemove = function (ev) {
            let e = ev || event;
            // 獲取瀏覽器寬度/高度,減去要檢測的盒子寬高一半
            let x = e.clientX - r1;
            let y = e.clientY - r1;
            // 設為要拿去做檢測的盒子左邊,上邊
            // 鼠標移動的時候改變要拿去做碰撞檢測的元素的top left值(改變位置,讓他動起來,動的范圍是整個可視頁面-自己寬高,不會卡一半在外面)
            box.style.left = x + 'px';
            box.style.top = y + 'px';
            for (let i = 0; i < item.length; i++) {
                // item的半徑
                let r2 = item[i].offsetHeight / 2;
                // 生成的小球的左邊+半徑,減用來檢測的元素的左邊+半徑(兩個球圓心距)
                let leftC = item[i].offsetLeft + r2 - (box.offsetLeft + r1);
                // 生成的小球上邊加半徑-檢測小球的上邊加半徑
                let topC = item[i].offsetTop + r2 - (box.offsetTop + r1);
                // pow() 方法可返回 x 的 y 次冪的值。
                // sqrt() 方法可返回一個數的平方根。
                // 水平方向圓心距的2次冪 +  垂直方向的圓心距2次冪,的平方根(勾股定理?)
                let dis = Math.sqrt(Math.pow(leftC, 2) + Math.pow(topC, 2));
                // 求出來的值小於檢測的兩個球的半徑的和,碰撞上了,生成的小球變色
                if (dis < r1 + r2) {
                    item[i].style.background = 'red';
                } else {
                    item[i].style.background = item[i].color;
                }
            }
        };

over


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM