摘要:碰撞檢測邊界檢測在前端游戲,以及涉及拖拽交互的場景應用十分廣泛。這就涉及到碰撞檢測或者叫邊界檢測的問題了。若四邊均未發(fā)生重合,則未發(fā)生碰撞,反之則發(fā)生碰撞。目前業(yè)務有遇到碰撞需求,所以抽時間整理了下。
碰撞檢測(邊界檢測)在前端游戲,以及涉及拖拽交互的場景應用十分廣泛。
那么啥叫碰撞?JavaScript 又是如何檢測 DOM 發(fā)生碰撞的呢?
碰撞,顧名思義,就是兩個物體碰撞在了一起,眼睛是可以直觀的觀察到碰撞的發(fā)生。但對于前端實現(xiàn),如何讓 JavaScript 代碼理解兩個獨立的“物體”(DOM)碰撞在一起呢。這就涉及到碰撞檢測(或者叫邊界檢測)的問題了。
碰撞檢測的常見需求場景:前端常見的的碰撞,我們可以粗略的分為幾下幾類:
兩個矩形塊的碰撞:判斷任意兩個(水平)矩形的任意一邊是否有間距,從而得之兩個矩形塊有沒有發(fā)生碰撞。具體實現(xiàn)方式,可以選定一個矩形為參照物,計算另一矩形的與自己相近的邊是否發(fā)生重合現(xiàn)象。若四邊均未發(fā)生重合,則未發(fā)生碰撞,反之則發(fā)生碰撞。
圖形示例:
簡單算法實現(xiàn)(非碰撞情況,else 分支就是碰撞情況):
if( domA.left > domB.right || domA.top > domB.bottom || domA.right < domB.left || domA.bottom < domB.top ) { return false // 未碰撞 } else { return true // 碰撞 }圓形與圓形的碰撞:
判斷任意兩個圓形碰撞比較簡單,只需要判斷兩個圓的圓心距離是否小于兩圓半徑之和,如果小于半徑和,就可以判定兩個圓發(fā)生碰撞。
圖形示例:
簡單算法實現(xiàn)
let distance = Math.sqrt(Math.pow(x1 - x2) + Math.pow(y1 - y2) ) if (distance < r1 + r2) { // r1、r2 分別為兩圓的半徑 return true // 發(fā)生碰撞 } else { return false //未發(fā)生碰撞 }圓形與矩形塊的碰撞:
圓形與矩形發(fā)生碰撞的要點則是要找出矩形上距離圓心最近的點,然后通過判斷該點與圓心的決定是否小于圓的半徑,若小于則為碰撞。
點的位置,可以通過獲取矩形某一個特定的定點坐標結合矩形寬高與圓的圓心進行比較確定。基本原理與兩個矩形碰撞相似,但是略有差異,因為圓形有直接與矩形頂點碰撞的情況。
如下圖所示,與矩形碰撞的區(qū)別在于,多出了處理矩形寬高延長線交叉區(qū)域的情況。當圓心位于兩條平行邊線之間時:矩形上與圓心最近的點為圓心垂直與矩形最近邊線的交叉點;當圓心位于兩條交叉邊線之間時(如下圖斜線區(qū)域),與圓心最近的點則是矩形交叉邊線的頂點:
簡單算法實現(xiàn)(B 圓只是做輔助說明)
// 假設 矩形為 Box, 圓的半徑為 R let distance if (x1 < Box.left && y1 > Box.top && y1 < Box.bottom) { // 位于上圖中 圓 A 的 位置 distance = Box.left - x1 } else if ( x1 > Box.Right && y1 < Box.top ) { // 位于 上圖中 圓 B 的位置 distance = Math.sqrt(Math.pow(x1 - Box.right) + Math.pow(y1 - Box.top)) } // 其他幾種情況類似...按著順/逆時針的順序,總共八個區(qū)域就能全覆蓋 if (distance < R) { return true // 碰撞 } else { return false // 未碰撞 }
還有一種涉及到多 DOM 碰撞的情況,一般業(yè)務需求是動態(tài)生成 DOM,占位,移動,然后再生成新 DOM,使他們不可重疊。通過查資料發(fā)現(xiàn) 地圖碰撞 算法比較適合這樣的場景。
地圖碰撞算法地圖碰撞算法 主要是應用了矩陣的思想。即將拖拽區(qū)域進行數(shù)據(jù)化分割,劃分成一個假想的數(shù)據(jù)地圖,每一個小塊算是一個獨立的位置格子,通過標記狀態(tài)來確定小格子是否被占用。然后應用最簡單的 矩形碰撞 來判定拖動的 DOM 是否與格子發(fā)生碰撞,發(fā)生則將格子狀態(tài)改為 1,未被占用則標記為 0。只有未被占用的格子可以被占用,占用的格子,釋放后標記為 0。這種狀態(tài)管理的方式,很適合結合 React、Vue 等前端框架做一些拖拽、碰撞的復雜業(yè)務交互。
圖形示例:
簡單思路實現(xiàn)
// 區(qū)域是否可用 標記 矩陣 let map = [ [0, 1, 0, 0], [0, 0, 0, 0] ] // 設置初始位置 let NewDom = { left: 0, top: 0} // 判斷是否可安置 ...
以上是比較主流的幾種碰撞情況,以及主要的思路實現(xiàn)。目前業(yè)務有遇到碰撞需求,所以抽時間整理了下。圓形和矩形碰撞的情況感覺還可以優(yōu)化下,如果有好的思路,可以互相學習下。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/100245.html
摘要:碰撞檢測邊界檢測在前端游戲,以及涉及拖拽交互的場景應用十分廣泛。這就涉及到碰撞檢測或者叫邊界檢測的問題了。若四邊均未發(fā)生重合,則未發(fā)生碰撞,反之則發(fā)生碰撞。目前業(yè)務有遇到碰撞需求,所以抽時間整理了下。 碰撞檢測(邊界檢測)在前端游戲,以及涉及拖拽交互的場景應用十分廣泛。 那么啥叫碰撞?JavaScript 又是如何檢測 DOM 發(fā)生碰撞的呢? 碰撞,顧名思義,就是兩個物體碰撞在了一起,...
摘要:通用算法概念模型圓形與矩形之間的碰撞核心理念通過找出矩形上離圓心最近的點,然后通過判斷該點與圓心的距離是否小于圓的半徑,若小于則為碰撞。 碰撞檢測在前端游戲,設計拖拽的實用業(yè)務等領域的應用場景非常廣泛,今天我們就在這里對于前端JavaScript如何實現(xiàn)碰撞檢測算法進行一個原理上的探討,讓大家能夠明白如何實現(xiàn)碰撞以及碰撞的理念是什么:1.矩形與矩形間的碰撞核心理念判斷任意兩個(無旋轉(zhuǎn))...
摘要:前言啃了這么長時間,基本上已經(jīng)把某數(shù)的套路摸了個八九不離十,不愧是中國反爬界的集大成者,感覺收獲滿滿,這里就簡單記錄一下分析成果。注意某數(shù)在不同的網(wǎng)站上有不同的版本,其流程也略有不同,這里的流程不一定適用于其它網(wǎng)站。 showImg(https://segmentfault.com/img/remote/1460000018765904); 前言 啃了這么長時間,基本上已經(jīng)把某數(shù)的套路...
閱讀 1813·2021-09-22 15:54
閱讀 2923·2021-09-01 10:42
閱讀 3442·2019-08-30 15:56
閱讀 1432·2019-08-29 18:46
閱讀 2464·2019-08-29 10:57
閱讀 2703·2019-08-28 17:57
閱讀 3659·2019-08-23 18:14
閱讀 833·2019-08-23 17:03