91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS/HTML5游戲常用算法之碰撞檢測和像素檢測算法的示例分析

發布時間:2021-07-16 13:51:55 來源:億速云 閱讀:181 作者:小新 欄目:web開發

這篇文章主要介紹JS/HTML5游戲常用算法之碰撞檢測和像素檢測算法的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

具體如下:

使用像素碰撞檢測法算是最精確的算法了,當然,帶來的代價也是比較明顯的,那就是效率上的低下。除非是在極為特殊的情況下,要求使用非常精確的碰撞,否則,一般情況下在游戲中是不建議使用這種算法,特別是在運行效率不太高的HTML5游戲中。

一般來說在使用像素碰撞檢測之前會使用AABB矩形包圍盒先檢測兩個精靈是否有碰撞,如果AABB包圍盒檢測沒有碰撞,那一定是沒有碰撞到,反之,則不一定,需要進一步進行像素檢測。如下圖所示,很明顯,雖然兩個精靈的包圍盒發生了碰撞,但兩個精靈本身沒有發生碰撞,所以在這種精靈的形狀極為不規則的情況下,除非使用多邊形包圍盒,并且需要多邊形和精靈的形狀極為接近,才能夠獲取好的效果,而且,別忘了,多邊形只適合凸多邊形的情況。

JS/HTML5游戲常用算法之碰撞檢測和像素檢測算法的示例分析

這樣,我們就只能采用像素檢測算法達到精確檢測的目的。接下來,先來看看像素碰撞的原理,首先,我們知道所有的精靈都是由像素點組成,而在canvas的像素數據中每個點都是由RGBA四個數據組成。如果某個點的A(alpha值,透明度)為0則表示該點是透明的,比如在圖6-19中兩個精靈的空白部分的點的A值為0。如果兩個精靈發生碰撞,則表示兩個精靈有像素點發生了重疊,即兩個精靈的像素點坐標相同,如下圖所示。

JS/HTML5游戲常用算法之碰撞檢測和像素檢測算法的示例分析

根據這個原理,基本上我們可以采取以下步驟來進行檢測。

(1)選擇需要檢測的兩個精靈。

(2)先檢測兩個精靈是否發生包圍盒碰撞,如果沒有則退出,否則獲取兩個矩形的相交區域,并繼續。

(3)把一個精靈繪制到和游戲屏幕等大的空白的后臺緩沖區中,獲取緩沖區中在相交區域的像素數據。

(4)清除后臺緩沖區。

(5)對另一個精靈進行步驟3的操作。

(6)得到兩個精靈在同一個相交矩形的像素數據后,循環比較每一個像素點,如果兩個精靈在同一位置的透明度不都是0,則表示兩個精靈有相交,退出循環,返回真。

需要注意的一點是,在第3步獲取相交區域的像素數據中,需要在后臺另外的一個和游戲屏幕等大的空白區域中繪制,而不能直接獲取游戲畫面中的相交區域,因為兩個精靈在相交區域中的像素已經發生了重疊【包圍盒】。

由以上的算法可以看出,在進行像素檢測的時候,需要另外一個緩沖區,把需要檢測的精靈繪制一次,需要清空緩沖區,最后還要使用一個for循環檢測像素。如果相交區域為100×100個像素點,則最壞的情況需要循環10 000 次,由此看來,這真不是一個省時的工作。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
 <meta charset="UTF-8">
 <title>盒包圍碰撞算法-像素檢測算法</title>
 <style>
  #stage {
   border: 1px solid lightgray;
  }
 </style>
</head>
<body>
<h2>包圍盒是否碰撞:<span class="hitTestBox">否</span></h2>
<h2>像素檢測是否碰撞:<span class="hitTestPixel">否</span></h2>
<canvas id="stage"></canvas>
<img src="./images/penguin.png" alt="penguinImg" id="penguinImg"  />
<img src="./images/giraffe.png" alt="giraffeImg" id="giraffeImg"  />
</body>
<script>
 window.onload = function () {
  var stage = document.querySelector('#stage'),
   ctx = stage.getContext('2d');
  stage.width = 600;
  stage.height = 600;
  //創建后臺canvas
  var bC = document.createElement("canvas");
  bC.width = stage.width;
  bC.height = stage.height;
  var backBuf = bC.getContext("2d");
  var penguin = document.querySelector('#penguinImg'),giraffe = document.querySelector('#giraffeImg');
  var penguinImg = {
   x:stage.width/2,
   y:stage.height/2,
   r:128,
   data:null
  },giraffeImg = {
   x:100,
   y:100,
   r:128,
   data:null
  };
  function drawImageBox(img,x,y,width,height){
   ctx.beginPath();
   ctx.rect(x,y,width,height);
   ctx.stroke();
   ctx.drawImage(img,x,y,width,height);
  }
  //緩存畫布繪制方法
  function drawImageBC(img,x,y,width,height){
   backBuf.clearRect(0,0,stage.width,stage.height);
   backBuf.save();
   backBuf.drawImage(img,x,y,width,height);
   backBuf.restore();
  }
  //獲取兩個矩形相交區域
  function getInRect(x1,y1,x2,y2,x3,y3,x4,y4) {
   return [Math.max(x1,x3),Math.max(y1,y3),Math.min(x2,x4),Math.min(y2,y4)];
  }
  document.onkeydown = function (event) {
   var e = event || window.event || arguments.callee.caller.arguments[0];
   //根據地圖數組碰撞將測
   switch (e.keyCode) {
    case 37:
     console.log("Left");
     if (penguinImg.x > 0) {
      penguinImg.x -= 2;
     }
     break;
    case 38:
     console.log("Top");
     if (penguinImg.y > 0) {
      penguinImg.y -= 2;
     }
     break;
    case 39:
     console.log("Right");
     if (penguinImg.x < stage.width) {
      penguinImg.x += 2;
     }
     break;
    case 40:
     console.log("Bottom");
     if (penguinImg.y < stage.height) {
      penguinImg.y += 2;
     }
     break;
    default:
     return false;
   }
  };
  stage.addEventListener('click', function (event) {
   var x = event.clientX - stage.getBoundingClientRect().left;
   var y = event.clientY - stage.getBoundingClientRect().top;
   penguinImg.x = x;
   penguinImg.y = y;
  });
  function update() {
   ctx.clearRect(0, 0, 600, 600);
   drawImageBox(giraffe,giraffeImg.x,giraffeImg.y,giraffeImg.r,giraffeImg.r);
   drawImageBox(penguin,penguinImg.x,penguinImg.y,penguinImg.r,penguinImg.r);
   document.querySelector('.hitTestBox').innerHTML = "否";
   document.querySelector('.hitTestPixel').innerHTML = "否";
   var rect = getInRect(giraffeImg.x,giraffeImg.y,giraffeImg.x+giraffeImg.r,giraffeImg.y+giraffeImg.r,penguinImg.x,penguinImg.y,penguinImg.x+penguinImg.r,penguinImg.y+penguinImg.r)
   //如果沒有相交則退出
   if(rect[0]>=rect[2]||rect[1]>=rect[3]) {
   } else{
    document.querySelector('.hitTestBox').innerHTML = "是";
    giraffeImg.data = null;
    penguinImg.data = null;
    //獲取精靈在相交矩形像素數據
    drawImageBC(giraffe,giraffeImg.x,giraffeImg.y,giraffeImg.r,giraffeImg.r);
    giraffeImg.data = backBuf.getImageData(rect[0],rect[1],rect[2],rect[3]).data;
    drawImageBC(penguin,penguinImg.x,penguinImg.y,penguinImg.r,penguinImg.r);
    penguinImg.data = backBuf.getImageData(rect[0],rect[1],rect[2],rect[3]).data;
    for(var i=3;i<giraffeImg.data.length;i+=4)
    {
     if(giraffeImg.data[i]>0&&penguinImg.data[i]>0){
      document.querySelector('.hitTestPixel').innerHTML = "是";
     }
    }
   }
   requestAnimationFrame(update);
  }
  update();
 };
</script>
</html>

以上是“JS/HTML5游戲常用算法之碰撞檢測和像素檢測算法的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西贡区| 石屏县| 云浮市| 凤山县| 康保县| 黑河市| 闻喜县| 乌苏市| 酉阳| 浏阳市| 祁连县| 万源市| 泊头市| 民县| 南投县| 绥棱县| 贵溪市| 和平县| 会宁县| 清新县| 喜德县| 民乐县| 镇远县| 普定县| 陆河县| 郓城县| 岢岚县| 北京市| 威远县| 永新县| 西青区| 新竹县| 霍山县| 汉中市| 商河县| 图木舒克市| 遵化市| 信阳市| 喀喇| 盐城市| 丰顺县|