欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用JavaScript實現(xiàn)一個物理模擬

 更新時間:2024年01月04日 10:49:51   作者:純愛掌門人  
最近掌門人在寫3D游戲,對于其中的物理效果很感興趣,今天我將使用純JavaScript來實現(xiàn)一個簡易的物理模擬,其中包括碰撞檢測與響應、摩擦力與空氣阻力、以及物體的破壞效果,文中通過代碼示例講解的非常詳細,需要的朋友可以參考下

1. 碰撞檢測

首先就是碰撞檢測,在游戲中這是最基礎的效果,下述栗子中將會實現(xiàn)檢測兩個矩形物體是否發(fā)生碰撞。

function isColliding(rect1, rect2) {
  return (
    rect1.x < rect2.x + rect2.width &&
    rect1.x + rect1.width > rect2.x &&
    rect1.y < rect2.y + rect2.height &&
    rect1.height + rect1.y > rect2.y
  );
}

// 測試碰撞檢測
const rect1 = { x: 5, y: 5, width: 50, height: 50 };
const rect2 = { x: 20, y: 20, width: 50, height: 50 };

console.log(isColliding(rect1, rect2)); // 輸出:true

2. 碰撞響應

正常情況下,當兩個物體發(fā)生碰撞時,我們需要計算它們的碰撞響應。在這里,就簡單地反轉(zhuǎn)它們的速度來模擬彈性碰撞。

function resolveCollision(obj1, obj2) {
  const tempVelocity = obj1.velocity;
  obj1.velocity = obj2.velocity;
  obj2.velocity = tempVelocity;
}

// 測試碰撞響應
let obj1 = { velocity: { x: 5, y: 0 } };
let obj2 = { velocity: { x: -3, y: 0 } };

if (isColliding(rect1, rect2)) {
  resolveCollision(obj1, obj2);
}

console.log(obj1.velocity, obj2.velocity); // 輸出:{ x: -3, y: 0 } { x: 5, y: 0 }

3. 摩擦力

摩擦力會減緩物體在接觸表面上的移動。在這個示例中,我們使用一個簡單的摩擦系數(shù)來模擬摩擦力對速度的影響。

function applyFriction(velocity, friction) {
  velocity.x *= friction;
  velocity.y *= friction;
}

// 測試摩擦力
let velocity = { x: 10, y: 0 };
const friction = 0.95; // 摩擦系數(shù)

applyFriction(velocity, friction);

console.log(velocity); // 輸出:{ x: 9.5, y: 0 }

4. 空氣阻力

空氣阻力會減緩物體在空中的移動。我們可以通過減小速度的百分比來模擬這種效果.

function applyDrag(velocity, drag) {
  velocity.x *= (1 - drag);
  velocity.y *= (1 - drag);
}

// 測試空氣阻力
let velocity = { x: 10, y: 0 };
const drag = 0.05; // 空氣阻力系數(shù)

applyDrag(velocity, drag);

console.log(velocity); // 輸出:{ x: 9.5, y: 0 }

5. 物體破壞

首先當物體的速度超過一定閾值時,我們可以假設物體已經(jīng)被破壞。這里我們定義一個簡單的函數(shù)來判斷物體是否應該被破壞,并在破壞發(fā)生時改變其狀態(tài)。

function checkAndApplyDamage(obj, threshold) {
  const speed = Math.sqrt(obj.velocity.x ** 2 + obj.velocity.y ** 2);
  if (speed > threshold) {
    obj.isDestroyed = true;
  }
}

// 測試物體破壞
let obj = { velocity: { x: 50, y: 0 }, isDestroyed: false };
const damageThreshold = 30; // 破壞閾值

checkAndApplyDamage(obj, damageThreshold);

console.log(obj.isDestroyed); // 輸出:true

完整案例

俗話說光說不練假把式,所有的都是為最終的效果服務的,最后我們將上述的所有效果整合起來,實現(xiàn)一個簡單的demo效果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"> 
    <title>物理模擬</title>
    <style> 
        canvas { 
            border: 1px solid black;
        } 
        #controls {
            margin-top: 10px;
        }
        .info {
            margin-right: 10px;
        }
    </style>
</head>
</body>
  <canvas id="simulation" width="500" height="300"></canvas>
  <div id="controls">
    <div class="info">
      <label for="friction">摩擦力:</label>
      <input type="range" id="friction" min="0" max="1" step="0.01" value="0.99">
      <span id="frictionValue">0.99</span>
    </div>
    <div class="info">
      <label for="drag">風阻:</label>
      <input type="range" id="drag" min="0" max="0.1" step="0.001" value="0.01">
      <span id="dragValue">0.01</span>
    </div>
    <div class="info">
      <label for="threshold">臨界值:</label>
      <input type="range" id="threshold" min="0" max="500" step="1" value="25">
      <span id="thresholdValue">25</span>
    </div>
    <button id="restartBtn">重啟模擬</button>
  </div>
  <script>
  document.addEventListener('DOMContentLoaded', function () {
  // 獲取canvas和context
  const canvas = document.getElementById('simulation');
  const ctx = canvas.getContext('2d');

  // 定義物體構(gòu)造函數(shù)
  function GameObject(x, y, width, height, velocity) {
    this.initialX = x;
    this.initialY = y;
    this.width = width;
    this.height = height;
    this.initialVelocity = { ...velocity };
    this.velocity = { ...velocity };
    this.isDestroyed = false;
  }

  // 添加方法到GameObject原型
  GameObject.prototype = {
    reset() {
      this.x = this.initialX;
      this.y = this.initialY;
      this.velocity = { ...this.initialVelocity };
      this.isDestroyed = false;
    },
    isColliding(other) {
      return (
        this.x < other.x + other.width &&
        this.x + this.width > other.x &&
        this.y < other.y + other.height &&
        this.height + this.y > other.y
      );
    },
    resolveCollision(other) {
      if (!this.isDestroyed && !other.isDestroyed) {
        console.log('打印碰撞前的速度:', Math.sqrt(this.velocity.x ** 2 + this.velocity.y ** 2), Math.sqrt(other.velocity.x ** 2 + other.velocity.y ** 2));
        const tempVelocity = this.velocity;
        this.velocity = other.velocity;
        other.velocity = tempVelocity;
        console.log('打印碰撞后的速度:', Math.sqrt(this.velocity.x ** 2 + this.velocity.y ** 2), Math.sqrt(other.velocity.x ** 2 + other.velocity.y ** 2));
      }
    },
    update(friction, drag, threshold) {
      if (this.isDestroyed) return;

      // 應用摩擦力和空氣阻力
      this.velocity.x *= friction;
      this.velocity.y *= friction;
      this.velocity.x *= (1 - drag);
      this.velocity.y *= (1 - drag);

      // 更新位置
      this.x += this.velocity.x;
      this.y += this.velocity.y;

      // 檢查破壞
      const speed = Math.sqrt(this.velocity.x ** 2 + this.velocity.y ** 2);
      if (speed > threshold) {
        this.isDestroyed = true;
      }
    },
    draw() {
      ctx.fillStyle = this.isDestroyed ? 'red' : 'blue';
      ctx.fillRect(this.x, this.y, this.width, this.height);
    }
  };

  // 實例化物體,確保設置了 x 和 y
  const obj1 = new GameObject(100, 100, 50, 50, { x: 5, y: 0 });
  const obj2 = new GameObject(300, 100, 50, 50, { x: -5, y: 0 });

  // 設置物理參數(shù)
  let friction = 0.99;
  let drag = 0.01;
  let destructionThreshold = 25;

  // 獲取控件元素
  const frictionInput = document.getElementById('friction');
  const dragInput = document.getElementById('drag');
  const thresholdInput = document.getElementById('threshold');
  const frictionValueDisplay = document.getElementById('frictionValue');
  const dragValueDisplay = document.getElementById('dragValue');
  const thresholdValueDisplay = document.getElementById('thresholdValue');
  const restartBtn = document.getElementById('restartBtn');

  // 更新參數(shù)值的函數(shù)
  function updateParameters() {
    friction = parseFloat(frictionInput.value);
    drag = parseFloat(dragInput.value);
    destructionThreshold = parseFloat(thresholdInput.value);
  }

  // 監(jiān)聽滑動條的變化
  frictionInput.addEventListener('input', function () {
    frictionValueDisplay.textContent = this.value;
  });
  dragInput.addEventListener('input', function () {
    dragValueDisplay.textContent = this.value;
  });
  thresholdInput.addEventListener('input', function () {
    thresholdValueDisplay.textContent = this.value;
  });

  // 動畫循環(huán)函數(shù)
  let animationFrameId;

  function animate() {
    animationFrameId = requestAnimationFrame(animate);

    // 清除畫布
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 更新和繪制物體
    obj1.update(friction, drag, destructionThreshold);
    obj2.update(friction, drag, destructionThreshold);
    obj1.draw();
    obj2.draw();

    // 碰撞檢測和響應
    if (obj1.isColliding(obj2)) {
      obj1.resolveCollision(obj2);
    }
  }

  // 啟動動畫
  animate();

  // 重新開始動畫的函數(shù)
  function restartAnimation() {
    // 取消當前的動畫幀請求
    cancelAnimationFrame(animationFrameId);

    // 重置物體狀態(tài)
    obj1.reset();
    obj2.reset();

    // 更新參數(shù)
    updateParameters();

    // 重新開始動畫
    animate();
  }

  // 綁定重啟按鈕事件
  restartBtn.addEventListener('click', restartAnimation);

})
  </script>
<body>

總結(jié)

上述的案例我們實現(xiàn)了簡單的物理模擬效果,只是給大家一個思路,畢竟萬物皆可JS嘛,但是如果大家想要在項目中使用的話,就需要更加擬真和復雜的算法,本文只是帶大家大概的了解一下它的實現(xiàn)方式。

大家快去試試吧,俗話說眼過千遍,不如手過一遍,說不定大家在實現(xiàn)的過程中,會找到更加方便簡易的實現(xiàn)方法。

以上就是使用JavaScript實現(xiàn)一個物理模擬的詳細內(nèi)容,更多關于JavaScript物理模擬的資料請關注腳本之家其它相關文章!

相關文章

  • 微信小程序自動客服功能

    微信小程序自動客服功能

    微信小程序最近比較熱,今天小編抽空做了一個客服機器人的小程序,下面小編給大家分享微信小程序自動客服功能,需要的朋友參考下吧
    2017-11-11
  • chrome不支持form.submit的解決方案

    chrome不支持form.submit的解決方案

    最近在解決項目中網(wǎng)站瀏覽器兼容性問題,發(fā)現(xiàn)chrome竟然不支持form.submit,經(jīng)網(wǎng)上搜尋,終于找到了解決方案,有需要的小伙伴參考下。
    2015-04-04
  • JS解決ie6下png透明的方法實例

    JS解決ie6下png透明的方法實例

    解決ie6下png透明的問題想必前端都比較清楚,雖然有很多方法,但是我覺得用JS還是最省事的方法,不管是圖片還是背景圖片都OK。
    2013-08-08
  • javascript輸入CD-KEY自動分割的代碼

    javascript輸入CD-KEY自動分割的代碼

    開發(fā)過程中用寫的一個腳本,記錄下來以備后用與他用,其中attributes["max"].nodeValue是取HTML自定義的 max屬性(兼容Firefox和IE)
    2010-10-10
  • javascript中萬惡的function實例分析

    javascript中萬惡的function實例分析

    javascript中萬惡的function實例分析,學習js的朋友可以參考下。
    2011-05-05
  • JavaScript如何在不重新加載頁面的情況下修改URL

    JavaScript如何在不重新加載頁面的情況下修改URL

    在現(xiàn)代Web應用中,單頁面應用(SPA)越來越流行,為了提升用戶體驗,我們經(jīng)常需要在不重新加載頁面的情況下修改URL,本文將詳細介紹如何在不重新加載頁面的情況下修改URL,并通過多個示例展示其應用場景,需要的朋友可以參考下
    2024-11-11
  • js Flash插入函數(shù)免激活代碼

    js Flash插入函數(shù)免激活代碼

    好多情況下flash會出現(xiàn)需要單擊激活,不過一般新版本中直接插入隨然不用激活但代碼較多,下面的方法是個函數(shù),其實代碼也不少,不過思路很好,大家可以看看。
    2009-03-03
  • JQuery加載圖片自適應固定大小的DIV

    JQuery加載圖片自適應固定大小的DIV

    在固定大小的div中放置一個圖片,當圖片較小時顯示實際大小,當圖片超過div大小時圖片 自動適應div 的大小,實現(xiàn)思路如下,感興趣的朋友可以了解下
    2013-09-09
  • JavaScript中在光標處插入添加文本標簽節(jié)點的詳細方法

    JavaScript中在光標處插入添加文本標簽節(jié)點的詳細方法

    本文主要介紹了JavaScript中在光標處插入添加文本標簽節(jié)點的詳細方法。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • 淺談webpack打包過程中因為圖片的路徑導致的問題

    淺談webpack打包過程中因為圖片的路徑導致的問題

    下面小編就為大家分享一篇淺談webpack打包過程中因為圖片的路徑導致的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02

最新評論