中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

JS/HTML5游戲常用算法之碰撞檢測 包圍盒檢測算法詳解【圓形情況】

發布時間:2020-10-10 13:42:43 來源:腳本之家 閱讀:243 作者:krapnik 欄目:web開發

本文實例講述了JS/HTML5游戲常用算法之碰撞檢測 包圍盒檢測算法。分享給大家供大家參考,具體如下:

檢測物體碰撞實際上是需要檢測物體是否相交,而實際應用中物體的形狀大小各異,如果直接對物體的邊緣進行碰撞檢測,實際計算過程的代價非常高昂。如果物體的數量太多,比如像網絡游戲中,通常少則幾千用戶,多則上萬、幾十萬用戶同時在線,而這些碰撞都要通過服務器檢測,這樣計算的消耗,即使是大型服務器也會崩潰,所以通常不需要十分精確的碰撞檢測情況下,使用包圍盒算法,即把物體放在一個多邊形中,這個多邊形就是包圍盒。

基于這樣一個概念,通常情況下我們就使用了最簡單的幾種多邊形,比如圓形、矩形等。

先來看看如何使用圓形包圍盒算法,圓形包圍盒算法就是使用圓形作為包圍盒將物體包圍起來,檢測的時候只需要檢測兩個圓形是否碰撞即可。檢測圓形的碰撞比較容易,假設圓 A 的坐標(x1, y1),半徑是 r1,圓 B 的坐標(x2, y2),半徑是 r2,則如果滿足不等式(y2−y1)2+(x2−x1)2≤(r1+r2)2則表示兩個圓發生了碰撞,其實就是圓心之間的距離小于兩個圓的半徑之和即可,由于計算距離需要用到開方運算,效率較低,所以直接比較距離的平方。

JS/HTML5游戲常用算法之碰撞檢測 包圍盒檢測算法詳解【圓形情況】

關鍵代碼:

  function hitTest( source, target ) {
   /* 源物體和目標物體都包含 x, y 以及 width, height */
   return !(
    Math.pow((source.x - target.x),2) + Math.pow((source.y - target.y),2) > Math.pow((source.r + target.r),2)
   );
  }

完整示例代碼:

<!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="hitTest">否</span></h2>
<canvas id="stage"></canvas>
</body>
<script>
 window.onload = function () {
  var stage = document.querySelector('#stage'),
   ctx = stage.getContext('2d');
  stage.width = 400;
  stage.height = 400;
  document.onkeydown = function (event) {
   var e = event || window.event || arguments.callee.caller.arguments[0];
   //根據地圖數組碰撞將測
   switch (e.keyCode) {
    case 37:
     console.log("Left");
     if (balls[0].x > 0) {
      balls[0].x -= 2;
     }
     break;
    case 38:
     console.log("Top");
     if (balls[0].y > 0) {
      balls[0].y -= 2;
     }
     break;
    case 39:
     console.log("Right");
     if (balls[0].x < stage.width) {
      balls[0].x += 2;
     }
     break;
    case 40:
     console.log("Bottom");
     if (balls[0].y < stage.height) {
      balls[0].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;
   balls[0].x = x - balls[0].r/2;
   balls[0].y = y - balls[0].r/2;
  });
  var player = {
   x: stage.width / 2 - 20,
   y: stage.height / 2 - 20,
   r: 40,
   c: "red"
  },balls = [];
  balls.push(player);
  for (var i = 0; i < 10; i++) {
   var ball = {
    x: 60 * i,
    y: 60 * i,
    r: 40,
    c: "blue"
   };
   balls.push(ball);
  }
  function createBall(x, y, r, c) {
   ctx.beginPath();
   ctx.fillStyle = c;
   ctx.arc(x, y, r, 0, Math.PI*2);
   ctx.fill();
  }
  function hitTest( source, target ) {
   /* 源物體和目標物體都包含 x, y 以及 width, height */
   return !(
    Math.pow((source.x - target.x),2) + Math.pow((source.y - target.y),2) > Math.pow((source.r + target.r),2)
   );
  }
  function update() {
   ctx.globalAlpha=1;
   ctx.clearRect(0, 0, 400, 400);
   document.querySelector('.hitTest').innerHTML = "否";
   for (var i = 1, len = balls.length; i < len; i++) {
    createBall(balls[i].x, balls[i].y, balls[i].r, balls[i].c);
    var flag = hitTest(balls[0],balls[i]);
    if(flag){
     document.querySelector('.hitTest').innerHTML = "是";
     ctx.globalAlpha=0.5;
    }
   }
   createBall(balls[0].x, balls[0].y, balls[0].r, balls[0].c);
   requestAnimationFrame(update);
  }
  update();
 };
</script>
</html>

這里使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun 測試上述代碼運行結果如下:

JS/HTML5游戲常用算法之碰撞檢測 包圍盒檢測算法詳解【圓形情況】

github地址:https://github.com/krapnikkk/JS-gameMathematics

更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《JavaScript數學運算用法總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript數組操作技巧總結》、《JavaScript排序算法總結》、《JavaScript遍歷算法與技巧總結》、《JavaScript查找算法技巧總結》及《JavaScript錯誤與調試技巧總結》

希望本文所述對大家JavaScript程序設計有所幫助。

向AI問一下細節

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

AI

泰宁县| 恩平市| 漳州市| SHOW| 西贡区| 梓潼县| 嘉峪关市| 当雄县| 长沙市| 神农架林区| 五华县| 镇康县| 沁源县| 怀安县| 咸丰县| 凌海市| 彰化市| 龙岩市| 德安县| 浠水县| 宁波市| 玉溪市| 姚安县| 阜新| 遂溪县| 屯留县| 来宾市| 屏东市| 马鞍山市| 道孚县| 龙江县| 阿巴嘎旗| 砚山县| 淮阳县| 九龙县| 凤阳县| 大丰市| 阜宁县| 资讯| 肥西县| 天祝|