使用 getImageData 實現碰撞檢測

前言

最近作了一個 H5 小遊戲,遊戲的玩法是小汽車搶停車位,須要手指拖拽小汽車躲避障礙快速進入停車位。javascript

最終效果

最終效果

在線預覽

在線預覽:go.163.com/web/2019051…html

掃碼跳過視頻體驗小遊戲java

製做思路

遊戲複雜的部分可能就是小紅車和障礙物的碰撞檢測,由於地圖不是固定的,會有不一樣的遊戲地圖。剛開始想把障礙物切成一塊一塊的,而後給幾種排列方式,但須要測量不少數據,以爲仍是有些複雜。git

以前 小建老師 和我提到過不少次用 getImageData() 實現的神奇功能,以後我用 getImageData() 實現了點擊塗色,以爲這個方法確實神奇且好用,因此此次碰撞檢測也用 getImageData() 實現了一下。github

getImageData()

getImageData()canvas 的一個方法,能夠讀取到圖片指定矩形的數據,數據指的是 rgba 數據。web

思路重點

有了 getImageData() 這個方法的助攻,就能夠在 PS 中新建一個透明圖層,給小車行駛的路上塗上一個特定的顏色,而後小車每次移動,讀取小車位置所在像素的顏色,就知道小車在不在道路上了。canvas

開始實現

開始摳圖

在 PS 中新建一個透明圖層,把小車能夠行駛的路上,塗上白色,給停車位塗上紅色,而後保存爲 png 圖片。下圖左側爲遊戲地圖,右測爲對應的塗色圖片,兩張圖片尺寸保存相同: 佈局

關鍵代碼

碰撞檢測關鍵:ui

function areaJudge(x,y){ // 傳入小車的位置
    return ((resolve)=>{
        const canvas = document.createElement('canvas'); // 建立一個canvas,將咱們塗好色的透明圖片畫到canvas
        const ctx = canvas.getContext('2d');
        canvas.width = WIDTH; // WIDTH 爲圖片的寬度
        canvas.height = HEIGHT; // HEIGHT 爲圖片的高度
        const path = new Image();
        path.onload = ()=>{
            ctx.drawImage(path,0,0);
            // 參數說明:getImageData(小車x座標,小車y座標,獲取1像素寬度的數據,獲取1像素高度的數據) 
            // data:[r,g,b,a] 圖像數據爲 rgba
            if(ctx.getImageData(x,y,1,1).data[3]===0){ // 獲取當前像素的透明度,爲 0 說明處於障礙區域
                resolve(0);
            }else if(ctx.getImageData(x,y,1,1).data[0]===255){// 獲取當前像素的透明度,爲 255 說明處於能夠行駛的區域
                resolve(1);
            }else{ // 紅色,停車位的位置
                resolve(2);
            }
        };
        path.src = psImgSrc; // psImgSrc 爲咱們在 ps 塗色的透明圖片
    });
}
複製代碼

而後在小車移動的過程當中,經過碰撞檢測判斷小車處於可行駛區域、故障區域仍是停車位:this

// 此處使用了 pixi.js 的 pointermove ,同理可使用 touchmove
car.on('pointermove',(e)=>{
    // 此處 car.x 爲小車中心的位置,省略了計算代碼
    this.areaJudge(car.x,car.y).then((resolve)=>{
        if(resolve===1){
            // 可行駛區域
                        
        }else if(resolve===0){
            // 不可行駛區域
                        
        }else{
            // 車位
                        
        }
    });
});

複製代碼

以上,就使用 getImageData() 實現了碰撞檢測。

總結

  1. 使用getImageData() 能夠讀取圖片的顏色與透明度數據,這樣節省了咱們頁面障礙物的佈局,能夠少測量不少數據;
  2. 給透明圖片塗上不一樣的顏色來區分障礙物、可行駛路段與停車位,能夠經過顏色來處理不一樣的邏輯;
  3. 本文的代碼爲刪減的關鍵代碼,沒有考慮小車的寬高,能夠在小車位置加上寬高信息,這樣碰撞檢測更加準確;
  4. getImageData() 的功能很強大,能夠考慮擴展到其它應用場景。

更多文章

相關文章
相關標籤/搜索