摘要:微信端口的小游戲相信大家已經(jīng)做了很多類似于碰撞檢測這種也是數(shù)不勝數(shù)因?yàn)檎系K物和主角都是圖片也就意味著碰撞檢測實(shí)際上是兩個(gè)矩形直接是否有交叉的判斷包括這樣的框架也是這樣子做的當(dāng)然這種方法也無可厚非然而唯一的問題是如果素材障礙物和主角并不能鋪滿
微信端口的小游戲相信大家已經(jīng)做了很多,
類似于碰撞檢測這種也是數(shù)不勝數(shù).因?yàn)檎系K物和主角都是圖片,也就意味著碰撞檢測實(shí)際上是兩個(gè)矩形直接是否有交叉的判斷.包括phaser這樣的框架也是這樣子做的.
當(dāng)然這種方法也無可厚非.然而, 唯一的問題是如果素材(障礙物和主角)并不能鋪滿整個(gè)矩形的話一旦程序檢查到碰撞而實(shí)際上兩個(gè)素材并沒有真正意義上的接觸就會(huì)略顯尷尬,
如下面這個(gè)圖所示:
為了方便演示和對比起來更直觀, 我給兩個(gè)png圖片加了背景, 如果是簡單的矩形相交判斷這個(gè)時(shí)候判斷了碰撞就會(huì)很尷尬...
所以, 我們需要稍微高級點(diǎn)兒的辦法來解決, 雖然我數(shù)學(xué)很差, 但是還是要考數(shù)學(xué)來解決:
用判斷矩形的四條邊是否有與多邊形上的邊相交來替代單純的兩個(gè)矩形相交.在案例中, 因?yàn)槲业恼系K物都比較小 而且填的比較滿, 所以就不做拆分(如上圖的綠色的血), 主角有棱有角 需要做一下拆分轉(zhuǎn)換為多邊形.
在程序中我是取障礙物的坐標(biāo)和主角的坐標(biāo)來做判斷的, 因此, 獲取主角的坐標(biāo)就是首要任務(wù), 最快捷的方法就是借住ps的鋼筆工具, 如下圖所示:
用鋼筆工具沿著豬腳的實(shí)際圖片區(qū)域走一次, 然后把相對坐標(biāo)點(diǎn)記錄下來. 所謂的相對坐標(biāo)點(diǎn)是基于該圖片左上角水平和垂直方向的距離,
比如第一個(gè)點(diǎn)的坐標(biāo)是x:42, y:8.
我做這些小游戲的思路是 主角和障礙物都在一個(gè)canvas上做, 程序先記錄下豬腳的起點(diǎn)坐標(biāo) 然后根據(jù)相對坐標(biāo)即可計(jì)算出多邊形的每個(gè)點(diǎn)在canvas上的實(shí)際坐標(biāo)了. 拿到實(shí)際坐標(biāo)后我們就可以做公式的運(yùn)算判斷是否相撞了, 公式如下:
/** *@param {Array} point 障礙物4個(gè)點(diǎn)坐標(biāo)的集合 *@param {String} x 主角的x坐標(biāo) *@param {String} x 主角的y坐標(biāo) *@param {Array} area 主角偏移坐標(biāo)的集合 */ function lineJudge(point, x, y, area){ var p1, p2, p3, p4; for(var i = 0; i < 4; i++) { p1 = point[i]; if(3 == i) { p2 = point[0] } else { p2 = point[i + 1]; } for(var j = 0, lenA = area.length; j < lenA; j++) { p3 = [area[j][0] + x, area[j][3] + y]; if(j == lenA - 1) { p4 = [area[0][0] + x, area[0][4] + y]; } else { p4 = [area[j + 1][0] + x, area[j + 1][5] + y]; } if("boolean" != typeof _getIntersectionPoint(p1, p2, p3, p4)) return true; } } return false; } function _getIntersectionPoint(a, b, c, d){ // 三角形abc 面積的2倍 var area_abc = (a[0] - c[0]) * (b[1] - c[1]) - (a[1] - c[1]) * (b[0] - c[0]); // 三角形abd 面積的2倍 var area_abd = (a[0] - d[0]) * (b[1] - d[1]) - (a[1] - d[1]) * (b[0] - d[0]); // 面積符號相同則兩點(diǎn)在線段同側(cè),不相交 (對點(diǎn)在線段上的情況,本例當(dāng)作不相交處理); if ( area_abc*area_abd>=0 ) { return false; } // 三角形cda 面積的2倍 var area_cda = (c[0] - a[0]) * (d[1] - a[1]) - (c[1] - a[1]) * (d[0] - a[0]); // 三角形cdb 面積的2倍 // 注意: 這里有一個(gè)小優(yōu)化.不需要再用公式計(jì)算面積,而是通過已知的三個(gè)面積加減得出. var area_cdb = area_cda + area_abc - area_abd ; if ( area_cda * area_cdb >= 0 ) { return false; } //計(jì)算交點(diǎn)坐標(biāo) var t = area_cda / ( area_abd- area_abc ); var dx= t*(b[0] - a[0]), dy= t*(b[1] - a[1]); return { x: a[0] + dx , y: a[1] + dy }; }
鑒于手機(jī)上性能有限, 可以先用兩個(gè)矩形相交來簡單判斷一下, 只有兩個(gè)矩形相交的情況下再做線是否和多邊形上邊相交的判斷.
最后, 附上項(xiàng)目高清二維碼, 歡迎大家體驗(yàn):
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91751.html
摘要:為了實(shí)現(xiàn)物體隨機(jī)出現(xiàn)的效果,讓每個(gè)物體隨機(jī)多少秒后開始出現(xiàn)最后一個(gè)物體出現(xiàn)完,多少秒后出現(xiàn)結(jié)束畫面等等,需要理清楚各個(gè)定時(shí)器的關(guān)系,并對其添加語義化良好的標(biāo)記,及時(shí)對未完結(jié)的定時(shí)器進(jìn)行清除,防止定時(shí)器帶來的意想不到的問題。 快到年終的時(shí)候做了一個(gè)以游戲形式展示的h5活動(dòng)頁,第一次嘗試使用js寫小游戲,很有趣的過程,很寶貴的經(jīng)驗(yàn)。 效果圖 直接上個(gè)效果的gif圖,游戲的一小部分效果,錄出...
摘要:為了實(shí)現(xiàn)物體隨機(jī)出現(xiàn)的效果,讓每個(gè)物體隨機(jī)多少秒后開始出現(xiàn)最后一個(gè)物體出現(xiàn)完,多少秒后出現(xiàn)結(jié)束畫面等等,需要理清楚各個(gè)定時(shí)器的關(guān)系,并對其添加語義化良好的標(biāo)記,及時(shí)對未完結(jié)的定時(shí)器進(jìn)行清除,防止定時(shí)器帶來的意想不到的問題。 快到年終的時(shí)候做了一個(gè)以游戲形式展示的h5活動(dòng)頁,第一次嘗試使用js寫小游戲,很有趣的過程,很寶貴的經(jīng)驗(yàn)。 效果圖 直接上個(gè)效果的gif圖,游戲的一小部分效果,錄出...
閱讀 3583·2021-11-15 11:36
閱讀 1073·2021-11-11 16:55
閱讀 712·2021-10-20 13:47
閱讀 3034·2021-09-29 09:35
閱讀 3461·2021-09-08 10:45
閱讀 2562·2019-08-30 15:44
閱讀 860·2019-08-30 11:10
閱讀 1438·2019-08-29 13:43